When I try to execute newly created azure function with CosmosDBTrigger, I get the above exception for the function with cosmosdb trigger
Investigative information
Environment:
Visual Studio 2017 15.3.5
Packages referenced:
Marvin.JsonPatch.Dynamic Version="1.1.0"
Microsoft.Azure.DocumentDB Version="1.17.0"
Microsoft.Azure.WebJobs Version="2.1.0-beta4"
Microsoft.Azure.WebJobs.Extensions.DocumentDB Version="1.1.0-beta4"
Microsoft.Azure.WebJobs.ServiceBus Version="2.0.0"
Microsoft.NET.Sdk.Functions Version="1.0.5"
Newtonsoft.Json Version="10.0.3"
System.Configuration.ConfigurationManager Version="4.4.0"
Steps to reproduce the issue
Provide the steps required to reproduce the problem:
Create a new Azure Function Project from Visual Studio
Add a function (i didn't find any option for CosmosDB Binding so i created using HttpTrigger)
once the .cs file is created, replace the file with the code that i have put below.
Build
Hit F5
Here is the code sample
public static class AddEventInEventStore
{
[FunctionName("AddEventInEventStore")]
public static void Run([CosmosDBTrigger("db", "Items",
ConnectionStringSetting = "AzureWebJobsDocumentDBConnectionString",
LeaseCollectionName = "leases", LeaseDatabaseName = "db"
)]
IReadOnlyList<Document> changeList, TraceWriter log)
{
if (changeList != null && changeList.Count > 0)
{
log.Verbose("Documents modified " + changeList.Count);
foreach (var change in changeList)
{
log.Verbose("First document Id " + change.Id);
}
}
}
}
Update your Azure Functions and Web Jobs Tools (Tools -> Extensions and Updates).
I can see you are on 1.0.0 version (console title), while 1.0.4 is already available.
Related
I'm unable to create directory in android 10. It's working on devices till android Oreo.
I tried two ways for creating folders.
Using File.mkdir():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
success = f.mkdir();
}
Here, the variable success is always false which means the directory isn't created.
Using Files.createDirectory():
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
if (!f.isFile()) {
if (!(f.isDirectory())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
Files.createDirectory(Paths.get(f.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
}
} else {
f.mkdir();
}
}
which causes this exception:
pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err: at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err: at java.nio.file.Files.createDirectory(Files.java:674)
I've implemented the run-time permissions and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
are all set.
As was first disclosed back in March 2019, you no longer have access by default to arbitrary locations on external storage or removable storage on Android 10+. This includes Environment.getExternalStorageDirectory() and other methods on Environment (e.g., getExternalStoragePublicDirectory().
For Android 10 and 11, you can add android:requestLegacyExternalStorage="true" to your <application> element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work.
Otherwise, your choices are:
Use methods on Context, such as getExternalFilesDir(), to get at directories on external storage into which your app can write. You do not need any permissions to use those directories on Android 4.4+. However, the data that you store there gets removed when your app is uninstalled.
Use the Storage Access Framework, such as ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT.
If your content is media, you can use MediaStore to place the media in standard media locations.
For Android 10, you can add
android:requestLegacyExternalStorage="true"
to your element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work. This fix will not work on Android R and higher though, so this is only a short-term fix.
There are more restrictions in Android API 30
you can only write in your app-specific files
File dir_ = new File(context.getFilesDir(), "YOUR_DIR");
dir_.mkdirs();
or in the external storage of your app Android/data
File dir_ = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");
UPDATE
this answer provided another solution https://stackoverflow.com/a/65744517/8195076
UPDATE
another way is to grant this permission in manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
like this answer https://stackoverflow.com/a/66968986/8195076
This works for me and I think it's functional on Android 10>
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
File folder = new File(path);
boolean isCreada = folder.exists();
if(!isCreada) {
folder.mkdirs();
}
You can use public directory to save files in Android 11 like this:
dir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getPath()
+ "/foldername");
if (!dir.exists()) {
dir.mkdir();
Toast.makeText(getApplicationContext(), "not exist", Toast.LENGTH_SHORT).show();
}
Since Q beta 4 it's possible to opt-out of that feature by:
targeting api 28 (or lower)
using requestLegacyExternalStorage manifest attribute:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
only use
android:requestLegacyExternalStorage="true"
in manifests
I am trying to create VSIX package to extend functionality of TFS 2012 source control right click context menu when clicking on branch.
I don't want to use Add-in. this has to be package which other developers can directly install.
The customized menu items need to appear in the source control explorer contextual menu after they install the extension. I am not able to get any sample for this requirement or not able to get proper documentation source. One of sample I found is "TFS community branch tool", which is kind of similar functionality I am looking for, but I am not able to get the source code of it.
Appreciate your help.
I assume that you are familiar with the .vsct file, command/menu/groups Guids/Id stuff (all this is documented in MSDN). So, the question would be which is the Guid/Id of the group inside the context menu of Source Control Explorer.
Guessing that you may want your command below the "Get Latest Version" menu entry of the context menu of a file, the code would be:
<Commands package="guidVSMyPackagePkg">
<Buttons>
<Button guid="guidVSMyPackageCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
<Parent guid="guidSourceControlExplorerMenuGroup" id="SourceControlExplorerMenuGroupId"/>
<Strings>
<ButtonText>My Command</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="guidVSMyPackagePkg" value="{...}" />
<GuidSymbol name="guidVSMyPackageCmdSet" value="{...}">
<IDSymbol name="cmdidMyCommand" value="0x0100" />
</GuidSymbol>
<GuidSymbol name="guidSourceControlExplorerMenuGroup" value="{ffe1131c-8ea1-4d05-9728-34ad4611bda9}">
<IDSymbol name="SourceControlExplorerMenuGroupId" value="0x1111" />
</GuidSymbol>
</Symbols>
Building upon Carlos Quintero's answer:
If you need to put the command in any other location in the Source Control Explorers context menu, you need the right Id. Using EnableVSIPLogging you can only find information for commands and their parent menus, but not the groups.
In order to find Group Ids (or any other ID for that matter) used in the Source Control Explorer you can follow these steps (for VS2015):
Decompile Microsoft.VisualStudio.TeamFoundation.VersionControl.dll (using JetBrains dotPeek for instance).
Open Resources\HatPackage.resources.
Look up 1000.ctmenu and copy the Base64 data.
Convert the data from Base64 to bytes.
Save the bytes in a file as TfsMenu.cto (the extension needs to be .cto and it needs to be in a location with write rights for the next step to work).
Run "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VSSDK\VisualStudioIntegration\Tools\Bin\vsct.exe" TfsMenu.cto TfsMenu.vsct to decompile the file.
Now you have the original .vsct file that was used to make the TFS plugin. In here you can look up all IDs.
To get you started finding the menuitems in TfsMenu.vsct, you can enable EnableVSIPLogging:
Add HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0\General\EnableVSIPLogging as DWORD32 with value 1.
Now, in Visual Studio, when Holding Ctrl+Shift while hovering menus or clicking menu items in the Source Control Explorer, a messagebox pops up with information about that item, including the GUID and ID of that menu/menuitem
#Erik I was so happy to run across your explanation for extracting the vsct as I trying very hard to figure out how to do that very thing. Just to expound upon your answer I converted it into code. Sharing here in case anyone is interested.
static void Main(string[] args)
{
/*
Extract menus from extensions
http://stackoverflow.com/questions/29831181/creating-vsix-package-for-tfs-source-control-explorer-context-menu-extension
*/
try
{
string vsctPath = ConfigurationManager.AppSettings["VSCTPath"];
if (!File.Exists(vsctPath))
{
WriteConsole("The path to the vsct.exe could not be found. Please edit the app.config to set the right executable path.", ConsoleColor.Yellow);
return;
}
//TODO: Convert to a command line argument
string dllPath = #"C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\Extensions\Application\Microsoft.SqlServer.Management.SqlStudio.Explorer.dll";
var assembly = Assembly.LoadFrom(dllPath);
if (assembly == null)
{
WriteConsole("Could not load assembly.", ConsoleColor.Yellow);
return;
}
var resourceName = assembly.GetManifestResourceNames().FirstOrDefault(n => Regex.IsMatch(n, #"VSPackage\.resources", RegexOptions.IgnoreCase));
if (String.IsNullOrWhiteSpace(resourceName))
{
WriteConsole("Could find VSPackage.resources in assembly.", ConsoleColor.Yellow);
return;
}
var resourceManager = new ResourceManager(Path.GetFileNameWithoutExtension(resourceName), assembly);
if (resourceManager == null)
{
WriteConsole("Could find load the resource " + resourceName + ".", ConsoleColor.Yellow);
return;
}
var menus = resourceManager.GetObject("Menus.ctmenu") as byte[];
if (menus == null)
{
WriteConsole("Could find Menus.ctmenu resource in VSPackage.resources.", ConsoleColor.Yellow);
return;
}
string dir = Path.Combine(Path.GetTempPath(), "PackageMenus");
string fileName = Path.GetFileNameWithoutExtension(dllPath) + ".cto";
Directory.CreateDirectory(dir);
Directory.SetCurrentDirectory(dir);
File.WriteAllBytes(Path.Combine(dir, fileName), menus);
string processArgs = String.Format(#"{0} {1}.vsct", fileName, fileName);
var pi = new ProcessStartInfo(vsctPath, processArgs);
pi.UseShellExecute = false;
pi.RedirectStandardError = true;
pi.RedirectStandardOutput = true;
var ret = Process.Start(pi);
var output = ret.StandardOutput.ReadToEnd();
var errors = ret.StandardError.ReadToEnd();
Console.WriteLine(output);
if (!string.IsNullOrWhiteSpace(errors))
{
Console.Write("Errors: ");
WriteConsole(errors, ConsoleColor.Red);
}
else
{
Console.WriteLine("New files written to: " + dir);
}
}
catch(Exception ex)
{
WriteConsole(ex.ToString(), ConsoleColor.Red);
}
finally
{
Console.WriteLine("\r\nPress any key to continue.");
Console.ReadKey(true);
}
}
private static void WriteConsole(string message, ConsoleColor color = ConsoleColor.White)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
I'm trying to use an SSIS script task to copy an excel file into a Sharepoint library when a file with the same name already exists there. It doesn't matter if it deletes the old file first then copies the new or just copies and replaces the new. I can't figure out how to delete the old file and it won't copy the new until the old is gone. So far I have:
/*
Microsoft SQL Server Integration Services Script Task
Write scripts using Microsoft Visual C# 2008.
The ScriptMain is the entry point class of the script.
*/
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
namespace ST_be5f0817a6b54483a96a8c9e79402175.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
/*
The execution engine calls this method when the task executes.
To access the object model, use the Dts property. Connections, variables, events,
and logging features are available as members of the Dts property as shown in the following examples.
To reference a variable, call Dts.Variables["MyCaseSensitiveVariableName"].Value;
To post a log entry, call Dts.Log("This is my log text", 999, null);
To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, true);
To use the connections collection use something like the following:
ConnectionManager cm = Dts.Connections.Add("OLEDB");
cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;";
Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
To open Help, press F1.
*/
public void Main()
{
string fileDir = (string)Dts.Variables["fileDir"].Value;
string SPDir = (string)Dts.Variables["SPDir"].Value;
if (File.Exists(Path.Combine(SPDir, "filename.CSV")))
{
File.Delete(Path.Combine(SPDir, "filename.CSV"));
}
File.Copy(Path.Combine(fileDir, "filename.CSV"), Path.Combine(SPDir, "filename.CSV"));
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
I think I can delete the file by running a data flow component with the sharepoint list connector before the script and have the script just copy the file over, but I'm trying to avoid that many components and connections and that method just generally sounds more complicated.
Any help or advice would be welcome.
Fixed this issue by changing the relevant line to: File.Copy(Path.Combine(fileDir, "filename.CSV"), Path.Combine(SPDir, "filename.CSV"), true);
The boolean argument specifies whether to overwrite the existing file and is "false" if not specified.
I'm using MOSS (SharePoint 2007 Enterprise), 32-bit, SP2.
I've been noticing some odd problems with Custom Workflow Activities which I've developed and am using in SharePoint Designer (SPD) workflows. These actions seem to work correctly, but don't "play nice" with the rest of the workflow (specifically, the root issue was posted at: Timing concerns with Custom WF Activity changing permissions , since that hasn't gotten any responses I've been digging deeper...)
To help pin down the problem, I've developed a very simple test, which I will outline in detail below, and am noticing even more odd behavior with this test, which is what I'll get into first...
So, at the end of this test I've got a simple SPD WF which I can start manually on a list I created for this test, which contains a Single Line of Text field/column named "TextField". The WF contains 1 step which performs 4 actions:
Set Field to Value (uses my custom WFA to assign "1" to the TextField column)
Log "Set 1" to the workflow history list
Set Field in Current Item (uses the OOTB action to assign "2" to the TextField column)
Log "Set 2" to the workflow history list
This workflow runs perfectly, completing successfully with the workflow messages in order, and TextField==2.
However, if I move the last 2 actions to the top of the actions list, making the WF's single step then look like:
Set Field in Current Item (uses the OOTB action to assign "2" to the TextField column)
Log "Set 2" to the workflow history list
Set Field to Value (uses my custom WFA to assign "1" to the TextField column)
Log "Set 1" to the workflow history list
In this case, the workflow status is "Error Occurred", and even though TextField==1 (the second assignment) the only items in the workflow history are:
Error updating a list item
An error has occured in Set Field Test.
("Set Field Test" is the name of my SPD WF)
So, that's what the problem looks like: The WF works 100% if my custom WFA happens first, but fails every time (even though the field does get updated correctly) if my custom WFA happens second. I've repeated this test many times, including to perform the action reversal multiple times.
I might be doing something dumb in my custom WFA, so here it is (I've replaced my company's acronym with public agency - getting my tax dollars' worth) in its entirety:
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
namespace NASA.workflowActivity {
public partial class TestSetFieldValueActivity : Activity {
#region Dependency Properties
public static DependencyProperty itemFieldProperty = DependencyProperty.Register("itemField", typeof(String), typeof(TestSetFieldValueActivity));
public static DependencyProperty newValueProperty = DependencyProperty.Register("newValue", typeof(String), typeof(TestSetFieldValueActivity));
public static DependencyProperty __ActivationPropertiesProperty = DependencyProperty.Register("__ActivationProperties", typeof(Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties), typeof(TestSetFieldValueActivity));
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
public String itemField {
get { return base.GetValue(TestSetFieldValueActivity.itemFieldProperty).ToString(); }
set { base.SetValue(TestSetFieldValueActivity.itemFieldProperty, value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
public String newValue {
get { return base.GetValue(TestSetFieldValueActivity.newValueProperty).ToString(); }
set { base.SetValue(TestSetFieldValueActivity.newValueProperty, value); }
}
[ValidationOption(ValidationOption.Required)]
public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties __ActivationProperties {
get { return (Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties)base.GetValue(TestSetFieldValueActivity.__ActivationPropertiesProperty); }
set { base.SetValue(TestSetFieldValueActivity.__ActivationPropertiesProperty, value); }
}
#endregion
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) {
try {
SPListItem listItem = this.__ActivationProperties.Item;
SPField field = listItem.Fields[this.itemField];
listItem[field.Id] = this.newValue;
listItem.SystemUpdate();
} catch {
return ActivityExecutionStatus.Faulting;
}
return ActivityExecutionStatus.Closed;
}
}
}
And my .ACTIONS file (saved to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\Workflow ) contains this entry for this action:
<Action
Name="Set field in current item (Custom WFA)"
ClassName="NASA.workflowActivity.TestSetFieldValueActivity"
Assembly="NASA.workflowActivity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f579ebeb24170bf5"
AppliesTo="all"
Category="NASA WFA: Test">
<RuleDesigner Sentence="Set %1 to %2 (Custom WFA)">
<FieldBind Id="1" Field="itemField" DesignerType="FieldNames" text="field" />
<FieldBind Id="2" Field="newValue" DesignerType="Text" text="value" />
</RuleDesigner>
<Parameters>
<Parameter Name="itemField" Type="System.String, mscorlib" Direction="In" />
<Parameter Name="newValue" Type="System.String, mscorlib" Direction="In" />
<Parameter Name="__ActivationProperties" Type="Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties, Microsoft.SharePoint" Direction="In" />
</Parameters>
</Action>
And finally, of course, my web.config contains an entry for my assembly.
This is a very simple action of course, but even it isn't working right in my SPD WF. I must be doing something wrong, but all the documentation I can find on creating a custom WFA makes this look correct. Can anyone see a problem in my code, or even try this out in your own environment?
I have acually solved this problem in my open source project. Download the source code from http://spdactivities.codeplex.com/ and look at the source for one of the permission activities. The reason your code does not work is because the OOTB activities participate in a transaction and your custom activity does not. That is why your custom activity runs before all OOTB activities.
To participate in the workflow you need to implement IPendingWork and submit to WorkflowEnvironment.WorkBatch. HTH
I'm logged in as the System Account, so it's probably not a "real access denied"!
What I've done :
- A custom master page
- A custom page layout from a custom content type (with custom fields)
If I add a custom field (aka "content field" in the tools in SPD) in my page layout, I get an access denied when I try to edit a page that comes from that page layout.
So, for example, if I add in my page layout this line in a "asp:content" tag :
I get an access denied. If I remove it, everyting is fine. (the field "test" is a field that comes from the content type).
Any idea?
UPDATE
Well, I tried in a blank site and it worked fine, so there must be something wrong with my web application :(
UPDATE #2
Looks like this line in the master page gives me the access denied :
<SharePoint:DelegateControl runat="server" ControlId="PublishingConsole" Visible="false"
PrefixHtml="<tr><td colspan="0" id="mpdmconsole" class="s2i-consolemptablerow">"
SuffixHtml="</td></tr>"></SharePoint:DelegateControl>
UPDATE #3
I Found http://odole.wordpress.com/2009/01/30/access-denied-error-message-while-editing-properties-of-any-document-in-a-moss-document-library/
Looks like a similar issue. But our Sharepoint versions are with the latest updates. I'll try to use the code that's supposed to fix the lists and post another update.
** UPDATE #4**
OK... I tried the code that I found on the page above (see link) and it seems to fix the thing. I haven't tested the solution at 100% but so far, so good. Here's the code I made for a feature receiver (I used the code posted from the link above) :
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Xml;
namespace MyWebsite.FixAccessDenied
{
class FixAccessDenied : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
FixWebField(SPContext.Current.Web);
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
static void FixWebField(SPWeb currentWeb)
{
string RenderXMLPattenAttribute = "RenderXMLUsingPattern";
SPSite site = new SPSite(currentWeb.Url);
SPWeb web = site.OpenWeb();
web.AllowUnsafeUpdates = true;
web.Update();
SPField f = web.Fields.GetFieldByInternalName("PermMask");
string s = f.SchemaXml;
Console.WriteLine("schemaXml before: " + s);
XmlDocument xd = new XmlDocument();
xd.LoadXml(s);
XmlElement xe = xd.DocumentElement;
if (xe.Attributes[RenderXMLPattenAttribute] == null)
{
XmlAttribute attr = xd.CreateAttribute(RenderXMLPattenAttribute);
attr.Value = "TRUE";
xe.Attributes.Append(attr);
}
string strXml = xe.OuterXml;
Console.WriteLine("schemaXml after: " + strXml);
f.SchemaXml = strXml;
foreach (SPWeb sites in site.AllWebs)
{
FixField(sites.Url);
}
}
static void FixField(string weburl)
{
string RenderXMLPattenAttribute = "RenderXMLUsingPattern";
SPSite site = new SPSite(weburl);
SPWeb web = site.OpenWeb();
web.AllowUnsafeUpdates = true;
web.Update();
System.Collections.Generic.IList<Guid> guidArrayList = new System.Collections.Generic.List<Guid>();
foreach (SPList list in web.Lists)
{
guidArrayList.Add(list.ID);
}
foreach (Guid guid in guidArrayList)
{
SPList list = web.Lists[guid];
SPField f = list.Fields.GetFieldByInternalName("PermMask");
string s = f.SchemaXml;
Console.WriteLine("schemaXml before: " + s);
XmlDocument xd = new XmlDocument();
xd.LoadXml(s);
XmlElement xe = xd.DocumentElement;
if (xe.Attributes[RenderXMLPattenAttribute] == null)
{
XmlAttribute attr = xd.CreateAttribute(RenderXMLPattenAttribute);
attr.Value = "TRUE";
xe.Attributes.Append(attr);
}
string strXml = xe.OuterXml;
Console.WriteLine("schemaXml after: " + strXml);
f.SchemaXml = strXml;
}
}
}
}
Just put that code as a Feature Receiver, and activate it at the root site, it should loop trough all the subsites and fix the lists.
SUMMARY
You get an ACCESS DENIED when editing a PAGE or an ITEM
You still get the error even if you're logged in as the Super Admin of the f****in world (sorry, I spent 3 days on that bug)
For me, it happened after an import from another site definition (a cmp file)
Actually, it's supposed to be a known bug and it's supposed to be fixed since February 2009, but it looks like it's not.
The code I posted above should fix the thing.
Try to publish your MasterPage and Page Layouts, this is the most common reason. Since the system account is godmode, it wont get that error.
In SharePoint Designer you cannot do the last step in the publishing workflow (Approval), so you:
SharePoint Designer:
CheckIn => Publish Major Version, hit the OK button or go to /_catalogs/masterpage on the site .
Then and use the Context Menu to Approve the MasterPage and Layouts.
Some ideas:
Check if any web parts in your custom Page Layout and Master Page are not registered as safe.
Did you define your own custom field type, like write a class which extends SPField? If so, are you using a custom Field Control? If you are, check if it is doing anything which may need elevated privileges.
Likewise, check for any edit mode panels containing web parts of web controls which might be trying to do something which needs elevated privileges.
See the code I've posted in the edit of the post. It fixed my problem.
The problem appears to be caused by an error in the stsadm -o export function in certain versions of SharePoint (I got it doing an export from a 2007 RTM MOSS server). Importing the bogus export file causes the "edit-denied-access" problem in all NEWLY-CREATED lists. The patches for later version from Microsoft fix stsadm -o export, but DO NOT FIX the broken lists; that requires a procedure like tinky05's.