mvc3中带小数的错误 - 该值对字段无效

fur*_*ish 28 asp.net-mvc decimal model-binding razor asp.net-mvc-3

我正在关注[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; }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

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);
    }
}
}
Run Code Online (Sandbox Code Playgroud)

视图:

    @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; }
}
Run Code Online (Sandbox Code Playgroud)

Len*_*rri 37

两年后我再次偶然发现了这一点.我认为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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

里面这样Global.asax.cs,使用它Application_Start():

ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
Run Code Online (Sandbox Code Playgroud)

  • 辉煌.如果ppl在十进制输入中放入有效的数字字符,请在JS中保存这么多时间. (3认同)
  • 我发现这个答案非常有帮助,非常感谢,比我之前尝试的其他解决方案更好. (2认同)
  • 超过6年后,这仍然像一种魅力。谢谢。 (2认同)

And*_*iff 6

您是MS未预见到的非英语客户之一.您需要付出额外的努力才能使您的版本运行.我有一个类似的问题,拒绝我将"9,99"和"9.99"作为有效数字.似乎一旦服务器端验证失败,并且一旦客户端验证,导致没有数字被接受.

所以你必须使验证一致.

与评论中的建议一样,请查看 http://msdn.microsoft.com/en-us/library/gg674880(VS.98).aspxhttp://haacked.com/archive/2010/05/10 /globalizing-mvc-validation.aspxMVC 3 jQuery验证/ 全局化数字/十进制字段 或 - 如果您了解德语(或只是查看代码示例) http://www.andreas-reiff.de/2012/06/probleme-MIT-mvcmovies-beispiel-validierung-DES-preises-MIT-dezimalstellen-schlagt-费尔/

顺便说一句,音乐和电影示例教程都存在同样的问题.