Skip to content

PnP.Core.Model.SharePoint.Web.GetPages throws JsonException: The JSON value could not be converted to System.Single. Path: $.position.zoneIndex #1552

@larry-lau

Description

@larry-lau

Category

  • Bug

Describe the bug

When calling GetPages API, it throws the follow exception for some pages.

Result: The JSON value could not be converted to System.Single. Path: $.position.zoneIndex | LineNumber: 0 | BytePositionInLine: 105.
Exception: System.Text.Json.JsonException: The JSON value could not be converted to System.Single. Path: $.position.zoneIndex | LineNumber: 0 | BytePositionInLine: 105.
---> System.InvalidOperationException: Cannot get the value of a token type 'Null' as a number.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedNumber(JsonTokenType tokenType)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
--- End of inner exception stack trace ---
at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
at PnP.Core.Model.SharePoint.CanvasControl.GetType(String controlDataJson)
at PnP.Core.Model.SharePoint.Page.LoadFromHtml(String html, String pageHeaderHtml)
at PnP.Core.Model.SharePoint.Page.LoadPageAsync(IList pagesLibrary, IListItem item)
at PnP.Core.Model.SharePoint.Page.LoadPagesAsync(PnPContext context, String pageName)
at PnP.Core.Model.SharePoint.Web.GetPagesAsync(String pageName)
at PnP.Core.Model.SharePoint.Web.GetPages(String pageName)

I print out the content of the CanvasContent1 field of the page that caused the GetPages to fail.

     "id": "61f0ef56-b5f0-4d94-b1b9-0a5087332cc7",
     "controlType": 3,
     "position": {
       "layoutIndex": 1,
       "zoneIndex": null,
       "sectionIndex": 1,
       "controlIndex": 1,
       "sectionFactor": 0,
       "zoneId": "f419c0ec-ee17-48d1-b8cb-30e296c9d286"
     },
     "webPartId": "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",
     "reservedHeight": 207,
     "addedFromPersistedData": true,
     "reservedWidth": 1607
   }

Following the stack trace, the last method that fails is CanvasControl.GetType(controlDataJson) and inspecting the method, it call
var controlData = JsonSerializer.Deserialize(controlDataJson, PnPConstants.JsonSerializer_IgnoreNullValues);

This leads me to the ZoneIndex property which is not nullable.

internal class CanvasPosition
{
    /// <summary>
    /// Gets or sets JsonProperty "zoneIndex"
    /// </summary>
    [JsonPropertyName("zoneIndex")]
    public float ZoneIndex { get; set; }

Steps to reproduce

[TestMethod]
public void DeserializeCanvasControlDataTest()
{
    var controlDataJson = """
        {
          "id": "61f0ef56-b5f0-4d94-b1b9-0a5087332cc7",
          "controlType": 3,
          "position": {
            "layoutIndex": 1,
            "zoneIndex": null,
            "sectionIndex": 1,
            "controlIndex": 1,
            "sectionFactor": 0,
            "zoneId": "f419c0ec-ee17-48d1-b8cb-30e296c9d286"
          },
          "webPartId": "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",
          "reservedHeight": 207,
          "addedFromPersistedData": true,
          "reservedWidth": 1607
        }
        """;
    var controlData = JsonSerializer.Deserialize<CanvasControlData>(controlDataJson, PnPConstants.JsonSerializer_IgnoreNullValues);
    Assert.IsNotNull(controlData);
}

Expected behavior

context.Web.GetPages API should not throw exception on valid site pages.

using (var context = await pnpContextFactory.CreateAsync(new Uri(siteUrl), authProvider))
{
    var page = context.Web.GetPages(pageName).FirstOrDefault(); 
}

Environment details (development & target environment)

DELETE THIS LINE BEFORE SUBMITTING - Complete the following (if ignored you'll be prompted for it before we can address your issue... save the time and provide it in your initial submission).

  • SDK version: 1.14.0
  • OS: [e.g. Windows 11
  • SDK used in: Console App | ASP.Net Web app
  • Framework: .NET 8.0.10
  • Browser(s): N/A
  • Tooling: Visual Studio 2022
  • Additional details: The more context you can provide, the easier it is (and therefore quicker) to help.

Additional context

Our solution is a SaaS base solution that work different client's tenants and this started happening to 2 tenants a few month ago. Since we don't have direct access to the page via SharePoint UI, I am not sure the page looks like visually.

Thanks for your contribution! Sharing is caring.

Metadata

Metadata

Assignees

Labels

area: pages API 📄Working with modern pagesquestionFurther information is requested

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions