Problem getting the MVC3 model binder to bind to a decimal instead of an int
I have a AJAX call from my webpage sending the following data to my MVC3 action method.
{
"name":"Test",
"newitems":[
{"id":15,"amount":100,"unit":"gram"},
{"id":1,"amount":75,"unit":"gram"},
{"id":46,"amou开发者_StackOverflow社区nt":25,"unit":"gram"}
]
}
In my controller I have the following classes:
public class NewDataItem
{
public string name { get; set; }
public List<NewDataItemDetails> newitems { get; set; }
}
public class NewDataItemDetails
{
public int id { get; set; }
public int amount { get; set; }
public string unit { get; set; }
}
And the Action method that received the request have a NewDataItem
as a parameter. This works perfect, however the amount property of NewDataItemDetails might not always contain an int. It might for example be 50.45. So because of that I changed the line public int amount { get; set; }
to public decimal amount { get; set; }
.
After this change amount is always shown as 0, and not the proper value that it did when it was an int.
Why does MVC fail to bind the value to the property when it is a decimal, when it worked just fine as an int?
See the answer here Default ASP.NET MVC 3 model binder doesn't bind decimal properties from ryudice about creating a DecimalModelBinder. It works and it also keeps all the model validation working, (some other solutions use deserialization which can stop validation from working.
I found the problem.
If I change the line "amount":100,
to "amount":"100",
it works fine. It seems that the MVC ModelBinder can manage the string to decimal conversion, but not the int to decimal.
Your type (class) NewDataItemDetails property amount is of type int.
You are making things difficult to manage. If you are expecting to have amount as a decimal eventually, it simplifies to actually use amount's type as decimal.
This will avoid having you to extend the default model binder and cater for your behaviour.
I think, it is wiser and it simplies to send the amount as decimal in the ajax call. it provides consistency.
I know I am a bit late with this but there is another solution which works without changing anything until MVC fixes it (I believe it is at their end).
In my javascript I add 0.00001 to my value if it is supposed to be a decimal but is a round number. For those I know should be currency values I know this has no effect and will round down. For those that I do not know their value and this could affect it I remove the 0.00001 from the value after binding in mvc. The binding works correctly as this is no longer an int in the eyes of mvc
If you don't want to change model binder then you can create json object and convert amount to string.It will work fine for me.
var test={"amount":""};
var test1={"amount":100}
test.amount=test1.amount.toString();
精彩评论