{"id":1235,"date":"2017-10-17T10:00:08","date_gmt":"2017-10-17T08:00:08","guid":{"rendered":"http:\/\/tpodolak.com\/blog\/?p=1235"},"modified":"2017-10-17T00:34:23","modified_gmt":"2017-10-16T22:34:23","slug":"asp-net-core-1-x-curios-case-missing-ioptionst-array-item","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2017\/10\/17\/asp-net-core-1-x-curios-case-missing-ioptionst-array-item\/","title":{"rendered":"ASP.NET Core 1.x &#8211;  curios case of missing IOptions&lt;T&gt; array item"},"content":{"rendered":"<h3> 1. Introduction<\/h3>\n<p>Last week while I was working on one of the features for my current project, I noticed quite surprising behavior of <i>IOptions&lt;T&gt;<\/i> object.  Long story short, for some reasons there were missing array elements in my parsed application settings class.<\/p>\n<h3> 2. Problem <\/h3>\n<p>Just like everyone else, we store our application settings in <i>JSON<\/i> file. The settings are pretty straightforward, just a bunch of properties with some nested objects<\/p>\n<pre lang=\"javascript\">\r\n{\r\n    \"PaymentMethods\": [\r\n        {\r\n            \"Name\": \"MasterCard\",\r\n            \"ExcludedCurrencies\": []\r\n        },\r\n        {\r\n            \"Name\": \"Visa\",\r\n            \"ExcludedCurrencies\": null\r\n        },\r\n        {\r\n            \"Name\": \"Apple Pay\"\r\n        },\r\n        {\r\n            \"Name\": \"PayPal\",\r\n            \"ExcludedCurrencies\": [\r\n                \"MAD\"\r\n            ]\r\n        }\r\n    ]\r\n}\r\n<\/pre>\n<p>which are bound to the <i>AppSetting<\/i> class thanks to these couple of lines of code<\/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.Configure<AppSettings>(Configuration);\r\n    \/\/ Add framework services.\r\n    services.AddMvc();\r\n}\r\n<\/pre>\n<p>where <i>AppSettings<\/i> class looks as follows<\/p>\n<pre lang=\"csharp\">\r\npublic class AppSettings\r\n{\r\n    public List<PaymentMethod> PaymentMethods { get; set; }\r\n}\r\n\r\npublic class PaymentMethod\r\n{\r\n    public string Name { get; set; }\r\n\r\n    public List<string> ExcludedCurrencies { get; set; }\r\n}\r\n<\/pre>\n<p>As you can see nothing too fancy in here, standard <i>ASP.NET Core<\/i> approach for handling configuration files. However, if you access the <i>PaymentMethods<\/i> property of <i>IOptions&lt;AppSettings&gt;<\/i><\/p>\n<pre lang=\"csharp\">\r\n[Route(\"api\/[controller]\")]\r\npublic class ValuesController : Controller\r\n{\r\n    private readonly IOptions<AppSettings> _appSettings;\r\n\r\n    public ValuesController(IOptions<AppSettings> appSettings)\r\n    {\r\n        _appSettings = appSettings;\r\n    }\r\n        \r\n    \/\/ GET api\/values\r\n    [HttpGet]\r\n    public List<PaymentMethod> Get()\r\n    {\r\n        return _appSettings.Value.PaymentMethods;\r\n    }\r\n}\r\n<\/pre>\n<p>you will see that instead of four elements we ended up having 3 items<br \/>\n<a href=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/MissingItem.png\"><img decoding=\"async\" src=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/MissingItem.png\" alt=\"\" width=\"339\" class=\"aligncenter size-full wp-image-1237\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/MissingItem.png 339w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/MissingItem-130x150.png 130w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/MissingItem-260x300.png 260w\" sizes=\"(max-width: 339px) 100vw, 339px\" \/><\/a><br \/>\nas the &#8220;Visa&#8221; element is missing.<\/p>\n<h3> 3. Solution<\/h3>\n<p>If you look closely at the appsettings.json file you will notice that a &#8220;Visa&#8221; item configuration is a bit different than the ones which are parsed just fine. Namely <i>null<\/i> is assigned to <i>excludedCurrencies<\/i> property, whereas in other items an empty array or no property at all is used. So the first fix is just to use the same approach as in the other items<\/p>\n<pre lang=\"javascript\">\r\n{\r\n    \"Name\": \"Visa\",\r\n    \"ExcludedCurrencies\": []\r\n}\r\n<\/pre>\n<p>This approach works fine, however, it is not a silver bullet as someone still might use null and introduce a bug. Another fix might be upgrading to <i>ASP.NET Core 2.0<\/i> as the problem doesn\u2019t seem to exist in there. Of course, this is rather a huge change so not everyone will be willing to do it. The last option is a manual installation of <i>Microsoft.Extensions.Configuration.Binder 2.0<\/i> along with <i>Microsoft.Extensions.Configuration.Json 2.0<\/i> package. However, this approach requires you to retarget your application to <i>netcoreapp2.0<\/i>. One way or another every solution in here works fine, so once you apply the fix you will see all items in the array<br \/>\n<a href=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/AllItems.png\"><img decoding=\"async\" src=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/AllItems.png\" alt=\"\" width=\"334\" class=\"aligncenter size-full wp-image-1236\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/AllItems.png 334w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/AllItems-111x150.png 111w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/10\/asp-net-core-1-x-curios-case-of-missing-ioptions-array-item\/AllItems-222x300.png 222w\" sizes=\"(max-width: 334px) 100vw, 334px\" \/><\/a> Source code for this post can be found <a href=\"https:\/\/github.com\/tpodolak\/Blog\/tree\/master\/ASP.NETCoreCuriousCaseOfMissingIOptionsOfTArrayItem\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction Last week while I was working on one of the features for my current project, I noticed quite surprising behavior of IOptions&lt;T&gt; object. Long story short, for some reasons there were missing array elements in my parsed application settings class. 2. Problem Just like everyone else, we store our application settings in JSON [&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-1235","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\/1235","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=1235"}],"version-history":[{"count":9,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1235\/revisions"}],"predecessor-version":[{"id":1246,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1235\/revisions\/1246"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=1235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=1235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=1235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}