Reputation: 33071
I have a model (Northwind) in my MVC application that has a property called UnitPrice:
public class Product {
public decimal UnitPrice { get; set; }
}
In my view, I want to display this as currency {0:C}. I tried using the DataAnnotations DisplayFormatAttribute: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayformatattribute.aspx
It worked fine for display purposes, but when I try and POST it is preventing me from submitting because it is not in the correct format. If I remove the $ then it will allow me.
Is there any way I can have it ignore format when trying to validate?
Upvotes: 3
Views: 3492
Reputation: 1039468
You could write a custom model binder for the Product
type and manually parse the value. Here's how you could proceed:
Model:
public class Product
{
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:C}")]
public decimal UnitPrice { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new Product { UnitPrice = 10.56m });
}
[HttpPost]
public ActionResult Index(Product product)
{
if (!ModelState.IsValid)
{
return View(product);
}
// TODO: the model is valid => do something with it
return Content("Thank you for purchasing", "text/plain");
}
}
View:
@model AppName.Models.Product
@using (Html.BeginForm())
{
@Html.LabelFor(x => x.UnitPrice)
@Html.EditorFor(x => x.UnitPrice)
@Html.ValidationMessageFor(x => x.UnitPrice)
<input type="submit" value="OK!" />
}
Model Binder (here's where the magic will happen):
public class ProductModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var price = bindingContext.ValueProvider.GetValue("unitprice");
if (price != null)
{
decimal p;
if (decimal.TryParse(price.AttemptedValue, NumberStyles.Currency, null, out p))
{
return new Product
{
UnitPrice = p
};
}
else
{
// The user didn't type a correct price => insult him
bindingContext.ModelState.AddModelError("UnitPrice", "Invalid price");
}
}
return base.BindModel(controllerContext, bindingContext);
}
}
Registration of the model binder in Application_Start
:
ModelBinders.Binders.Add(typeof(Product), new ProductModelBinder());
Upvotes: 4
Reputation: 2077
If you want the formatting only applicable on display, then set ApplyFormatInEditMode to false.
Upvotes: 0