{"id":1196,"date":"2017-08-21T12:00:49","date_gmt":"2017-08-21T10:00:49","guid":{"rendered":"http:\/\/tpodolak.com\/blog\/?p=1196"},"modified":"2017-08-21T11:40:42","modified_gmt":"2017-08-21T09:40:42","slug":"asp-net-core-request-serialization-issues-migration-classic-webapi","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2017\/08\/21\/asp-net-core-request-serialization-issues-migration-classic-webapi\/","title":{"rendered":"ASP.NET Core \u2013  request serialization issues after migration from classic WebApi"},"content":{"rendered":"<p>We&#8217;ve been migrating a classic <i>WebApi<\/i> application into the <i>ASP.NET Core API<\/i> for quite a while now, and last week we decided to deploy it on the test environment and try to run a website against it. We were pretty confident about the quality of a migration because all of the integration tests from old <i>API<\/i> were green when running against a new one. We were expecting maybe some business logic bugs but from our perspective, the infrastructure part was good to go. Unfortunately, when the <i>QA&#8217;s<\/i> run the selenium test suite they quickly found a major issue in our codebase. They basically were getting <i>HTTP 500<\/i> errors indicating a <i>NullReferenceException<\/i>. That was pretty surprising to us and after a bit of a digging we found following lines in the logs<\/p>\n<pre lang=\"bash\">\r\nTimeStamp=2017-08-20 00:43:49.4383 TraceId=0HL77AF0N305P Level=DEBUG Message=JSON input formatter threw an exception. Newtonsoft.Json.JsonSerializationException: Error converting value {null} to type 'System.Int32'. Path 'PassengerNumber', line 2, position 26. ---> System.InvalidCastException: Null object cannot be converted to a value type.\r\n   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)\r\n   --- End of inner exception stack trace ---\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)\r\n<\/pre>\n<p>this was resulting in a null request in controller&#8217;s action<br \/>\n<a href=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NullRequest.png\"><img decoding=\"async\" src=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NullRequest.png\" alt=\"\"  height=\"281\" class=\"aligncenter size-full wp-image-1201\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NullRequest.png 708w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NullRequest-150x60.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NullRequest-300x119.png 300w\" sizes=\"(max-width: 708px) 100vw, 708px\" \/><\/a> As you can see <i>JSON<\/i> serializer was not able to convert null into the int. We double checked the requests coming from front-end and this is how one of them looked like<\/p>\n<pre lang=\"javascript\">\r\n{\r\n   \"PassengerNumber\": null,\r\n   \"PassengerType\": \"2\"\r\n}\r\n<\/pre>\n<p>whereas corresponding request class on the server side was written in following way<\/p>\n<pre lang=\"csharp\">\r\npublic class CreatePassengerRequest\r\n{\r\n    public int PassengerNumber { get; set; }\r\n        \r\n    public int PassengerType { get; set; }\r\n}\r\n<\/pre>\n<p>Clearly front-end shouldn&#8217;t be sending a null as a <i>PassengerNumber<\/i> however the same request was serialized just fine when running against classic <i>WebApi<\/i><br \/>\n<a href=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAspWebApi.png\"><img decoding=\"async\" src=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAspWebApi.png\" alt=\"\" height=\"272\" class=\"aligncenter size-full wp-image-1200\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAspWebApi.png 691w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAspWebApi-150x59.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAspWebApi-300x118.png 300w\" sizes=\"(max-width: 691px) 100vw, 691px\" \/><\/a> Fortunately the fix for that was pretty straightforward. All we had to do was to configure <i>JSON<\/i> serializer to ignore null values. <\/p>\n<pre lang=\"csharp\">\r\n\/\/ This method gets called by the runtime. Use this method to add services to the container.\r\npublic void ConfigureServices(IServiceCollection services)\r\n{\r\n    services.AddMvc().AddJsonOptions(options =>\r\n    {\r\n        options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;\r\n    });\r\n}\r\n<\/pre>\n<p>From now on we were able to properly serialize the request<br \/>\n<a href=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAfterChange.png\"><img decoding=\"async\" src=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAfterChange.png\" alt=\"\" height=\"291\" class=\"aligncenter size-full wp-image-1199\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAfterChange.png 703w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAfterChange-150x62.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/08\/asp-net-core-request-serialization-issues-after-migration-from-classic-webapi\/NotNullAfterChange-300x124.png 300w\" sizes=\"(max-width: 703px) 100vw, 703px\" \/><\/a> Source code for this post can be found <a href=\"https:\/\/github.com\/tpodolak\/Blog\/tree\/master\/AspNetCoreRequestPropertyNullParsing\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;ve been migrating a classic WebApi application into the ASP.NET Core API for quite a while now, and last week we decided to deploy it on the test environment and try to run a website against it. We were pretty confident about the quality of a migration because all of the integration tests from old [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[317],"tags":[318],"class_list":["post-1196","post","type-post","status-publish","format-standard","hentry","category-asp-net-core","tag-asp-net-core"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=1196"}],"version-history":[{"count":16,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1196\/revisions"}],"predecessor-version":[{"id":1216,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1196\/revisions\/1216"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=1196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=1196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=1196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}