Note that there are some explanatory texts on larger screens.

plurals
  1. POMVC3 RTM fails number type coercion when deserializing JSON
    text
    copied!<p>Simply put serializing data in the "application/json; charset=utf-8" format misbehaves in MVC3 (and possibly older versions). What happens is a nullable numbers all end up null, and numbers of "decimal" type end up 0 when serializing them inside a javascript object (to JSON) and leaving them as numbers and not strings. </p> <p><strong>Here is the example code that illustrates this misbehavior</strong><br> <em>- - - this example was created using jquery-1.4.4.js and jquery.json-2.2.js - - - -</em></p> <p><em>HomeController.cs:</em></p> <pre><code>public class HomeController : Controller { public ActionResult Index() { ViewBag.SaveUrl = Url.Action("Save", "Home", new { inspectionFormID = Guid.Empty }, Request.Url.Scheme); return View(); } public JsonResult Save(Guid inspectionFormID, JsonTest result) { return Json(result); } public class JsonTest { public double Double { get; set; } public double? DoubleNull { get; set; } public decimal Decimal { get; set; } public decimal? DecimalNull { get; set; } public Double Double2 { get; set; } public Double? Double2Null { get; set; } public Decimal Decimal2 { get; set; } public Decimal? Decimal2Null { get; set; } public Single Single { get; set; } public Single? SingleNull { get; set; } public float Float { get; set; } public float? FloatNull { get; set; } public int Int { get; set; } public int? IntNull { get; set; } public Int64 Int64 { get; set; } public Int64? Int64Null { get; set; } } } </code></pre> <p><em>Index.cshtml:</em></p> <pre><code> @{ ViewBag.Title = "Index"; } &lt;h2&gt;Index&lt;/h2&gt; &lt;b&gt;@ViewBag.SaveUrl&lt;/b&gt; &lt;br /&gt; &lt;hr /&gt; &lt;br /&gt; &lt;h3&gt;Integral Numbers&lt;/h3&gt; &lt;button type="button" class="a"&gt;Clicky&lt;/button&gt; &lt;div&gt;&lt;/div&gt; &lt;h3&gt;Decimal Numbers (xx.0)&lt;/h3&gt; &lt;button type="button" class="b"&gt;Clicky&lt;/button&gt; &lt;div&gt;&lt;/div&gt; &lt;h3&gt;Decimal Numbers (xx.5)&lt;/h3&gt; &lt;button type="button" class="c"&gt;Clicky&lt;/button&gt; &lt;div&gt;&lt;/div&gt; &lt;h3&gt;Integral Numbers as strings&lt;/h3&gt; &lt;button type="button" class="d"&gt;Clicky&lt;/button&gt; &lt;div&gt;&lt;/div&gt; &lt;h3&gt;Decimal Numbers as strings (xx.5)&lt;/h3&gt; &lt;button type="button" class="e"&gt;Clicky&lt;/button&gt; &lt;div&gt;&lt;/div&gt; &lt;script type="text/javascript"&gt; $(function () { var saveUrl = '@ViewBag.SaveUrl'; var printObj = function (inObj, destx) { var dest = $('&lt;table&gt;').appendTo(destx), dst1 = $('&lt;tr&gt;').appendTo(dest), dst2 = $('&lt;tr&gt;').appendTo(dest); for (var p in inObj) { $('&lt;th&gt;', { text: p, css: { color: 'red', padding: '3px', background: '#dedede' } }).appendTo(dst1); $('&lt;td&gt;', { text: inObj[p] || 'null' }).appendTo(dst2); } }; $('button.a').click(function () { var curr = $(this).next(), outR = { Double: 12, DoubleNull: 13, Decimal: 14, DecimalNull: 15, Double2: 16, Double2Null: 17, Decimal2: 18, Decimal2Null: 19, Single: 20, SingleNull: 21, Float: 22, FloatNull: 23, Int: 24, IntNull: 25, Int64: 26, Int64Null: 27 }; $('&lt;hr /&gt;').appendTo(curr); printObj(outR, curr); $.ajax({ type: 'POST', url: saveUrl, contentType: "application/json; charset=utf-8", dataType: 'json', data: $.toJSON({ inspectionFormID: 'fbde6eda-dde6-4ba9-b82d-3a35349415f0', result: outR }), error: function (jqXHR, textStatus, errorThrown) { alert('save failed'); }, success: function (data, textStatus, jqXHR) { printObj(data, curr); } }); }); $('button.b').click(function () { var curr = $(this).next(), outR = { Double: 12.0, DoubleNull: 13.0, Decimal: 14.0, DecimalNull: 15.0, Double2: 16.0, Double2Null: 17.0, Decimal2: 18.0, Decimal2Null: 19.0, Single: 20.0, SingleNull: 21.0, Float: 22.0, FloatNull: 23.0, Int: 24.0, IntNull: 25.0, Int64: 26.0, Int64Null: 27.0 }; $('&lt;hr /&gt;').appendTo(curr); printObj(outR, curr); $.ajax({ type: 'POST', url: saveUrl, contentType: "application/json; charset=utf-8", dataType: 'json', data: $.toJSON({ inspectionFormID: 'fbde6eda-dde6-4ba9-b82d-3a35349415f0', result: outR }), error: function (jqXHR, textStatus, errorThrown) { alert('save failed'); }, success: function (data, textStatus, jqXHR) { printObj(data, curr); } }); }); $('button.c').click(function () { var curr = $(this).next(), outR = { Double: 12.5, DoubleNull: 13.5, Decimal: 14.5, DecimalNull: 15.5, Double2: 16.5, Double2Null: 17.5, Decimal2: 18.5, Decimal2Null: 19.5, Single: 20.5, SingleNull: 21.5, Float: 22.5, FloatNull: 23.5, Int: 24.5, IntNull: 25.5, Int64: 26.5, Int64Null: 27.5 }; $('&lt;hr /&gt;').appendTo(curr); printObj(outR, curr); $.ajax({ type: 'POST', url: saveUrl, contentType: "application/json; charset=utf-8", dataType: 'json', data: $.toJSON({ 'inspectionFormID': 'fbde6eda-dde6-4ba9-b82d-3a35349415f0', 'result': outR }), error: function (jqXHR, textStatus, errorThrown) { alert('save failed'); }, success: function (data, textStatus, jqXHR) { printObj(data, curr); } }); }); $('button.d').click(function () { var curr = $(this).next(), outR = { Double: '12', DoubleNull: '13', Decimal: '14', DecimalNull: '15', Double2: '16', Double2Null: '17', Decimal2: '18', Decimal2Null: '19', Single: '20', SingleNull: '21', Float: '22', FloatNull: '23', Int: '24', IntNull: '25', Int64: '26', Int64Null: '27' }; $('&lt;hr /&gt;').appendTo(curr); printObj(outR, curr); $.ajax({ type: 'POST', url: saveUrl, contentType: "application/json; charset=utf-8", dataType: 'json', data: $.toJSON({ 'inspectionFormID': 'fbde6eda-dde6-4ba9-b82d-3a35349415f0', 'result': outR }), error: function (jqXHR, textStatus, errorThrown) { alert('save failed'); }, success: function (data, textStatus, jqXHR) { printObj(data, curr); } }); }); $('button.e').click(function () { var curr = $(this).next(), outR = { Double: '12.5', DoubleNull: '13.5', Decimal: '14.5', DecimalNull: '15.5', Double2: '16.5', Double2Null: '17.5', Decimal2: '18.5', Decimal2Null: '19.5', Single: '20.5', SingleNull: '21.5', Float: '22.5', FloatNull: '23.5', Int: '24.5', IntNull: '25.5', Int64: '26.5', Int64Null: '27.5' }; $('&lt;hr /&gt;').appendTo(curr); printObj(outR, curr); $.ajax({ type: 'POST', url: saveUrl, contentType: "application/json; charset=utf-8", dataType: 'json', data: $.toJSON({ 'inspectionFormID': 'fbde6eda-dde6-4ba9-b82d-3a35349415f0', 'result': outR }), error: function (jqXHR, textStatus, errorThrown) { alert('save failed'); }, success: function (data, textStatus, jqXHR) { printObj(data, curr); } }); }); }); &lt;/script&gt; </code></pre> <p>Run it click each button once, and look at the before/after. Thanks in advance for any insight, correction or help that you can provide to resolve this issue.</p> <p>you can also download the code samples listed above and see the official bug report for this at this link: <a href="http://aspnet.codeplex.com/workitem/8114" rel="nofollow">http://aspnet.codeplex.com/workitem/8114</a></p> <p><hr /> <strong>EDIT: I am including this image to help everyone get what's going on here</strong> </p> <p><a href="http://i.stack.imgur.com/j1Zno.png" rel="nofollow">click here to see the screenshot of the included example running</a> </p> <p>Basically: { propertyThatIsADecimal: 54 } becomes { propertyThatIsADecimal: 0 } on the server for multiple different number types in varying scenarios which there doesn't seem to be any rhyme or reason to.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload