Search code examples
dynamics-crmdynamics-crm-webapi

Dynamics 365 Web API - How can I register a step for a webhook using the web API?


I am exploring the Dynamics CRM web API and trying to register a webhook that will trigger when entities (like contacts/accounts) are updated/created. I am able to create this setup using the PluginRegistration tool but I'd like to exclude the tool from my workflow. I'd like to register the webhook and the step through web API, if possible. I am able to register a webhook successfully - using a POST request to the following endpoint:

/api/data/v9.0/serviceendpoints

with the following body:

{
    "name":"Test Webhook",
    "url":"http://somewebhookendpoint.somedomain.com",
    "contract":8,
    "authtype":4,
    "authvalue":"args"
}

However, when attempting to create an sdkmessageprocessingstep (which I assume is the step I am trying to create under this webhook), I am getting 400 Bad Request errors. This is the request body I am passing to the sdkmessageprocessingstep create endpoint (api/data/v9.0/sdkmessageprocessingsteps)

{
        "name":"Test for Step Creation",
        "stage":40,
        "rank":1,
        "eventhandlerid":"04e08d50-e63b-eb11-a813-000d3a0a7552",
        "sdkmessageid":"9ebdbb1b-ea3e-db11-86a7-000a3a5473e8",
        "sdkmessagefilterid": "c2c5bb1b-ea3e-db11-86a7-000a3a5473e8",
        "supporteddeployment":0,
        "description":"TEST FOR STEP CREATION #1"
}

but upon passing this request, I am getting the following error (which seems to specify that I am not sending the sdkmessageid in the proper format).

{
    "error": {
        "code": "0x0",
        "message": "An error occurred while validating input parameters: Microsoft.OData.ODataException: A 'PrimitiveValue' node with non-null value was found when trying to read the value of the property 'sdkmessageid'; however, a 'StartArray' node, a 'StartObject' node, or a 'PrimitiveValue' node with null value was expected.\r\n   at Microsoft.OData.JsonLight.ODataJsonLightPropertyAndValueDeserializer.ValidateExpandedNestedResourceInfoPropertyValue(IJsonReader jsonReader, Nullable`1 isCollection, String propertyName)\r\n   at Microsoft.OData.JsonLight.ODataJsonLightResourceDeserializer.ReadPropertyWithValue(IODataJsonLightReaderResourceState resourceState, String propertyName, Boolean isDeltaResourceSet)\r\n   at Microsoft.OData.JsonLight.ODataJsonLightResourceDeserializer.<>c__DisplayClass9_0.<ReadResourceContent>b__0(PropertyParsingResult propertyParsingResult, String propertyName)\r\n   at Microsoft.OData.JsonLight.ODataJsonLightDeserializer.ProcessProperty(PropertyAndAnnotationCollector propertyAndAnnotationCollector, Func`2 readPropertyAnnotationValue, Action`2 handleProperty)\r\n   at Microsoft.OData.JsonLight.ODataJsonLightResourceDeserializer.ReadResourceContent(IODataJsonLightReaderResourceState resourceState)\r\n   at Microsoft.OData.JsonLight.ODataJsonLightReader.StartReadingResource()\r\n   at Microsoft.OData.JsonLight.ODataJsonLightReader.ReadResourceSetItemStart(PropertyAndAnnotationCollector propertyAndAnnotationCollector, SelectedPropertiesNode selectedProperties)\r\n   at Microsoft.OData.JsonLight.ODataJsonLightReader.ReadAtStartImplementationSynchronously(PropertyAndAnnotationCollector propertyAndAnnotationCollector)\r\n   at Microsoft.OData.ODataReaderCore.ReadImplementation()\r\n   at Microsoft.OData.ODataReaderCore.InterceptException[T](Func`1 action)\r\n   at System.Web.OData.Formatter.Deserialization.ODataReaderExtensions.ReadResourceOrResourceSet(ODataReader reader)\r\n   at System.Web.OData.Formatter.Deserialization.ODataResourceDeserializer.Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)"
    }
}

I am not sure how the eventhandlerid,sdkmessageid & sdkmessagefilterid should be passed. I tried passing it as an object - like this:

{
        "name":"test through json",
        "stage":40,
        "rank":1,
        "EventHandler":{"@id":"04e08d50-e63b-eb11-a813-000d3a0a7552"},
        "SdkMessage":{"@id":"9ebdbb1b-ea3e-db11-86a7-000a3a5473e8"},
        "SdkMessageFilter": {"@id":"c2c5bb1b-ea3e-db11-86a7-000a3a5473e8"},
        "description":"TEST through JSON #1"
}

but to no avail (Removing the @ does not work either). The response seems to specify that I have passed some incorrect parameters:

{
    "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 System.Web.OData.Formatter.ODataMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)"
    }
}

Can someone please help by specifying how I can register an sdkmessageprocessingstep under a serviceendpoint using the Dynamics Web API?


Solution

  • Probably an issue with single valued navigation property (lookup) assignment problem but the error message is a bit different though.

    I haven’t tested this payload, so pls test this. Btw CRM REST builder can be helpful in these scenarios for building web api snippets.

    {
            "name":"Test for Step Creation",
            "stage":40,
            "rank":1,
            "eventhandler_serviceendpoint@odata.bind":"/serviceendpoints(04e08d50-e63b-eb11-a813-000d3a0a7552)",
            "sdkmessageid@odata.bind":"/sdkmessages(9ebdbb1b-ea3e-db11-86a7-000a3a5473e8)",
            "sdkmessagefilterid@odata.bind": "/sdkmessagefilters(c2c5bb1b-ea3e-db11-86a7-000a3a5473e8)",
            "supporteddeployment":0,
            "description":"TEST FOR STEP CREATION #1"
    }