Wednesday, November 26, 2014

Dynamics GP JSON Integration Issue: null object property values for JSON parsed by MVC controller

By Steve Endow

I haven't yet seen code samples or API documentation for the new Dynamics GP 2015 Service Based Architecture (SBA), but I have a hunch that this might be relevant when we start working with GP 2015 SBA and use JSON to communicate with the GP SBA interface.

WARNING:  If the title wasn't warning enough, this post is a full-on geek fest, so if you aren't a developer that loves Riddles of the Code, flee now.

I'm currently working on a web service application that allows a Linux web server to integrate to Dynamics GP.  After considering various options, the client and I agreed that the simplest approach would be for me to develop a custom web application that could receive and send JSON.  The Linux developers were very comfortable with this, and after getting some help from an expert with experience developing JSON web apps in Visual Studio using MVC, I was able to create an integration that worked great.

After the release of the initial version of the web integration, I noticed a quirk about how blank JSON values were being received by my code.

If the client sent a JSON parameter value that was blank, that particular property on my object would be null.  So if he did not supply a Address2 value, I would get Customer.Address2 == null.

I thought that it was due to how I was defining my objects in Visual Studio using the simple property definition style, such as:

   public string Address2 { get; set; }

Since I wasn't defining a default value for the property, I thought it made sense that I was getting null, assuming that the .NET MVC JSON parser was skipping the empty JSON parameters.  Seemed to make perfect sense at the time.

I didn't think much about it, and just added some workaround code to check for null values and set them to empty strings.  In hindsight, I now know that was sloppy, but since I didn't realize the underlying problem, it was a simple fix and seemed to worked.

Now, I'm adding some additional functionality to the web application, as the customer wants to have new features, such as the ability to search for GP customers.  This time around, I'm more familiar with web app development and MVC, so I was a little more observant about the null property issue.

While testing my recent enhancements, I once again noticed that when I submitted a request to my web app, blank JSON values were being translated to null property values on my objects.  Still thinking that this was due to my object property definitions, I modified my object to use a "full" property definition, like so:

private string address = string.Empty;
public string Address
{
    get { return address; }
    set { address = value; }
}

When I walked through the code in debug mode, what I found surprised me.  Even though my property was initializing properly to an empty string, the MVC JSON parser was subsequently setting the property value to null.

So the null values weren't due to my property definitions!  So why was I getting a null, and how can I fix this?

I didn't even know how to phrase a search, but after a few random search attempts in Google, I found this Stack Overflow thread that appeared to exactly describe my scenario:

http://stackoverflow.com/questions/12734083/string-empty-converted-to-null-when-passing-json-object-to-mvc-controller

It appears that with MVC version 2.0, Microsoft changed the way that JSON is parsed.  Instead of assigning empty strings, the newer MVC versions assign null.  Here is a post that covers some of that history:

http://brianreiter.org/2010/09/16/asp-net-mvc-2-0-undocumented-model-string-property-breaking-change/

Okay, great, so how do I "fix" this "problem"?

The Stack Overflow post has several suggestions, none of which I really understand.  I understand the concept that it changes how the JSON is parsed, but the actual code is currently Greek to me.

I ended up trying the suggestion to create a new class called EmptyStringDataAnnotationsModelMetadataProvider.  I then modify my Global.asax file and add the single line to the Application_Start() method.

ModelMetadataProviders.Current = new EmptyStringDataAnnotationsModelMetadataProvider();


I am using MVC 4.0, and this solution worked for me.

Now, when I pass in JSON with blank parameter values, my string properties are empty strings and not nulls.  You know you are a geek when you get excited about an empty string.

It was a bit of a journey, but this obscure change should make my life easier.

And I suspect that once we start developing against the GP 2015 Service Based Architecture, this may come in handy if GP returns empty JSON parameters.


Steve Endow is a Microsoft MVP for Dynamics GP and a Dynamics GP Certified IT Professional in Los Angeles.  He is the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

You can also find him on Google+ and Twitter






No comments: