pnpcore icon indicating copy to clipboard operation
pnpcore copied to clipboard

When running in Blazor WASM, constructor is being skipped and instance is returned from ordinary property

Open FelipeCostaGualberto opened this issue 1 year ago • 0 comments

Category

  • [x] Bug

Describe the bug

I'm having a very strange error when referring PnPCore from a Blazor WASM Web App, but in Blazor Server works as expected.

The error happens when PnpCore builds a request batch. Refer here.

I rewrote it just adding a WriteLine before:

Console.WriteLine("batchRequestId being passed as parameter: " + batchRequestId.ToString()); // prints valid GUID such as 59174352-e729-4787-923b-b117235cf925
return new BatchSingleResult<TModel>(batch, batchRequestId, testGuid);

Then the code flows to this constructor, but:

public BatchSingleResult(Batch batch, Guid batchRequestId, Guid testGuid) : base(batch, batchRequestId, testGuid)
{
    // Blazor Server hits this constructor, but Blazor WASM doesn't!!!
}

The weird part is that Blazor WASM hits this statement instead of the constructor above:

public static IBatchSingleResult<T> None { get; } = new BatchSingleResult<T>(null, Guid.Empty);

And then, the code - both in Blazor WASM and Server - flows to the parent constructor:

public BatchResult(Batch batch, Guid batchRequestId, Guid testGuid)
{
    // In Blazor Server, the GUID has the expected value (such as 59174352-e729-4787-923b-b117235cf925)
    // In Blazor WASM, the GUID has the a "default" value: 00000000-0000-0000-0000-000000000000

Why didn’t WASM call the constructor but did call an ordinary static property? Is this a compiler detail related to how C# runs in the browser? Or is it related to trimming or heavy reflection in the PnP library that I haven’t checked yet?

The only place in the library that BatchSingleResult<TModel>.None is used is in the code below (also in BaseBatchRetrieveAsync), but this condition never hits in my application!

if (api.Cancelled)
{
    ApiCancellationMessage(api);
    return BatchSingleResult<TModel>.None;
}

Solution (Edit)

The fix confirms the weird behavior.

1 - delete this line:

public static IBatchSingleResult<T> None { get; } = new BatchSingleResult<T>(null, Guid.Empty);

2 - The code won't compile because of this:

if (api.Cancelled)
{
    ApiCancellationMessage(api);
    return BatchSingleResult<TModel>.None;
}

Just change it for what we just deleted:

if (api.Cancelled)
{
    ApiCancellationMessage(api);
    return new BatchSingleResult<TModel>(null, Guid.Empty);
}

And now it works.

Environment details (development & target environment)

  • SDK version: current (1.14.0)
  • OS: Windows 11
  • SDK used in: Blazor WebAssembly
  • Framework: .NET Core v9.0 (9.0.102)
  • Browser(s): Chrome v133.0.6943.126 64 bits
  • Tooling: Visual Studio 2022

FelipeCostaGualberto avatar Feb 20 '25 00:02 FelipeCostaGualberto