2

简短版本:需要 ViewUserControl(即登录表单)发布到自己并能够重定向(即,成功登录时),或返回带有验证摘要的原始视图(即主页/索引),并且不干扰其他 ViewUserControls页。

此外,HomeController/Index 应该对登录表单的内部工作有最少的了解。理想情况下,只需要 Html.RenderAction("Login","User") 或类似的东西。

目前,停留在重定向给出“不允许子动作执行重定向动作”。我知道为什么,但想知道是否有办法,或者我应该这样做的另一种方式。

我要达到的目标的详细信息:

  • 封装要跨站点重用的登录(或任何)表单
  • 发给自己
  • 当登录/验证失败时,显示带有验证摘要的原始页面
    • (有些人可能会争辩说只是发布到登录页面并在那里显示验证摘要;如果我想要实现的目标是不可能的,我会走那条路)
  • 当登录成功时,重定向到 /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 或 User Credentials 失败 - return View() 确实屈服于 Home/Index 并显示适当的验证摘要。

(我在同一页面上有一个注册表格,使用相同的结构。每个表格的验证摘要仅在提交该表格时显示。)

在以下情况下失败:ModelState 和用户凭据有效 - RedirectToAction<>() 给出以下错误:
“不允许子操作执行重定向操作。”

似乎在经典的 ASP 时代,这可以通过Response.Buffer=True. 现在有等效的设置或解决方法吗?

顺便说一句,正在运行:ASP.Net 4、MVC 2、VS 2010、开发/调试 Web 服务器

我希望所有这些都是有道理的。

那么,我有哪些选择?或者我的方法哪里出错了?蒂亚!

4

2 回答 2

0

我会使用可以放置在 MasterPage/_Layout 上的部分视图(例如“_Login.cshtml”或“_Login.ascx”)。在部分视图中,您编写一个表单标签,该标签发布到控制器上的操作(比如说“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 可能为空(例如,如果不是像 fiddler 之类的浏览器或脚本发出请求),因此还有一些错误处理。

于 2011-04-08T15:56:15.767 回答
0

古老的问题,但这与我现在所做的基本上完全相同,而且我的搜索仍然没有发现符合所有标准的答案;我不明白为什么像这样完全封装登录过程如此困难,但也许我只是错过了一个清晰编写的示例。

我的完美解决方案是简单地使用旧标准

System.Web.HttpContext.Current.Response.Redirect(url, true);

...在登录过程的控制器中。

发布它是因为它有效,它保持封装,并且它比我见过的 return-a-view- contains-a-Javascript-redirect 解决方案稍微可怕,但我仍然想更好地了解如何实现这一点以一种更 MVC 的方式进行包装。

于 2014-06-16T13:53:08.917 回答