I am attempting to implement the Search Resource Capability as described here: Search Resource Availability with Universal Resource Scheduling API
There is an example here of how to implement it via JavaScript (although the JavaScript libraries are probably deprecated or unsupported), which I have referenced here: How to use the Search Resource Availability API – Universal Resource Scheduling
I have written a .NET Core Class Library that uses the Dynamics 365 OData Service to POST to the msdyn_SearchResourceAvailability Action.
I have seen some examples on the internet, but they all use the Dynamics 365 SDK, not the Dynamics 365 Web API.
I am getting an error and have therefore extracted the JSON that is being posted and tried the same call in Postman, where I am getting the same error:
{ "error": { "code": "0x0", "message": "An error occurred while validating input parameters: Microsoft.OData.ODataException: Does not support untyped value in non-open type.\r\n at System.Web.OData.Formatter.Deserialization.DeserializationHelpers.ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, Object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyStructuralProperties(Object resource, ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)\r\n at Microsoft.Crm.Extensibility.CrmODataEntityDeserializer.ApplyStructuralProperties(Object resource, ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.Deserialization.ODataResourceDeserializer.ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)\r\n at Microsoft.Crm.Extensibility.ODataV4.CrmODataActionPayloadDeserializer.ReadEntry(ODataDeserializerContext readContext, ODataParameterReader reader, IEdmOperationParameter parameter)\r\n at Microsoft.Crm.Extensibility.ODataV4.CrmODataActionPayloadDeserializer.Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)", "innererror": { "message": "An error occurred while validating input parameters: Microsoft.OData.ODataException: Does not support untyped value in non-open type.\r\n at System.Web.OData.Formatter.Deserialization.DeserializationHelpers.ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, Object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyStructuralProperties(Object resource, ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)\r\n at Microsoft.Crm.Extensibility.CrmODataEntityDeserializer.ApplyStructuralProperties(Object resource, ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.Deserialization.ODataResourceDeserializer.ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)\r\n at Microsoft.Crm.Extensibility.ODataV4.CrmODataActionPayloadDeserializer.ReadEntry(ODataDeserializerContext readContext, ODataParameterReader reader, IEdmOperationParameter parameter)\r\n at Microsoft.Crm.Extensibility.ODataV4.CrmODataActionPayloadDeserializer.Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)", "type": "Microsoft.Crm.CrmHttpException", "stacktrace": " at Microsoft.Crm.Extensibility.OData.CrmODataUtilities.ValidateInputParameters(ModelStateDictionary controllerModelState)\r\n at Microsoft.Crm.Extensibility.OData.ActionController.<>c__DisplayClass9_0.b__0()\r\n at Microsoft.PowerApps.CoreFramework.ActivityLoggerExtensions.Execute[TResult](ILogger logger, EventId eventId, ActivityType activityType, Func`1 func, IEnumerable`1 additionalCustomProperties)\r\n at Microsoft.Xrm.Telemetry.XrmTelemetryExtensions.Execute[TResult](ILogger logger, XrmTelemetryActivityType activityType, Func`1 func)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()" } } }
The JSON that is being posted is as follows:
{
"Version": "1",
"Requirement": {
"msdyn_duration": 180,
"msdyn_effort": 1,
"msdyn_fromdate": "2020-03-10T00:00:00 00:00",
"msdyn_latitude": 55.784129,
"msdyn_longitude": -3.982742,
"msdyn_name": "Super Heroes Resource Requirement",
"msdyn_remainingduration": 180,
"msdyn_todate": "2020-03-12T00:00:00 00:00",
"msdyn_worklocation": 690970002
},
"Settings": {
"ConsiderSlotsWithLessThanRequiredCapacity": false,
"ConsiderSlotsWithLessThanRequiredDuration": false,
"ConsiderTravelTime": false,
"ConsiderSlotsWithOverlappingBooking": false,
"ConsiderSlotsWithProposedBookings": false,
"MovePastStartDateToCurrentDate": false,
"UseRealTimeResourceLocation": false,
"MaxResourceTravelRadius": {
"Value": 10,
"Unit": 192350000
},
"SortOrder": {
"value": [
{
"Name": "bookableresource",
"SortOrder": 0
}
]
}
},
"ResourceSpecification": {
"ResourceTypes": {
"value": [
2,
3,
5
]
},
"PreferredResources": {
"value": [
{
"bookableresourceid": "d7315245-b162-ea11-a811-000d3a0bad7c"
},
{
"bookableresourceid": "b54bc744-b162-ea11-a811-000d3a0ba110"
}
]
},
"RestrictedResources": {
"value": [
{
"bookableresourceid": "ba6d4a4b-b162-ea11-a811-000d3a0bad7c"
},
{
"bookableresourceid": "ca6d4a4b-b162-ea11-a811-000d3a0bad7c"
}
]
},
"Constraints": {
"Characteristics": {
"value": [
{
"characteristicid": "a02db73e-b162-ea11-a811-000d3a0ba110"
}
]
},
"Roles": {
"value": [
{
"bookableresourcecategoryid": "d56d4a4b-b162-ea11-a811-000d3a0bad7c"
}
]
},
"Territories": {
"value": [
{
"territoryid": "7c2db73e-b162-ea11-a811-000d3a0ba110"
}
]
},
"UnspecifiedTerritory": false,
"OrganizationalUnits": {
"value": [
{
"msdyn_organizationalunitid": "822db73e-b162-ea11-a811-000d3a0ba110"
}
]
},
"BusinessUnits": {
"value": [
{
"businessunitid": "fba6cf4b-f24a-ea11-a813-00224801cd21"
}
]
}
}
}
}
Could anyone please advise where I am going wrong?
Hi,
Did you received any workaround on this issue.
We implemented a custom action where the output will returns the entity collection of Time SLots, in the custom action we are calling (msdyn_searchresourceavailability), but when we are trying to call this action in WEB API, the entity collection output is not being retrieved where we are getting below result.
"value": [
{
"@odata.type": "#Microsoft.Dynamics.CRM.bookableresourcebooking"
},
{
"@odata.type": "#Microsoft.Dynamics.CRM.bookableresourcebooking"
},
{
"@odata.type": "#Microsoft.Dynamics.CRM.bookableresourcebooking"
},
{
"@odata.type": "#Microsoft.Dynamics.CRM.bookableresourcebooking"
}
]
Has anyone been able to return a valid response to this action via the OData Service? I'm encountering the same issue as Johan mentioned at getting to the same point where in it doesnt appear possible (or at least it isnt clear how to) pass valid values for the Settings and ResourceSpecification due to the action not specifying an entity type?
Part of the problem is that the C# samples out there use the SDK, which in turn uses the deprecated 2011 WCF service, not the current OData Service. It looks as if the OData Service is more strict in terms of the @odata.type you specify, in that it looks to check that the attributes you are providing are real attributes/fields of that entity. The problem with Settings and ResourceSpecification is that in the Action, the type of entity is not specified.
@Alexandre Heinze the problem I'm facing is that the C# samples out there use the SDK, not the raw OData Service.
It would be good to see working C# code that uses the raw OData Service rather than an OrganizationService.Execute, which is only available in the SDK libraries. The SDK libraries are not compatible with .NET Core and one has to use the raw OData Service.
I also tried the API using Postman and failed. Seems to be related to the nested JSON structure that you need to provide (also the provided example includes significant effort to construct that JSON). At least the sample works and people in this forum also mentioned they have working C# code.
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 290,802 Super User 2024 Season 2
Martin Dráb 229,129 Most Valuable Professional
nmaenpaa 101,154