ASP.NET MVC - HTML.BeginForm和SSL

JP.*_*JP. 12 c# asp.net-mvc ssl

我遇到的问题是ASP.NET MVC 2中应该是一个简单的登录表单.本质上我的表单看起来像这样:

using (Html.BeginForm("LogOn", "Account", new { area = "Buyers" }, FormMethod.Post, new { ID = "buyersLogOnForm" }))
Run Code Online (Sandbox Code Playgroud)

我在LogOn Action方法上有一个RequiresHTTPS过滤器但是当它执行时我收到以下消息

请求的资源只能通过SSL访问

此时唯一有效的解决方案是传递额外的动作htmlattribute,如下所示:

 var actionURL = "https://"  + Request.Url.Host + Request.Url.PathAndQuery;   
 using (Html.BeginForm("LogOn", "Account", new { area = "Buyers" }, FormMethod.Post, new { ID = "buyersLogOnForm", @action = actionURL }))
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但我想知道a)为什么我首先看到这个问题,b)如果有更直接的方式从http页面发布到https?

[编辑]

我应该说过登录下拉列表可以在很多公共页面上找到.我不希望我的所有页面都是HTTPS.例如,我的希望页面 - 任何人都可以看到 - 不应该基于HTTPS.基本上我需要在我的表单中指定协议,但不知道如何做到这一点,或者是否可能.

我将不胜感激任何意见/建议.提前致谢

J.P

Mat*_*s F 12

你可以用

<form action =" <%= Url.Action(
"action",
"controller",
ViewContext.RouteData.Values,
"https"
) %>" method="post" >
Run Code Online (Sandbox Code Playgroud)

  • 这个问题是没有为您的表单创建FormContext,因此所有Html输入帮助程序都不会添加附加到视图模型的验证属性... (3认同)

Dar*_*rov 6

[RequireHttps]在呈现表单的操作和要发布的表单上使用该属性.

  • 用户可能会被阻止在其浏览器中看不到挂锁的登录页面上输入用户名和密码.在登录页面上使用HTTPS被认为是一种好习惯. (3认同)

Bra*_*d J 5

更新:在考虑使用此代码之前,请查看以下有关此方法的安全漏洞的评论.

我发现JP和Malcolm的代码示例混合起来了.

using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @action = Url.Action("Login","Account",ViewContext.RouteData.Values,"https") }))
Run Code Online (Sandbox Code Playgroud)

尽管如此仍然感觉有点hacky所以我创建了一个自定义的BeginForm帮助器.自定义帮助程序更干净,在本地运行时不需要https.

public static MvcForm BeginFormHttps(this HtmlHelper htmlHelper, string actionName, string controllerName)
    {
        TagBuilder form = new TagBuilder("form");
        UrlHelper Url = new UrlHelper(htmlHelper.ViewContext.RequestContext);

        //convert to https when deployed
        string protocol = htmlHelper.ViewContext.HttpContext.Request.IsLocal == true? "http" : "https";

        string formAction = Url.Action(actionName,controllerName,htmlHelper.ViewContext.RouteData.Values,protocol);
        form.MergeAttribute("action", formAction);

        FormMethod method = FormMethod.Post;
        form.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);

        htmlHelper.ViewContext.Writer.Write(form.ToString(TagRenderMode.StartTag));

        MvcForm mvcForm = new MvcForm(htmlHelper.ViewContext);

        return mvcForm;
    }
Run Code Online (Sandbox Code Playgroud)

用法示例:

@using (Html.BeginFormHttps("Login", "Account"))
Run Code Online (Sandbox Code Playgroud)