【问题标题】:Unable to get values from form in controller method无法从控制器方法中的表单获取值
【发布时间】:2014-03-11 19:01:34
【问题描述】:

我有一个 MVC 4 网站 (.NET 4.5),如果他们试图访问网站的高分辨率照片 (Hrp) 部分,我想将用户重定向到一个非常简单的登录页面。我已经设置了路由,它们似乎工作正常,即用户被路由到“索引”页面或“登录”页面。但是,当我在 HrpController 的“登录”方法中收到数据时,用户名和密码字段为空,即使我在表单上填写了它们。

应用程序的逻辑流程应该如下:

  1. 用户转到索引页面 (/Hrp),如果用户未登录,他们将获得登录表单
  2. 用户填写登录表单并提交给HrpController.Login (/Hrp/Login)
  3. HrpController.Login 方法应该获取用户名和密码,并根据硬编码值进行验证(我知道这是非常弱的安全性,但它是对现有代码的重写,我无权更改机制)
  4. 如果用户名和密码与表单中输入的内容匹配,用户将获得 Hrp 索引页面 (/Hrp)
  5. 如果用户名或密码不匹配,则将用户返回登录页面 (/Hrp/Login)

我不确定为什么用户名和密码值为空,而不是包含用户在表单上填写的值。非常感谢任何帮助。

路线:

        routes.MapRoute(
          name: "Hrp",
          url: "Hrp/",
          defaults: new { controller = "Hrp", action = "Index" }
        );

        routes.MapRoute(
            name: "HrpLogin",
            url: "Hrp/Login/",
            defaults: new { controller = "Hrp", action = "Login" }
        );

        routes.MapRoute(
            name: "HrpDetails",
            url: "Hrp/Details/{id}/",
            defaults: new { controller = "Hrp", action = "Details",
                            id = UrlParameter.Optional }
        );

形式:

@using MyApp.App_Code;

@model MyApp.App_Code.Models.HrpUser


@using (Html.BeginForm("Login", "Hrp", FormMethod.Post)) 
{
    @Html.ValidationSummary(true, "Login failed. Check your login details.");
    <div>
         <div id="content" class="content">
            <section id="article">
                <div class="cont orangeTopBorder">
                    <fieldset>
                        <legend>Login</legend>
                        <div class="editor-label">
                            @Html.LabelFor(u => u.username)
                        </div>
                        <div class="editor-field">
                            @Html.TextBoxFor(u => u.username)
                            @Html.ValidationMessageFor(u => u.username)
                        </div>
                        <div class="editor-label">
                            @Html.LabelFor(u => u.password)
                        </div>
                        <div class="editor-field">
                            @Html.PasswordFor(u => u.password)
                            @Html.ValidationMessageFor(u => u.password)
                        </div>
                        <input type="submit" value="Submit"/>
                    </fieldset>
                    <div class="footerarticle">
                    </div>
                </div>
            </section>
        </div>
    </div>
}

控制器:

    public ActionResult Login(string username, string password)
    {
        if (username == "yourname" && password == "yourpassword")
        {
            SetHrpLogonAccepted();

            // Load Hrp object here, then show the main Hrp page

            return RedirectToAction("Index", hrp);
        }
        else
        {
            return View("Login");
        }
    }

    public ActionResult Index()
    {
        if (IsHrpLogonAccepted() == false)
        {
            return View("Login");
        }
        else
        {
               // Load Hrp object here, then show the main Hrp page

                return View("Index", hrp);
        }
   }

Hrp用户:

    public class HrpUser
    {
        [Required]
        [Display(Name = "User name")]
        public string username { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string password { get; set; }
    }

辅助方法:

    private bool IsHrpLogonAccepted()
    {
        return Session["HrpLogonAccepted"] != null;
    }

    private void SetHrpLogonAccepted()
    {
        Session["HrpLogonAccepted"] = true;
    }

【问题讨论】:

    标签: c# asp.net-mvc-4 asp.net-mvc-routing form-submit


    【解决方案1】:

    尝试将您的登录 ActionResult 更改为:

    public ActionResult Login(HrpUser loginModel)
    {
        if (loginModel.username == "yourname" && loginModel.password == "yourpassword")
        {
            SetHrpLogonAccepted();
    
            // Load Hrp object here, then show the main Hrp page
    
            return RedirectToAction("Index", hrp);
        }
        else
        {
            return View("Login");
        }
    }
    

    【讨论】:

    • 我加入了你的代码,但是 loginModel.username 和 loginModel.password 是空的,就像以前一样。
    • 不确定这是否有帮助,但这里是提琴手跟踪(标记)。 POST [ my web site ].localhost/Hrp/Login HTTP/1.1 Host: www.[ my web site ].localhost User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox /27.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding : gzip, deflate Referrer: [ my web site ].localhost/Hrp/ Cookie: [cookie was here] Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 29 username= afdg&password=asdfds
    【解决方案2】:

    表单作为 POST 提交到 Hrp/Login,并且浏览器正在执行 301 重定向到 Hrp/Login/。在此重定向期间,它将数据作为 GET 而不是 POST 发送,因此它能够路由到我的 HrpController.Login 方法,因为它没有使用 [HttpPost] 属性进行修饰,默认情况下它是 GET。

    为了解决这个问题,我现在使用 [HttpPost] 属性进行装饰。

      [HttpPost]
      public ActionResult Login(HrpUser loginModel)
    

    我还在“登录/”中添加一个斜杠:

    @using (Html.BeginForm("Login/", "Hrp", FormMethod.Post))
    

    由于我不得不做这个黑客,我想我会看到做一个重定向,这样我的表单位于 /Hrp/Login 并且可能我可以通过使用来摆脱黑客:

    @using (Html.BeginForm())
    

    【讨论】:

    • 进一步说明:我能够使用 return RedirectToAction("Login");调用现在呈现视图的我的登录方法的 GET 版本。 [HttpGet] public ActionResult Login() { return View("Login"); }。这让我可以在表单上使用@using (Html.BeginForm())。
    猜你喜欢
    • 2013-03-05
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多