【问题标题】:How to use Model Validation in a Partial View如何在局部视图中使用模型验证
【发布时间】:2012-08-18 04:17:03
【问题描述】:

我有一个这样的控制器:

public FooController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

使用索引视图:

@{ Html.RenderPartial("~/Views/Bar/Add", new Models.Bar()); }

Bar 控制器是这样的:

public BarController : Controller
{
    public ActionResult Add()
    {
        var bar = new Bar();
        return View(bar);
    }

    [HttpPost]
    public ActionResult Add(Bar bar)
    {
        if(ModelState.IsValid)
        {
            _repository.AddBar(bar);
            return RedirectToAction("Index", "Foo");
        }

        // This will return only the partial view (No Layout, no outer view)
        return View("Add", bar);

        // This will not show validation errors
        // return RedirectToAction("Index", "Foo");
    }
}

添加视图如下所示:

@model Models.Bar

@using(Html.BeginForm("Add", "Bar", FormMethod.Post))
{
    Name: @Html.TextBoxFor(x => x.Name)

    <input type="submit" value="Add Bar" />

    @Html.ValidationSummary()
}

我的问题是,如果我返回 View("Add", bar),我会得到部分视图,而没有其他内容(不是我想要的)。但是,如果我改为返回 RedirectToAction("Index", "Foo") 是否通过验证,我当然会丢失验证摘要的任何验证错误。

有没有办法在这样的局部视图中使用验证?

【问题讨论】:

  • 为什么在返回视图中使用 [HttpGet]
  • 好吧,您通常不会阅读任何内容,认为 grom get 您在这里所做的只是传递一个纯粹的操作,下一篇文章是当您从帖子中读取值时不确定是否需要 get
  • 你不需要需要 Get 属性,无论如何它都是隐式的 Get 方法。这只是一种风格偏好。但是你是什么意思你没有从Get中读到任何东西?你当然知道!发布意味着您正在修改内容...不确定您要说什么...
  • 它不是一个 get 方法,您所做的只是返回一个对象,该 get 通常用于从查询字符串或表单操作中读取某些内容,具体取决于您的表单操作使用 post 或 get 的方式
  • 您是说如果我删除 [HttpGet] 它就不再是 GET 方法了吗?我可以向你保证,它肯定仍然是一个 GET 方法。就像我说的,这纯粹是为了消除它下面的 POST 方法的歧义。但是使用您自己的术语,您确实在阅读 something...您正在阅读从服务器发出的 HTML 怎么样?再一次,我看不到你的意思...... HttpGet 用于限制使用不同的动词调用该方法,这是我在使用后重定向模式时喜欢明确地做的事情。据我所知,这是 MVC 中非常标准的做法

标签: c# asp.net-mvc asp.net-mvc-3 partial-views


【解决方案1】:

你可以:

  1. return View("~/Views/Home/Index.cshtml") 如果验证失败。
  2. 在 TempData 上保存 ModelState 并在 Home.Index 操作中恢复它。
  3. 发出 AJAX 请求。

【讨论】:

  • 对,在两个不同的控制器之间保存数据似乎是我缺少的必要步骤,谢谢。
  • @MaxToro,我下面的回答错了吗?如果是这样,您介意告诉我原因吗,谢谢!
  • @GarrettFogerlie 问题在于模型状态而不是视图模型。
【解决方案2】:

您应该使用@Ajax.Begin 而不是使用@Html.BeginForm,后者将使用ajax 提交您的请求。

@model Models.Bar

<div id="targetId">
</div>

        @using(Ajax.BeginForm("Add", "Bar",new AjaxOptions{  HttpMethod ="POST",UpdateTargetId="targetId"}))
        {


            Name: @Html.TextBoxFor(x => x.Name)

            <input type="submit" value="Add Bar" />

            @Html.ValidationSummary()
        }

它使 ajax 调用“添加”并在您的控制器中。

[HttpPost]
public ActionResult Add(Bar bar)
{
    if(ModelState.IsValid)
    {
        _repository.AddBar(bar);
        return RedirectToAction("Index", "Foo");
    }

    return RenderPartialViewToString("Add",bar);
}



protected string RenderPartialViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = ControllerContext.RouteData.GetRequiredString("action");

        ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            return sw.GetStringBuilder().ToString();
        }
    }

然后添加“RenderPartialViewToString”方法,该方法将返回“HtmlRenderString”,您需要将视图和模型作为参数传递给该方法。 您还必须在 AjxOption 中指定“UpdateTargetId”,您的结果将在其中追加。

【讨论】:

    【解决方案3】:

    @{ Html.RenderPartial("~/Views/Bar/Add", new Models.Bar()); } 替换为@{ Html.RenderPartial("~/Views/Bar/Add"); },按照您的方式,它试图将新的Bar 发布到[Post] Add 或获取视图。

    另外,我通常使用PartialViewResultreturn PartialView 在控制器中的部分视图。但不确定它是否会有所不同。

    更新

    我刚刚提取了一个项目,其中有一个部分表单,我使用@Html.Action() 访问它,一切似乎都可以正常工作并验证。试试@Html.RenderAction。这是一篇描述差异的好帖子。 http://www.arrangeactassert.com/when-to-use-html-renderpartial-and-html-renderaction-in-asp-net-mvc-razor-views/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多