Dynamics Ninja Logo

Blog.

Web API v8.2 - Bad request when setting lookup

Cover Image for Web API v8.2 - Bad request when setting lookup
·
2 min read

I'm working on lots of v8.2 instances and this issue was one of the most annoying issues I experienced.

Problem

You want to create or update custom entity (it's not a problem on OOB ones) with custom value in one of the custom lookup fields. CRM REST Builder will always be my tool number one when it comes to creating Web API requests on Dynamics, but if you try it on v8.2 for the upper problem it will fail.

Here is the simple jQuery code that will update one lookup on the custom entity.

var entity = {};
entity["ic_contact@odata.bind"] = "/contacts(8A593077-20FB-E511-80E0-5065F38A3951)";

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: Xrm.Page.context.getClientUrl() + "/api/data/v8.2/ic_consultings",
    data: JSON.stringify(entity),
    beforeSend: function(XMLHttpRequest) {
        XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
        XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
        XMLHttpRequest.setRequestHeader("Accept", "application/json");
    },
    async: true,
    success: function(data, textStatus, xhr) {
    },
    error: function(xhr, textStatus, errorThrown) {
        Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
    }
});

There is an "ic_consulting" entity that contains one lookup to contact that has a logical name "ic_contact".  If you try this code on v9.0 or any other earlier version that supports Web API it will work flawlessly, but not on the v8.2.

When you execute that code you will get a 400 Bad Request error message that says:

An undeclared property 'ic_contact' which only has property annotations in the payload but no property value was found in the payload. In OData, only declared navigation properties and declared named streams can be represented as properties without values.

An error message will not point us to the problem because of it's saying that there is no property with the name "ic_contact" which obviously exists if we created it.

Solution

The problem lays in the second row of the code. Just in v8.2, we need to change the input parameter to match schema name instead of logical name for lookup fields.

Schema name can be found in fields list under Schema Name column.

After we found schema name for our field it's time to replace the logical name with a newly found schema name.

Working code for this example would be:

var entity = {};
entity["ic_Contact@odata.bind"] = "/contacts(8A593077-20FB-E511-80E0-5065F38A3951)";

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: Xrm.Page.context.getClientUrl() + "/api/data/v8.2/ic_consultings",
    data: JSON.stringify(entity),
    beforeSend: function(XMLHttpRequest) {
        XMLHttpRequest.setRequestHeader("OData-MaxVersion", "4.0");
        XMLHttpRequest.setRequestHeader("OData-Version", "4.0");
        XMLHttpRequest.setRequestHeader("Accept", "application/json");
    },
    async: true,
    success: function(data, textStatus, xhr) {
    },
    error: function(xhr, textStatus, errorThrown) {
        Xrm.Utility.alertDialog(textStatus + " " + errorThrown);
    }
});

The only change here was capital letter C in the logical name "ic_contact" which is changed to "ic_Contact", but in your case, it can be even bigger change (usually it's only a capital letter change).

After we run this code everything will work as expected and we will get response code 204 No Content which is sent when the record is created successfully in Dynamics.

Conclusion

You must be aware that this issue is ONLY present when you use v8.2 Web API in Dynamics. In most cases, schema name will only be a logical name with the first letter written in caps so you don't need to check for the schema name every time.