2

I've got a really puzzling issue relating to mapping data to a Model in my Web API. It's a bit complex, so let me know if I haven't explained it well enough and I'll do my best to elaborate.

See Edit 2, the problem has changed

I have a MVC 5 application in which the user submits form data and that data is mapped to a model automatically based on matching the names of the fields in the JSON with the names of the model's members. For example, if the incoming JSON for user names is of the form:

{Id=0, Name=testName}

Then there will be a model called (example name only) UsernameModel that has an int id and a string name among other properties that don't need to be mapped from JSON (there are a number of these models for a number of different forms).

I'm not sure how useful it will be but I noticed that the call at the bottom of the stack trace was

System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(
ModelMetadata metadata, ValidationContext validationContext, Object container,
IEnumerable`1 validators)

Could this Validation have something to do with my probleM?

None of us have any idea as to why this is happening, and only happening on my machine. Any ideas/suggestions? Things to try? Ways to narrow down the error?

Edit: Found another question which may be related, but it's really odd that this only occurs on my computer, whereas in that post it was just a general problem.

Edit 2: I've narrowed down the issue, and have a much more specific problem now. I have discovered that on my computer the Web API's mapping of the JSON to the C# object (or some other process called during the mapping) calls the get() for each property in the process of mapping the object. This is why the exception is being thrown; one of the properties throws an exception when the get() is called (by design). On others' computers, the get() is called only on those properties that are mapped to by the JSON, and we're not sure why.

Edit 3 (revised): In researching System.Web.Http.ValidationI found this post which asked how to disable it. I followed the instructions in the accepted answer and disabled the default validation, and my issue went away! I'm still left with the question as to why this would be different between two computers, but at least I'm getting somewhere!

Community
  • 1
  • 1
Chris H.
  • 2,544
  • 19
  • 32
  • It's looking more likely to me that the error isn't the mapping, it's the validation. Validation doesn't "know" which properties were or weren't mapped from JSON. It just knows that it has an object, and it validates its properties. Can you try removing the validation from the property that throws a NotImplementedException? My guess is if you don't validate it it won't get called. That doesn't explain the difference between two computers but it might get you looking in a different place. – Scott Hannen Jul 15 '16 at 02:59

3 Answers3

1

For the same application code to behave so differently on two computers is unlikely. It's not impossible, just unlikely.

When something happens that borders on impossible, question every detail. In this case, question whether you're actually executing the same code in both places. Make sure one of you doesn't have an outdated version of the code from source control. Check the versions of the libraries you're referencing. See if someone has a different web.config. If necessary, step through the code in both places.

I don't know what it is, but I'm 90% certain you're going to find that you're getting different behaviors because you're executing something slightly different.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • I understand that since we have the same code, likely the problem is in some sort of configuration, but that's what I'm looking for, ideas or suggestions as to what configurations could affect data mapping. – Chris H. Jul 14 '16 at 17:20
  • I agree with @ScottHannen and doubt it's a configuration issue. More likely a deployment issue, where the application you are running is not coming from the code you are seeing in your IDE (either in your machine, or in the others). This can be easily seen trying to debug stepping through the code from the IDE (on each machine), and see if that comes out differently (if it's a different source, your breakpoints will be hollow if using Visual Studio), or trying to make some noticeable change within the class you are trying to do (make a log to a file when the method enters, for example) – Jcl Jul 14 '16 at 19:07
  • @Jcl I have tried stepping through, but the real issue is that the exception is thrown by the automatic mapping of JSON to c# object; more specifically, the web api POST method tries to access the member (which has the exception when it is accessed) in its mapping to the input parameter. (e.g. `public type POST(BasicModel input)` throws an exception in creating `input`) I'm not sure how I can access that process to see what's happening. – Chris H. Jul 14 '16 at 20:28
  • Just as a note, about an hour ago we sat down side by side and went through every reference and ensured that they are indeed the same version. The only versioning we could find that was different is that I'm running VS2015 update 2 while he is running VS2015 update 3. I'm updating now, doubt it will fix it though. – Chris H. Jul 14 '16 at 23:08
  • That it's calling the `get` method of the class *after* deserializing suggests to me that it's trying to validate those properties. Could the difference be in the validation? – Scott Hannen Jul 15 '16 at 02:13
0

Check the break on exceptions settings in your Visual Studio and the other users'. Maybe it is throwing the same exception on their computers but their Visual Studio is ignoring it because it's handled. That would be an environmental difference that has nothing to do with the code or configuration.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • They have also tried with breakpoints and confirmed that for them, only the `get()` for the properties that are deserialized from JSON get called, and the others (the once that get called for me) do not. – Chris H. Jul 14 '16 at 22:46
0

I was able to solve my problem by disabling the default System.Web.HTTP.Validation validation on my entire project. See this stack post for where I got the solution, which is shown below:

config.Services.Clear(typeof(ModelValidatorProvider));

If this is put at the top of the RouteConfig file, the default validation will be disabled, and the issue does not occur. This still does not explain why it was only validating that property on my computer, and that question remains unanswered, however for the purpose of this question this solves the problem.

Community
  • 1
  • 1
Chris H.
  • 2,544
  • 19
  • 32