pnp / pnpjs

Fluent JavaScript API for SharePoint and Microsoft Graph REST APIs
https://pnp.github.io/pnpjs/
Other
753 stars 304 forks source link

items.add using hooks error:"The security validation for this page is invalid and might be corrupted" #2102

Closed Ofer-Gal closed 2 years ago

Ofer-Gal commented 2 years ago

Category

Version

Please specify what version of the library you are using: [ "@pnp/sp": "^3.0.1" v3nightly ]

Please specify what version(s) of SharePoint you are targeting: [ SPO ]

Expected / Desired Behavior / Question

Add items should work as well as get

Observed Behavior

With version 3 there is no longer sp.setup(this.context); in the onInit() of the *WebPart.ts file of SPFx When using hooks now I am passing the context: WebPartContext as props to the components.

So all my gets work fine with const sp = spfi(window.location.origin + "/sites/dpc").using(SPFx(context));

But when I try to add, I am getting the error you get when there is no RequestDigest Error: "The security validation for this page is invalid and might be corrupted"

Steps to Reproduce

using the example

           const sp = spfi(window.location.origin + "/sites/dpc").using(SPFx(context));
            const iar: IItemAddResult = await sp.web.lists.getByTitle("Who Is On Queue").items.add({
                Title: "Title" //                Description: "Description"
            });

I know I can stop using hooks and adopt you service example. I was hoping for an easier transition to 3.0.? Hope you have an easy answer Thank you

Just in :-) I found this

import { spfi, SPFx } from "@pnp/sp";

  await super.onInit();
    const sp = spfi().using(SPFx(this.context));

Do I need to pass sp as property to the component? Just running the code didn't work .

juliemturner commented 2 years ago

As we outline in the transition docs, sp is no longer a global object, so if you want sp (after you create it) to be global you need to pick an architectural pattern to make that happen. I will say yes, you can pass the sp object around but that is never a good pattern in my opinion. I shared one in this answer, and we will formalize that and other patterns in the docs and samples in the days to come as we have time to do so.

Ofer-Gal commented 2 years ago

@juliemturner Please don't think of me like @trueleader. criticism is reserved for the contributors and no one else. :-) I have only thanks (and questions) to your guys. I adopted your getSP() suggestion and as is, it did not find my list because the context was of the root site where the web part is and not {tennat}/sites/DPC where the list is. So, I made it to take URL as parameter.

if (url !=='' && context != null) {
        _sp = spfi(window.location.origin + url).using(SPFx(context)).using(PnPLogging(LogLevel.Warning));
    }
    return _sp;

This code does not error But when I try the Add Item like so:

const spJulie = getSP(context,"/sites/dpc");
           const iar: IItemAddResult = await spJulie.web.lists.getByTitle("Who Is On Queue").items.add({
                Title: "Title"  
            });

I get the same error: "The security validation for this page is invalid and might be corrupted"

I am defiantly doing something wrong. I just don't know what.

Thank you very much for your significant help. I did a test running the workbench from the site containing the list. /sites/dpc/_layouts/15/workbench.aspx Now the same code added the item with no issue. I believe my problem is getting the context of another site. My code now is:

 const spJulie = getSP();      // Copy/Assign a new instance of Queryable using the existing 
 const spSiteC = spfi(window.location.origin + "/sites/dpc").using(AssignFrom(spJulie.web));  // get the sp of "/sites/dpc site
const queueForDPCList = await spSiteC.web.lists.getByTitle("Who Is On Queue");
            const iar: IItemAddResult = await queueForDPCList.items.add({
                Title: queue ,  DPCOperatorId: user.Id
            });  //here it errors if the workbench is not at /sites/dpc 

Hope you can help

Thank you

juliemturner commented 2 years ago

@Ofer-Gal -- no comparison just an explanation of the pattern that I didn't want to retype. I can't say I understand what you're doing wrong especially but if I can find some time I'll try and put together and test an example of connecting to two different webs... Honestly, it would be better if you forgot the two webs for a second and just verify that you can update a list item in the web that is the one where you're running the web part... simplify your test.

Ofer-Gal commented 2 years ago

Sure, added a list in the root site and ran the code

const sp = getSP(); //context,"/sites/dpc"      //TestList
const iar: IItemAddResult = await sp.web.lists.getByTitle("TestList").items.add({ Title: 'Added Title'});
console.log(iar);
const items: any[] = await sp.web.lists.getByTitle("TestList").items.top(1).filter(`Title eq 'Added Title'`)();
    if (items.length > 0) {
        const updatedItem = await sp.web.lists.getByTitle("TestList").items.getById(items[0].Id).update({Title: "Updated Title"});
        console.log(JSON.stringify(updatedItem));
    }

Ran with no problem at all. Verified that it works with same site as the one where running the web part. Thank you.

plodik commented 2 years ago

Hello all, I have exactly the same issue. When I run a solution in workbench in the same site where the list is, all is good. When I run the workbench in root site and execute add or delete action against the list in another site, I got "The security validation for this page is invalid and might be corrupted". This was not happening for sure in V2.x of PNP JS.

I create the connection to another site URL like this: this.sp = spfi("https://xxxx.sharepoint.com/sites/test").using(SPFx(props.context)).using(RequestDigest());

This is a major issue right now. The read action is fine, I can see the content of another list. Just actions add and delete are not working.

patrick-rodgers commented 2 years ago

@plodik - the SPFx behavior already includes RequestDigest. Can you remove it from your code and try again? Not saying there isn't an issue here, looking into it - but for sure adding the RequestDigest behavior again won't solve it.

patrick-rodgers commented 2 years ago

Trying to sum this up:

My guess is that the shim to try and grab the request digest is improperly returning it for the current site when you are trying to make a request to another site. This is for sure a bug.

plodik commented 2 years ago

@plodik - the SPFx behavior already includes RequestDigest. Can you remove it from your code and try again? Not saying there isn't an issue here, looking into it - but for sure adding the RequestDigest behavior again won't solve it.

At first I tried that without RequestDigest without any luck. I have already rollbacked the code to V2.0 of PNP SP package as I was not able to make it running in V3

patrick-rodgers commented 2 years ago

This was def a bug, and will be fixed in 3.0.2 which we are in the process of releasing. @plodik - hope you can give it another try - some hiccups will always occur when moving versions. Thanks to you both for reporting the problem!

plodik commented 2 years ago

This was def a bug, and will be fixed in 3.0.2 which we are in the process of releasing. @plodik - hope you can give it another try - some hiccups will always occur when moving versions. Thanks to you both for reporting the problem!

For sure I will retry later :) I just needed to rollback to continue developing the solution but I am ready to use V3 after this is fixed. Thanks for support!

Ofer-Gal commented 2 years ago

I tested 3.0.2 and it works like it should. Thank you, gals and guys.

plodik commented 2 years ago

Hello all, I have upgraded my solution to V3.0.2 and can confirm that the access to lists in another site works now. Great job, team!

kofrimpong commented 2 years ago

@patrick-rodgers I am experiencing similar issue in v3.0.3. {"odata.error":{"code":"-2130575252, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again."}}}.

I believe it is due to expired x-requestdigest value. It happens when I don't interact with the page for a long time and then try to perform an action without refreshing the page.

github-actions[bot] commented 2 years ago

This issue is locked for inactivity or age. If you have a related issue please open a new issue and reference this one. Closed issues are not tracked.