views:

2855

answers:

3

I have an existing document in a document library and I'm trying to overwrite that file in code using code like this:

byte[] data = ...
SPListItem li = ...
li.File.SaveBinary(data);

When I run this code I get:

Microsoft.SharePoint.SPException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again. ---> System.Runtime.InteropServices.COMException (0x8102006D): The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.
    at Microsoft.SharePoint.Library.SPRequestInternalClass.PutFile(String bstrUrl, String bstrWebRelativeUrl, Object varFile, PutFileOpt PutFileOpt, String bstrCreatedBy, String bstrModifiedBy, Int32 iCreatedByID, Int32 iModifiedByID, Object varTimeCreated, Object varTimeLastModified, Object varProperties, String bstrCheckinComment, UInt32& pdwVirusCheckStatus, String& pVirusCheckMessage)
    at Microsoft.SharePoint.Library.SPRequest.PutFile(String bstrUrl, String bstrWebRelativeUrl, Object varFile, PutFileOpt PutFileOpt, String bstrCreatedBy, String bstrModifiedBy, Int32 iCreatedByID, Int32 iModifiedByID, Object varTimeCreated, Object varTimeLastModified, Object varProperties, String bstrCheckinComment, UInt32& pdwVirusCheckStatus, String& pVirusCheckMessage)
    --- End of inner exception stack trace ---
    at Microsoft.SharePoint.Library.SPRequest.PutFile(String bstrUrl, String bstrWebRelativeUrl, Object varFile, PutFileOpt PutFileOpt, String bstrCreatedBy, String bstrModifiedBy, Int32 iCreatedByID, Int32 iModifiedByID, Object varTimeCreated, Object varTimeLastModified, Object varProperties, String bstrCheckinComment, UInt32& pdwVirusCheckStatus, String& pVirusCheckMessage)
    at Microsoft.SharePoint.SPFile.SaveBinary(Byte[] file, String checkInComment, Boolean checkRequiredFields, Boolean bIsMigrate, Boolean bIsPublish, SPUser modifiedBy, DateTime timeLastModified, SPVirusCheckStatus& virusCheckStatus, String& virusCheckMessage)
    at Microsoft.SharePoint.SPFile.SaveBinary(Byte[] file, Boolean checkRequiredFields, Boolean bIsMigrate, Boolean bIsPublish, SPUser modifiedBy, DateTime timeLastModified)
    at Microsoft.SharePoint.SPFile.SaveBinary(Byte[] file, Boolean checkRequiredFields)
    at Microsoft.SharePoint.SPFile.SaveBinary(Byte[] file)
    at TestClass.UploadFile()

I'm running this code on a form hosted in the same site as sharepoint and the user that is running the code can upload the file manually just fine. Do I need to delete the file first? Check it out?

+1  A: 

I figured it out. I was doing the call within a SPSecurity.RunWithElevatedPrivileges block which caused it to fail. I find that interesting since you would think running with elivated privileges would have more access not less.

joegtp
The problem is a design flaw in SharePoint. It validates the form digest when first used in a request. Among the items in the form digest is the user's ID. Now when you're elevated, the user ID changes to sharepoint\system, which no longer matches, and triggers the error. You should be able to avoid this by calling SPUtility.ValidateFormDigest() before elevating.
Yuliy
+2  A: 

Try this to fix it:

SPSecurity.RunWithElevatedPrivileges(delegate
{
  using (SPSite elevSite = new SPSite(currentWeb.Site.ID))
  {
    using (SPWeb elevWeb = elevSite.OpenWeb(currentWeb.ID))
    {
      elevWeb.AllowUnsafeUpdates = true;
      // ...
    }
  }
}
Simon B.
A: 

SPUtility.ValidateFormDigest();

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        SPSite oSite = new SPSite("http://moss");

        SPWeb oWeb = oSite.OpenWeb();
        Response.Write(oWeb.CurrentUser.ToString());

                SPList doclib = oWeb.Lists["laser"];
                SPListItem testItem = doclib.GetItemById(1);

                oSite.AllowUnsafeUpdates = true;

                SPFile file = testItem.File;
                file.CheckOut();

                byte[] byteText = file.OpenBinary();
                string text = Encoding.UTF8.GetString(byteText, 0, byteText.Length);

                text += sbFormData;

                byte[] modifiedText = Encoding.UTF8.GetBytes(text);

                file.SaveBinary(modifiedText);
                file.CheckIn("Automatic Modification");


            oSite.AllowUnsafeUpdates = false;
            oSite.Close();
            oWeb.Close();

        });

I have written the above code. But still get the Security validation error. The stack trace is as follows. I do not understand what the problem is. Any help is appretiated. [SPException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.] Microsoft.SharePoint.Library.SPRequest.ValidateFormDigest(String bstrUrl, String bstrListName) +188 Microsoft.SharePoint.SPWeb.ValidateFormDigest() +74 Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest() +66 sendmail.Page_Load(Object sender, EventArgs e) in c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\SwySiteDirectory\sendmail.aspx.cs:42 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +33 System.Web.UI.Control.OnLoad(EventArgs e) +99 System.Web.UI.Control.LoadRecursive() +47 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436

Granada