【问题标题】:How does the controller receive parameters on HttpPost methods?控制器如何接收 HttpPost 方法的参数?
【发布时间】:2011-10-31 00:37:47
【问题描述】:

将这个 sn-p 从控制器中取出,例如:

public ActionResult Login()
{
    if (User.Identity.IsAuthenticated)
    {
        return RedirectToAction("Index", "Home");
    }
    else
    {
        return View();
    }
}

//
// POST: /User/Login

[HttpPost]
public ActionResult Login(LoginModel lm, string returnUrl)
{
    if (ModelState.IsValid)
    {
        if (Membership.ValidateUser(lm.UserName, lm.Password))
        {
            FormsAuthentication.SetAuthCookie(lm.UserName, lm.RememberMe);
            if (Url.IsLocalUrl(returnUrl) &&
                returnUrl.Length > 0 &&
                returnUrl.StartsWith("/") &&
                !returnUrl.StartsWith("//") &&
                !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "Username and Password combination is incorrect");
        }
    }

    return View();
}

我的问题是,对于Login()(用于HTTP POST)的重载方法,第一个参数为LoginModel 类,第二个参数为string 的方法是什么?我的 Login.cshtml 视图使用了提交按钮,所以我很好奇这些参数是如何传递给 Login() 方法的?是什么阻止我添加第三个参数?以及该参数如何传递??

我知道这是一个基本问题,我只是想了解视图和控制器之间的连接部分。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    这个过程称为模型绑定,上面有很多资源...我将从如何实现自定义的开始,因为从那里您将了解该过程的工作方式和原因。

    http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/ http://bradwilson.typepad.com/blog/2010/10/service-location-pt9-model-binders.html

    编辑:

    存在一个默认模型绑定器,它获取 post 集合中的项目,如表单数据和 url 参数,并尝试将它们与您告诉控制器期望的项目匹配。它的工作原理是这样的......

    请求进来, MVC 决定哪个控制器应该获取请求 MVC 然后查看 HTTP 方法,它是 GET 还是 POST? 如果它是一个帖子,那么它会查找具有 HttpPost 属性的控制器操作 然后 MVC 会查看你定义的参数...

    在您的情况下,它说我有一个 LoginModel 和一个 returnUrl; MVC 现在很高兴 - 它知道事情的进展,所以现在它会查看您发送的内容...... 它查看您的帖子数据(表单字段和查询字符串参数) 它会一一查看它们的名称,然后尝试在您的控制器参数中找到匹配项。

    它在表单数据中找到一个用户名字段,它会查看您的参数并询问是否有用户名?不,也许用户名是 LoginModel 的一个属性......然后它会通过 LoginModel 查找。啊哈它说,找到一个。然后 MVC 创建一个 LoginModel 实例并将 Username 属性设置为您发布的值。

    对于它在您的表单和查询字符串中找到的每一项内容,此过程都会继续进行。它遵循一堆规则,但你明白了——这种匹配是 MVC 的“约定优于配置”之美的一部分。

    它上面的整个过程模型绑定,并且由于 MVC 实现了这个默认行为,你看不到它写在 Global.asax 或任何东西中,它只是 MVC 的一部分。

    【讨论】:

    • 我不确定我是否完全掌握了这一点。我阅读了这两篇文章,查看我的应用程序,我没有实现IModelBinder 的类,并且我的Application_Start() 方法中没有调用ModelBinders.Binders.Add() 的代码。我错过了什么吗?仍然没有看到这一点以及视图如何故意传递两个参数。
    • +1 很好的解释,绝对看你在说什么。我想我更习惯于“配置优于约定”,所以我试图向自己证明为什么会发生一切。啊,默认行为的美妙之处!现在我明白了。谢谢,@keithwarren7。
    • 另一个问题,基思。我的标记中有一个<input /> 控件。当点击它时,它会发布,但returnUrl 来自哪里?这只是提交按钮上的可捕获参数吗?
    • returnUrl 实际上是由安全过滤器添加的。您请求访问当前用户无权请求的资源。安全过滤器识别了这一点,它旨在将您发送到登录页面,以便您可以登录。它添加了 returnUrl 参数(其中包含您最初请求的页面的 url),以便在您登录后,它可以发送给您返回您第一次请求的位置。
    【解决方案2】:

    看看你的 LogOn 视图,这是 post 方法获取 returnUrl 参数的地方

    Html.BeginForm("LogOn", "Account", new { returnUrl = @Request.QueryString["ReturnUrl"] }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-19
      • 1970-01-01
      • 1970-01-01
      • 2020-10-12
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      相关资源
      最近更新 更多