microsoftgraph / msgraph-beta-sdk-dotnet

The Microsoft Graph Client Beta Library for .NET supports the Microsoft Graph /beta endpoint. (preview)
Other
95 stars 32 forks source link

[v5.60] Serialization issue #822

Closed AndrewShchetkin closed 5 months ago

AndrewShchetkin commented 6 months ago

Trying to create Intune DeviceCompliancePolicy by Graph SDK and getting a error "Cannot create an abstract class". I started looking on request by Fiddler and found that my request has json with empty props OR just with braces"{}". Code example:

var client = await _clientProvider.GetGraphApiClient();
var response = await client.DeviceManagement.DeviceCompliancePolicies.PostAsync(policy);

Anyway, now I serialize body manualy and it works as expected

var client = await _clientProvider.GetGraphApiClient();
var requestInformation = client.DeviceManagement.DeviceCompliancePolicies.ToPostRequestInformation(policy);
// To fix serialization issue
var strContent = policy.SerializeToJson();
using var content = new StringContent(strContent, Encoding.UTF8, "application/json");
requestInformation.Content = await content.ReadAsStreamAsync();

return await client.RequestAdapter.SendAsync<DeviceCompliancePolicy>(requestInformation,
    DeviceCompliancePolicy.CreateFromDiscriminatorValue);

My implementation for serialize objects:

public static string SerializeToJson<T>(this T entity) where T : IParsable
{
    var writer = new JsonSerializationWriter();
    writer.WriteObjectValue(string.Empty, entity);

    using var reader = new StreamReader(writer.GetSerializedContent());
    string result = reader.ReadToEndAsync().Result;

    return result;
}

Expected behavior I believe body should be serialized correct.

Client version Microsoft.Graph.Core - 3.1.3 Microsoft.Graph.Beta - 5.60.0

Additional context Here is Batch request with 2 requests, first one is prepared manualy and second by method ToPostRequestInformation. NOTE it's the same object

{
    "requests": [
        {
            "id": "54980aed-b741-489d-bafd-176f9e5a7614",
            "url": "/deviceManagement/deviceCompliancePolicies",
            "method": "POST",
            "headers": {
                "Accept": "application/json",
                "Authorization": "Bearer ",
                "Content-Type": "application/json; charset=utf-8"
            },
            "body": {
                "@odata.type": "#microsoft.graph.windows81CompliancePolicy",
                "displayName": "Win 8 All Compliant",
                "scheduledActionsForRule": [
                    {
                        "scheduledActionConfigurations": [
                            {
                                "actionType": "block",
                                "gracePeriodHours": 0,
                                "notificationMessageCCList": [],
                                "notificationTemplateId": "00000000-0000-0000-0000-000000000000"
                            }
                        ]
                    }
                ],
                "version": 35,
                "osMinimumVersion": "8.1",
                "passwordBlockSimple": false,
                "passwordRequired": false,
                "passwordRequiredType": "deviceDefault",
                "storageRequireEncryption": false
            }
        },
        {
            "id": "8b8fa746-a31e-4634-b66a-992bb8d4d36c",
            "url": "/deviceManagement/deviceCompliancePolicies",
            "method": "POST",
            "headers": {
                "Accept": "application/json",
                "Authorization": "Bearer ",
                "Content-Type": "application/json"
            },
            "body": {
                "id": null,
                "roleScopeTagIds": null,
                "createdDateTime": null,
                "description": null,
                "lastModifiedDateTime": null,
                "AdditionalData": null,
                "assignments": null,
                "scheduledActionsForRule": [
                    {
                        "scheduledActionConfigurations": [
                            {
                                "actionType": "block",
                                "gracePeriodHours": 0,
                                "notificationMessageCCList": [],
                                "notificationTemplateId": "00000000-0000-0000-0000-000000000000"
                            }
                        ]
                    }
                ]
            }
        }
    ]
}
andrueastman commented 6 months ago

Transferring this to the beta repo as this related to the beta SDK.

andrueastman commented 6 months ago

Thanks for raising this @AndrewShchetkin

Any chance you can confirm if the policy object is received from another API response. This may be related to the working of the backingStore.

https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/dev/docs/upgrade-to-v5.md#backing-store

AndrewShchetkin commented 6 months ago

Thanks for the quick answer @andrueastman Yes, I guess it's related. Actualy I deserialize object from json and then set some default fields as null or so on.

Do you have any idea how can I send all object properties instead of recreate instance?

andrueastman commented 5 months ago

@AndrewShchetkin

Any chance it works out for you if you reset the backingStore store state as below before sending out the data?

policy.BackingStore.InitializationCompleted = false;
AndrewShchetkin commented 5 months ago

@andrueastman Yeah, it makes serialization better but not enough. In this case I'm sendong entity with null fields, but API doesn't expect it. For example if I pass createdDateTime property as null API throw an error

"A null value was found for the property named 'createdDateTime', which has the expected type 'Edm.DateTimeOffset[Nullable=False]'"

So, I don't see any other variant as recreate entity directly before the post request. Of course serialize and deserialize works in the same way.

I guess we can close the issue, again @andrueastman thank you for help

microsoft-github-policy-service[bot] commented 5 months ago