C#,Valid ModelState失败.isValid

时间:2012-03-16 00:05:00

标签: c# asp.net-mvc

C#有效ModelState失败.isValid

搜索控制器

//
// GET: /Search/Create
public ActionResult Create()  { return View();  } 

//
// POST: /Search/Create
[HttpPost]
public ActionResult Create(Search search)
{
    search.Created = DateTime.Now;

    search.SearchSet = "test data";
    search.URLParameter = 1432567389;

    if (ModelState.IsValid)
    {
        _db.Searchs.Add(search);
        _db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(search); 
}

搜索类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace TalentProfile.Models
{
    public class Search
    {
        public int Id { get; set; }
        [Required]
        public int URLParameter { get; set; }
        [Required, MaxLength(50, ErrorMessage = "Client must be 50 characters or less")]
        public string Client { get; set; }
        [DataType(DataType.MultilineText), StringLength(150, ErrorMessage = "{0} must be {1} characters or less")]
        public string Notes { get; set; }
        [Required]
        public string SearchSet { get; set; }
        [Required]
        public DateTime Created { get; set; }
    }
}

如果我在调试中运行,则正确设置了类中的所有字段,但它失败了ModelState.IsValid。如果我钻进ModelState.IsValid那就错了。向下钻取我发现错误“需要SearchSet字段”。 SearchSet字段已正确设置为“测试数据”。如果我删除ModelState.IsValid检查,则保存到数据库成功。

如果字段包含有效数据,为什么我会收到“字段必填”错误。

人才控制器

//
// GET: /Talent/Create
public ActionResult Create()
{
    return View();
}

//
// POST: /Talent/Create
[HttpPost]
public ActionResult Create(Talent talent)
{
    talent.Modified = talent.Created = DateTime.Now;

    if (ModelState.IsValid)
    {
        _db.Talents.Add(talent);
        _db.SaveChanges();
        CreatePhoto(talent.Id);
        return RedirectToAction("Index");
    }

    return View(talent);
}

更新:搜索控制器和创建视图

//
// GET: /Search/Create
public ActionResult Create()
{ 
    Search search = new Search();
    search.SearchSet = "test Data";
    return View(search);
}

//
// POST: /Search/Create
[HttpPost]
public ActionResult Create(Search search)
{
    search.Created = DateTime.Now;

    search.URLParameter = 1435267836;

    if (ModelState.IsValid)
    {
        _db.Searchs.Add(search);
        _db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(search);
}

在视图中:@Html.HiddenFor(model => model.SearchSet)

4 个答案:

答案 0 :(得分:2)

这里有几点需要注意:

1)在值类型上放置Required属性是没有意义的。值类型必须始终包含一个值,它们不能为null ..因此必将始终为它们传递。

特别是,DateTime是一种值类型。此外,您的UrlParameter是一个int,它也是一个值类型。它始终至少包含一个默认值。要求是多余的。

2)正如其他人所说,ModelState仅在数据绑定期间设置。数据绑定仅在调用方法之前或调用UpdateModel或TryUpdateModel时发生。无论您是否有其他错误,如果您尚未调用UpdateModel或TryUpdateModel,则无法更新模型并期望ModelState反映更改。

3)客户端根据需要设置,但您似乎没有设置它。因此,如果您设置Client和SearchSet然后执行TryUpdateModel(搜索),它应该是有效的。

4)人才有效,因为与搜索一样,talent.Modifiedtalent.CreatedDateTime并且不可为空,因此即使您不这样做,它们也绝不会失败验证设置一个值(参见自己,删除任务并查看它是如何验证的)。您在Talent上可能拥有的任何其他必填字段也可能是值类型。

答案 1 :(得分:1)

使用TryUpdateModel(搜索);在您的ModelState检查之前。所以它应该是:

[HttpPost]
public ActionResult Create(Search search)
{
    search.Created = DateTime.Now;
    search.SearchSet = "test data";
    search.URLParameter = 1432567389;

    TryUpdateModel(search);

    if (ModelState.IsValid)
    {
        _db.Searchs.Add(search);
        _db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(search); 
}

答案 2 :(得分:1)

在模型绑定期间解析ModelState,因此传递给Search的{​​{1}}对象必须设置Create值。即如果在模型绑定期间值为空,则控制器中的SearchSet设置不会使模型有效。

答案 3 :(得分:-1)

MVC运行时在执行操作之前已经验证了模型,并且在操作中本地设置参数后它没有重新验证它。

所以我的想法是你在其中发布搜索模型的帖子,例如来自html表单,MVC在进入你的行动之前检查有效性,所以你不必:)