Asp.net-Mvc

mvc3 中的小數錯誤 - 該值對欄位無效

  • August 6, 2012

我正在關注 [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());

引用自:https://stackoverflow.com/questions/11822480