Asp.net-Mvc
mvc3 中的小數錯誤 - 該值對欄位無效
我正在關注 [ASP.NET MVC 3 入門][1]。而且我無法使用 Price = 9.99 或 9,99 的值添加/編輯。它說:“價值'9.99’對價格無效。” 和“價格欄位必須是數字。”
如何解決這個問題?
模型:
public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } } public class MovieDbContext : DbContext { public DbSet<Movie> Movies { get; set; } }控制器:
public class MovieController : Controller { private MovieDbContext db = new MovieDbContext(); // // GET: /Movie/ public ViewResult Index() { var movie = from m in db.Movies where m.ReleaseDate > new DateTime(1984, 6, 1) select m; return View(movie.ToList()); } // // GET: /Movie/Details/5 public ViewResult Details(int id) { Movie movie = db.Movies.Find(id); return View(movie); } // // GET: /Movie/Create public ActionResult Create() { return View(); } // // POST: /Movie/Create [HttpPost] public ActionResult Create(Movie movie) { if (ModelState.IsValid) { db.Movies.Add(movie); db.SaveChanges(); return RedirectToAction("Index"); } return View(movie); } // // GET: /Movie/Edit/5 public ActionResult Edit(int id) { Movie movie = db.Movies.Find(id); return View(movie); } // // POST: /Movie/Edit/5 [HttpPost] public ActionResult Edit(Movie movie) { if (ModelState.IsValid) { db.Entry(movie).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(movie); } // // GET: /Movie/Delete/5 public ActionResult Delete(int id) { Movie movie = db.Movies.Find(id); return View(movie); } // // POST: /Movie/Delete/5 [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { Movie movie = db.Movies.Find(id); db.Movies.Remove(movie); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } } }看法:
@model MvcMovies.Models.Movie @{ ViewBag.Title = "Create"; } <h2>Create</h2> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Movie</legend> <div class="editor-label"> @Html.LabelFor(model => model.Title) </div> <div class="editor-field"> @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </div> <div class="editor-label"> @Html.LabelFor(model => model.ReleaseDate) </div> <div class="editor-field"> @Html.EditorFor(model => model.ReleaseDate) @Html.ValidationMessageFor(model => model.ReleaseDate) </div> <div class="editor-label"> @Html.LabelFor(model => model.Genre) </div> <div class="editor-field"> @Html.EditorFor(model => model.Genre) @Html.ValidationMessageFor(model => model.Genre) </div> <div class="editor-label"> @Html.LabelFor(model => model.Price) </div> <div class="editor-field"> @Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div> public DbSet<Movie> Movies { get; set; } }
2年後,我再次偶然發現了這一點。我以為 ASP.NET MVC 5 已經解決了這個問題,但看起來情況並非如此。所以這裡是如何解決這個問題……
創建一個
DecimalModelBinder如下所示的類並將其添加到項目的根目錄中,例如:using System; using System.Globalization; using System.Web.Mvc; namespace YourNamespace { public class DecimalModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { ValueProviderResult valueResult = bindingContext.ValueProvider .GetValue(bindingContext.ModelName); ModelState modelState = new ModelState { Value = valueResult }; object actualValue = null; if(valueResult.AttemptedValue != string.Empty) { try { actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture); } catch(FormatException e) { modelState.Errors.Add(e); } } bindingContext.ModelState.Add(bindingContext.ModelName, modelState); return actualValue; } } }在裡面這樣
Global.asax.cs,使用它Application_Start():ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());