Asp.net mvc 2 页面加载时将显示验证消息

Asp.net mvc 2 页面加载时将显示验证消息,asp.net-mvc-2,validation,Asp.net Mvc 2,Validation,我在ASP.NET MVC 2.0中遇到验证问题。我在控制器中使用相同的操作来执行用户请求。 例如: public ActionResult Index(ReportModel model) { if (!model.IsInitialDisplay && ModelState.IsValid) { model.Result = service.GetResult(model); } return V

我在ASP.NET MVC 2.0中遇到验证问题。我在控制器中使用相同的操作来执行用户请求。
例如:

public ActionResult Index(ReportModel model)
{
    if (!model.IsInitialDisplay && ModelState.IsValid)
    {
        model.Result = service.GetResult(model);                
    }
    return View(model);
}  
在ReportModel中,我定义了一个标志IsInitialDisplay以确定页面是否初始显示:

public class ReportModel
{
    [Required(ErrorMessage = "*")]
    public string Criteria { get; set; }
    public bool IsInitialDisplay { get; set; }
    public ReportResult Result { get; set; }

    public ReportModel()
    {
        IsInitialDisplay = true;
    }
}  
在视图中,我使用以下代码:

<% using (Html.BeginForm())
   { %>
<table>
    <tr>
        <th>
            Criteria:
        </th>
        <td>
            <%= Html.TextBox("Criteria", "") %>
            <%= Html.ValidationMessage("Criteria") %>
        </td>
    </tr>
</table>
<br />
<input type="submit" value="Submit" />
<%= Html.Hidden("IsInitialDisplay", false) %>
<% } %>  
模型

看法


型号(标准)%>
型号(标准)%>

工作正常

在初始页面加载时显示错误消息的原因是控制器操作将
ReportModel
model作为参数。当您第一次使用
/Home/Index
访问此操作时,您没有传递任何参数,当默认模型绑定器尝试绑定到
ReportModel
实例时,它会触发验证错误

在呈现和处理表单提交时使用相同的操作是一种不好的做法,但如果您确实想这样做,可以尝试如下操作:

public ActionResult Index(bool? isInitialDisplay)
{
    if (isInitialDisplay.HasValue && !isInitialDisplay.Value)
    {
        var model = new ReportModel();
        UpdateModel(model);
        if (ModelState.IsValid)
        {
            model.Result = service.GetResult(model);                
        }
        return View(model);
    }

    // Initial request
    return View(new ReportModel());
}
在这种情况下,您不再需要模型上的
IsInitialDisplay
属性,也不需要将其设置为true的构造函数

尽管如此,以下是推荐的方法:

public ActionResult Index()
{
    var model = new ReportModel();
    return View(model);
}

[HttpPost]
public ActionResult Index(ReportModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
    model.Result = service.GetResult(model);                
    return View(model);
}

下面是一个结合了一些好答案的简单解决方案:

[HttpGet]
public ActionResult Index(ReportsModel model)
{
    ModelState.Clear(); //clears the validation

    return View(model);
}

[HttpPost]
public ActionResult Index(ReportsModel model, string unused)
{
    ...
}
这使用http方法来确定它是否是第一次加载(如Darin的解决方案)


最重要的是,它让MVC构建您的控制器,而不是自己手动更新控制器。如果使用依赖项注入,或者通过查询字符串(如嵌套的资源id)输入其他上下文数据,这一点很重要。

如果需要使用相同的操作名称处理表单提交,则应始终使用此技术:

[HttpGet]
public ActionResult Index()
{
    /* Just returning the view. No validation will happen because we are not passing a parameter*/
    return View();
}

[HttpPost]
public ActionResult Index(ReportsModel model)
{
    //Another post action for validation
}

谢谢你的建议,但在我的项目中,我需要为ReportModel.Criteria收集一些公共数据。因此,我不想在这两个操作(有模型和没有模型)中重复这些业务逻辑。这对我来说很奇怪,因为我得到了这个错误,原因是您描述的,但该操作正在接受一个模型,因为它是一系列表单的一部分,被发布到,然后实际页面发布到下一个表单。。。因此,我不知道为什么这是一种不好的做法为什么“在呈现和处理表单时使用相同的操作”是一种不好的做法?怎么了?@SandRock看到了这个答案贴到的问题,这是一个复杂的例子,当你试图用一个控制器操作多任务时会出现。我想知道为什么这个答案没有标记为答案。这对我很有帮助。谢谢:)在我的项目中,我将复杂模型对象用于ReportModel.Criteria。因此,你的建议并不合适。虽然这段代码可能会解决这个问题,但如何以及为什么解决这个问题将真正有助于提高你的帖子质量,并可能导致更多的投票。请记住,你是在将来回答读者的问题,而不仅仅是现在提问的人。请在回答中添加解释,并说明适用的限制和假设。
public ActionResult Index()
{
    var model = new ReportModel();
    return View(model);
}

[HttpPost]
public ActionResult Index(ReportModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }
    model.Result = service.GetResult(model);                
    return View(model);
}
[HttpGet]
public ActionResult Index(ReportsModel model)
{
    ModelState.Clear(); //clears the validation

    return View(model);
}

[HttpPost]
public ActionResult Index(ReportsModel model, string unused)
{
    ...
}
[HttpGet]
public ActionResult Index()
{
    /* Just returning the view. No validation will happen because we are not passing a parameter*/
    return View();
}

[HttpPost]
public ActionResult Index(ReportsModel model)
{
    //Another post action for validation
}