2014-04-03 54 views
0

我试图让我的脑袋为什么(数据注释)验证错误触发页面第一次加载之前,任何提交/帖子。但更重要的是如何解决这个问题。MVC绑定触发验证错误

读取SO和interwebs,原因似乎是模型绑定在视图模型属性具有值之前触发视图模型属性的验证错误。我不确定这是否属实,实际情况如何,但这听起来很合理。

而且我读过两种解决方法,这听起来有点哈克:在一个空的观点 1.使用ModelState.Clear在上inital页面加载控制器中的操作方法或 2. Initialiase视图模型属性模型构造函数。 (尚未确认此技术)

这两种技术听起来都像是解决方法。我宁愿了解正在发生的事情并适当地设计我的代码。

有没有人遇到过这个问题?如果是这样,你在做什么?

代码按要求。您可以在下面看到Property1上的Data Annotation验证,该验证在初始请求(即首页加载)时被触发。

控制器的操作方法(重构为简单起见):

public ActionResult Index([Bind(Include = Property1, Property2, Property3, vmclickedSearchButton)] IndexVM vm, string Submit) 
    { 
     bool searchButtonClicked = (Submit == "Search") ? true : false; 
     if (searchButtonClicked) 
     { 
      PopulateUIData(vm); // Fetch data from database and pass them to VM 

      if (ModelState.IsValid) 
      { 
       vm.clickedSearchButton = true; // Used in the vm to avoid logic execution duing initial requests 

       DoWork(vm); 
       } 
      } 

      return View(vm); 
     } 

     // Inital request 
     IndexVM newVM = new IndexVM(); 
     PopulateUIData(newVM); // Fetch data from database and pass to VM 

     return View(newVM); 
    } 

设计注: 理想我想sepate渲染和submiting逻辑到单独的动作的方法。 也就是说在[HttpGet] Index()操作方法内渲染,并在[HttpPost] Index()操作方法内提交。 但由于我在视图中使用ForMethod.Get,因为此方法用于搜索功能,所以我只能使用[HttpGet]索引操作方法。

视图模型(重构为简单起见):

public class IndexVM 
{ 
    // DropDownLists 
    public IEnumerable<SelectListItem> DDLForProperty1 { get; set; } 
    public IEnumerable<SelectListItem> DDLForProperty2 { get; set; } 
    public IEnumerable<SelectListItem> DDLForProperty3 { get; set; } 

    [Required] 
    public int? Property1 { get; set; }  
    public int? Property2 { get; set; } 
    public int? Property3 { get; set; } 
    public bool vmclickedSearchButton { get; set; } 
} 

注: 视图模型是非常简单的。它包含下拉列表,DDL的选定属性以及其中一个属性的验证规则。

添加一个构造函数来视图模型和初始化属性的解决方法:

public IndexVM() 
{ 
    this.Property1 = 0; 
} 
+0

可以显示模型和操作方法吗? – RyanCJI

+0

通过编辑发表:) –

回答

0

的问题是,您要发送一个无效的模型视图。

  1. Property1在模型中被要求是一个可空int。这并不能解释验证执行的原因,但为什么模型无效。

  2. 您的操作方法在初始加载期间正在执行验证。不管http方法(get或post),模型绑定都会执行验证。

既然你需要Property1int?)到为空,顾名思义,当它被实例化模型变得无效。有几种方法来处理这个(不知道这是最合适不过)

  1. 创建在您的控制器HttpGetHttpPost单独的方法。不要为HttpGet实现绑定。

  2. 使用默认值(因为你已经完成)

  3. 修改模型,使Property1不能为空(即int)。

+0

你100%正确!一旦我修复了模型属性(即属性现在不可空,并且还有Requried数据注释),验证规则不再在加载时触发,即与您的选项3一起使用。这看起来比选项更清晰(更简单) 2。 –