0

我对 ASP.NET MVC 3 应用程序有一个奇怪的需求,它阻碍了我当前的进度。情况如下:

我有一个小的产品搜索引擎,我在多个页面上呈现这个搜索引擎。product此 SE 向控制器的操作发出 HTTP POST 请求search。到这里还好。

假设我在home控制器的index操作(/home/index)上。我进行搜索并检查是否ModelState.IsValid. 结果,它是无效的。所以,我应该用输入的模型返回这个(这样用户就不会丢失值)和模型状态错误。但是当我这样做时,我最终得到了预期的不同 URL(/product/search)。

如果我进行重定向,我会丢失ModelState并且无法显示错误消息。

到目前为止,我有不同的解决方案,它们看起来都很脏。任何的想法?

编辑

这是一个小项目,它证明了这一点:

这是ProductController

public class ProductController : Controller {

    [HttpPost]
    public ActionResult Search(SearchModel searchModel) {

        if (ModelState.IsValid) { 
            //Do some stuff...

            return RedirectToAction("Index", "SearchResult");
        }
        return View(searchModel);
    }
}

这是SearchModel

public class SearchModel {

    [Required]
    public string ProductCategory { get; set; }

    [Required]
    public string ProductName { get; set; }
}

这是 *_SearchPartial*:

@model MvcApplication20.SearchModel

@using (Html.BeginForm("search", "product"))
{
    @Html.EditorForModel()

    <input type="submit" value="Search" />
}

最后这是呈现 *_SearchPartial*的Home控制器操作视图:Index

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>

@Html.Partial("_SearchPartialView")

在这里,当我提交表单并且模型状态失败时,我应该如何进行Product控制器Search操作?

4

2 回答 2

2

在这里,当我提交表单并且模型状态失败时,我应该如何进行产品控制器搜索操作?

通常在这种情况下,您应该渲染_SearchPartialView但不是部分视图,而是带有布局的完整视图,以便用户可以修复他的错误。在这种情况下无需留在 Home/Index:

[HttpPost]
public ActionResult Search(SearchModel searchModel) {

    if (ModelState.IsValid) { 
        //Do some stuff...

        return RedirectToAction("Index", "SearchResult");
    }
    // since we are returning a view instead of a partial view,
    // the _SearchPartialView template should be displayed with the layout
    return View("_SearchPartialView", searchModel);
}

如果您想在出错时留在同一页面上,您可以使用 AJAX 调用来执行搜索。因此,您将 AJAXify 这个搜索表单,然后在成功回调中测试 Search 操作的结果,并根据它决定是否刷新部分以显示错误或使用以下命令重定向到结果操作window.location.href

类似于:

$(document).on('submit', '#searchForm', function() {
    $.ajax({
        url: this.action,
        type: this.method,
        data: $(this).serialize(), 
        success: function(result) {
            if (result.redirectTo) {
                // no validation errors we can redirect now:
                window.location.href = result.redirectTo;
            } else {
                // there were validation errors, refresh the partial to show them
                $('#searchContainer').html(result);

                // if you want to enable client side validation
                // with jquery unobtrusive validate for this search form
                // don't forget to call the .parse method here 
                // since we are updating the DOM dynamically and we
                // need to reattach client side validators to the new elements:
                // $.validator.unobtrusive.parse(result);
            }
        }
    });
    return false;
});

这显然假设您现在已经将部分调用包装在一个 div 中,id="searchContainer"并且您id="searchForm"在生成搜索表单时提供了一个:

<div id="searchContainer">
    @Html.Partial("_SearchPartialView")
</div>

现在是搜索动作:

[HttpPost]
public ActionResult Search(SearchModel searchModel) {

    if (ModelState.IsValid) { 
        //Do some stuff...

        return Json(new { redirectTo = Url.Action("Index", "SearchResult") });
    }
    return PartialView("_SearchPartialView", searchModel);
}
于 2012-02-13T09:44:45.897 回答
1

据我所知,在执行 RedirectToAction 时模型状态会丢失,解决方案是将模型状态保存在 TempData 中,我正在使用的一个示例是:

http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg

这也在各种帖子中进行了讨论,例如MVC 在视图之间传输数据

于 2012-02-13T10:53:00.937 回答