Passing decimals to Action methods in MVC

Bsrkvarma
Posted by in ASP.NET MVC category on for Intermediate level | Points: 250 | Views : 8391 red flag

When we come across certain use cases, where we want to post the currency values like salary “1,234.56”, MVC framework will fail to bind them to the corresponding model properties. In such cases, we can implement the IModelBinder interface to bind those values.

Background

It’s more common practice to use Ajax to submit form data to the back end.

When we pass the data which are of type string/ int/ decimal(with points like “1234.56”) to the back end, the MVC framework will map them to the corresponding model properties.

When we come across use case, where we want to post the currency values like salary “1,234.56” MVC framework will fail to bind them to the corresponding model object.


If we debug this, we find those values are null (nullable decimal in the screenshot below)


In such cases, we can implement the IModelBinder interface and register the binder.

 

Describe the topic with code snippets

We can implement the BindModel method in IModelBinder interface and implement the logic to parse the input value and bind it to the context. I have provided the sample implementation of the interface but make sure we handle all the scenarios and exceptions.

public class DecimalBinder : IModelBinder
	{
		public object BindModel(ControllerContext controllerCntxt, ModelBindingContext bindingCntxt)
		{
			//Get the value from the context
			ValueProviderResult input = bindingCntxt.ValueProvider.GetValue(bindingCntxt.ModelName);

			ModelState modelState = new ModelState { Value = input };
			
			//Specify the numberstyle to parse the deciaml to convert $123.45 to 123.45
			object res = decimal.Parse(input.AttemptedValue,
				NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, new CultureInfo("en-US"));

			bindingCntxt.ModelState.Add(bindingCntxt.ModelName, modelState);
			return res;
		}
	}

After implementing the interface, register the custom decimal  binder to the MVC ModelBinders.
ModelBinders.Binders.Add(typeof(decimal), new DecimalBinder());
//Handle the null decimal type seperately 
ModelBinders.Binders.Add(typeof(decimal?), new DecimalBinder()); 

If we verify after registering the model binder, we can see that values are populating.


Note

If we bind decimal, it will not work for nullable decimal. We need to bind it separately as shown in above code snippet.


Conclusion
We can implement interface 
IModelBinder to handle the input of decimals with different scenarios. This will only handle id we register it specifically and the other bindings will be taken care by MVC framework.

Reference

MSDN Model binder
Page copy protected against web site content infringement by Copyscape

About the Author

Bsrkvarma
Full Name: varma bsrk
Member Level: Starter
Member Status: Member
Member Since: 8/25/2014 9:07:08 AM
Country: India
Varma
http://www.dotnetfunda.com
I have 4.5 + years of experience in .Net application development.

Login to vote for this post.

Comments or Responses

Posted by: Mcgregor1234 on: 4/4/2019 | Points: 25
nice

Login to post response

Comment using Facebook(Author doesn't get notification)