When running in Blazor WASM, constructor is being skipped and instance is returned from ordinary property
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