简短版本:需要ViewUserControl(即登录表单)发布到自己并能够重定向(即成功登录),或返回原始视图(即主页/索引)与验证摘要,而不是干扰页面上的其他ViewUserControls。
此外,HomeController / Index应该对Login Form的内部工作知之甚少。理想情况下,只需要Html.RenderAction(“登录”,“用户”)或类似内容。
此刻,坚持重定向“不允许子操作执行重定向操作。”我知道为什么,但想知道是否有办法,或者我应该采取其他方式。
我想要实现的细节:
- 封装要在网站上重复使用的登录(或任何)表单
- 发布自我
- 当登录/验证失败时,显示包含验证摘要的原始页面
- (有些人可能会争辩只是发布到登录页面并在那里显示验证摘要;如果我想要实现的目标是不可能的,我将走这条路线)
- 登录成功后,重定向到/ App / Home / Index
- 另外,想要:
- 坚持PRG原则
- 避免使用ajax
- 保持登录表单(UserController.Login())尽可能封装;避免必须实现HomeController.Login(),因为登录表单可能出现在其他地方
除了重定向之外的所有工作。到目前为止,我的方法是:
Home/Index
包含登录表单:<%Html.RenderAction("Login","User");%>
User/Login ViewUserControl<UserLoginViewModel>
包括:
using(Html.BeginForm()){}
- 包含隐藏的表单字段
"userlogin"="1"
public class UserController : BaseController {
...
[AcceptPostWhenFieldExists(FieldName = "userlogin")]
public ActionResult Login(UserLoginViewModel model, FormCollection form){
if (ModelState.IsValid) {
if(checkUserCredentials()) {
setUserCredentials()
return this.RedirectToAction<Areas.App.Controllers.HomeController>(x => x.Index());
}
else {
return View();
}
}
...
}
在:ModelState或用户凭据失败时运行良好 - 返回View()确实屈服于Home / Index并显示相应的验证摘要。
(我在同一页面上有一个注册表格,使用相同的结构。每个表格的验证摘要仅显示提交该表格的时间。)
时失败:ModelState和用户凭据有效 - RedirectToAction&lt;&gt;()出现以下错误:
“不允许子操作执行重定向操作。”
似乎在经典ASP时代,这将通过Response.Buffer=True
解决。现在是否有相应的设置或解决方法?
顺便说一下,运行: ASP.Net 4,MVC 2,VS 2010,开发/调试Web服务器
我希望所有这一切都有道理。
那么,我的选择是什么?或者我的方法在哪里出错了? TIA!
答案 0 :(得分:0)
我会使用可以放在MasterPage / _Layout上的部分视图(例如“_Login.cshtml”或“_Login.ascx”)。在局部视图中,您可以编写一个表单标记,该标记发布到Controller上的Action(假设“AuthController”和操作“LogIn”)。要记住你来自哪里
这就是行动的样子:
public ActionResult LogIn(string username, string password)
// name the id's of the form elements as the parameters
{
if(YouAuthMethodHere(username, password))
{
return View("Welcome");
}
else
{
return Redirect(HttpContext.Current.Request.Referer.AbsolutUri);
}
}
成功验证用户后,将返回名为“Welcome.cshtml”/“Welcome.aspx”的视图,否则将从提交表单的位置重定向。
注意:referer可能为null(例如,如果不是像fiddler这样的浏览器或脚本正在发出请求),那么就会有一些错误处理。
答案 1 :(得分:0)
古老的问题,但这基本上和我现在做的完全一样,我的搜索仍然没有发现符合所有标准的答案;我不明白为什么将登录过程完全封装起来是如此困难,但也许我只是错过了一个写得清楚的例子。
我的解决方案完美无缺,就是简单地使用旧标准
System.Web.HttpContext.Current.Response.Redirect(url, true);
...在登录过程的控制器中。
发布它因为它有效,它保持封装,并且它比我所看到的包含return-a-view-a-Javascript-redirect解决方案稍微不那么可怕,但我&#39; d还想更好地了解如何以更加MVC的方式实现这种包装。