这可能是一个新手问题。
当我创建ASP.NET MVC2应用程序时,会创建一个带有Action LogIn的帐户控制器,如下所示:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
现在,我不想拥有登录页面,我希望将登录控件作为更大页面的一部分。所以,我将Login.aspx更改为Login.ascx,并将其集成到我的主视图中,使用Html.RenderPartial或Html.RenderAction。
如果登录成功,两者都像魅力一样。如果不是,
return View(model)
杀了我。 我想要的是回到我的主页面(称之为Home / Index),但是带有局部视图的错误信息。
return RedirectToAction("Index", "Home")
显然不起作用。
提示?
答案 0 :(得分:3)
这当然不是一个新手问题,我已经在网上上下搜索这个问题的答案,到目前为止,我发现的最佳解决方案隐藏在本教程here中。这就是Darin Dimitrov在Ajax刷新时提出的建议。我将总结该链接的重要部分以及为什么不容易修复:/
基于怪异情人的Ajax刷新
使用ajax刷新的解决方案几乎取决于以下函数(奇怪的爱人使用ControllerContext但它不存在,所以我有ControllerExtension):
ControllerExtension.RenderPartialViewToString(this,"mypartial", (object)model)
这个函数是你的模型+模型状态,并将你的局部视图重新呈现为一个html字符串。然后,您可以获取该字符串并将其在json对象中发送回某些javascript以刷新视图。我使用了jquery,它看起来像这样,
$(document).ready(function () {
var partialViewUpdate = function (e) {
e.preventDefault(); //no postback
var partialDiv = $(this).parent(".partial");
$.post($(this).attr("action"),
$(this).serialize(),
function (json) {
if (json.StatusCode != 0) {
// invalid model, return partial
partialDiv.replaceWith(json.Content);
}
else if (json.Content != null && json.Content != "") {
window.location.replace(data.Content);
};
});
$(".partial").find("form")
.unbind('submit')
.live("submit", partialViewUpdate);
};
Jquery解释:
为什么它不能正常“正常工作”
因此,部分'不仅仅使用模型状态验证的原因是你不能使用POST返回View(模型),因为MVC会将其解析为部分视图的路由地址(login.ascx)部分嵌入的位置(index.aspx)。
你也不能使用RedirectAction()因为它会将它发送到(index.aspx)控制器函数,这相当于清除所有内容并刷新index.aspx页面。但是,如果您使用Chino和Thabaza建议的ActionFilter,那么当您的页面刷新并且login.ascx控制器函数再次启动时,它将获取该tempdata。但是,如果刷新页面会导致客户端代码(例如弹出模式)的麻烦(例如,如果刷新弹出窗口消失了),则无效。
这么说吧
我更喜欢它“只是工作”所以如果有人知道正确/更好的方式做这个pleaaaase分享它!我仍然认为Ajax刷新和ActionFilter解决方案并不是一种干净的方式,因为它几乎使它看起来像部分视图,如果没有某种“技巧”就无法使用表单。
答案 1 :(得分:1)
是的redirecttoaction但是在tempdata中提供了一条错误消息,所以你应该做这样的事情
TempData["errorMsg"] = "incorrect values provided";
return RedirectToAction("Index", "Home")
当然,在主索引中你应该有一个显示消息的div
<%= html.Encode(TempData["errorMsg"]) %>
EDIT 我看到你想维护可能存在问题的模型状态,但你可以做的是在索引操作中传递模型状态或在tempdata中传递modelstate对象。那么你可以做的是检查对象中是否存在模型状态错误,以及是否有检查字段并将错误添加到右侧字段。
答案 2 :(得分:0)
您可以明确指定要返回的视图:
return View("~/Views/Home/Index.aspx", model);
这样可以保留错误信息并呈现正确的视图。
答案 3 :(得分:0)
看看blog上的练习#13。当您使用PRG(Post-Redirect-Get)样式进行编码时,此方法可以很好地传递模型状态信息。您只需创建几个操作过滤器,并将其应用于您的get和post操作。
答案 4 :(得分:0)
使用Ajax.BeginForm时遇到了同样的问题,我需要返回部分视图,但所有的模型状态错误都消失了。 诀窍是将Ajax.BeginForm部分隔离到单独的View,并将RenderPartial包含在另一个包含视图的UpdateTargetId div中。
这样,您可以在拥有模型错误时返回视图模型,或者只显示您选择的一些成功消息(如果有)。 这是一个很好的详细解释: http://xhalent.wordpress.com/2011/02/05/using-unobtrusive-ajax-forms-in-asp-net-mvc3/