ASP.NET MVC - 将表单发布到html书签?

3Da*_*ave 4 asp.net-mvc

使用这样的表单时:

<h2>
<%:Model.EulaTitle %>
</h2>
<p>
<%=Model.EulaHtml %>
</p>
<a name="errors"></a>
<%:Html.ValidationSummary()%>


<div style="text-align:center;">
<% using (Html.BeginForm())
   { %>

<%:Html.HiddenFor(model => model.SourceUrl)%>
<%:Html.HiddenFor(model => model.EulaId)%>


<a name="accept"></a>
<div style="text-align:center;">
<%:Html.CheckBoxFor(model => model.Accepted)%>
<%:Html.LabelFor(model => model.Accepted)%>
</div>
<input type="submit" value="Submit">
<% } %>
</div>
Run Code Online (Sandbox Code Playgroud)

我需要页面滚动到#errors它发布时.将Model.EulaHtml包含一些长度EULA文本和我喜欢的是,用户不必手动向下滚动看到一个错误信息,如果他们发布的页面不接受该协议.

如果控制器ModelState.IsValid在Post上检测到,则会重定向到另一个页面.如果没有,我需要留在此页面,但滚动到#errors书签锚标签.

我想过只是在表单操作的url末尾添加'#errors',但是我收到了错误a potentially dangerous .... ('%').我可能错误地编码了哈希标记.其他人不得不处理这个?我们正在处理对浏览器兼容性(IE6 +以及其他所有其他方面)的限制性要求,因此我尽量避免使用JavaScript.

更新

我收到的错误是:

A potentially dangerous Request.Path value was detected from the client (%).
Run Code Online (Sandbox Code Playgroud)

我修改了Html.BeginForm()调用

<% using (Html.BeginForm(new { @action="#errors" }))
   { %>
Run Code Online (Sandbox Code Playgroud)

结果URL是:

http://..../TheControllerName/Eula/%2523errors/
Run Code Online (Sandbox Code Playgroud)

我还注意到,当我action以这种方式设置属性时,传递的一些queryString参数消失了.(这并不奇怪,但对我来说,没有任何解决办法对我来说很明显)

Dar*_*rov 6

试试这样:

<form action="<%: Url.Action("actionName", "controllerName") %>#errors" method="post">

    <%:Html.HiddenFor(model => model.SourceUrl)%>
    <%:Html.HiddenFor(model => model.EulaId)%>


    <a name="accept"></a>
    <div style="text-align:center;">
    <%:Html.CheckBoxFor(model => model.Accepted)%>
    <%:Html.LabelFor(model => model.Accepted)%>
    </div>
    <input type="submit" value="Submit">

</form>
Run Code Online (Sandbox Code Playgroud)

您还可以编写一个可以执行此任务的自定义HTML帮助程序:

public static class FormExtensions
{
    public static MvcForm MyBeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, string fragment)
    {
        var formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, htmlHelper.ViewContext.HttpContext.Request.Url.Scheme, null, fragment, null, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
        var builder = new TagBuilder("form");
        builder.MergeAttribute("action", formAction);
        builder.MergeAttribute("method", "post", true);
        htmlHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
        return new MvcForm(htmlHelper.ViewContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

<% using (Html.MyBeginForm("index", "home", "errors")) { %>
    ...
<% }
Run Code Online (Sandbox Code Playgroud)


gab*_*aim 6

更新了MVC 4解决问题的方法:

 @using (Html.BeginForm(null, null, null, FormMethod.Post,
     new
        {
            @action = Url.Action("MyAction") + "#bookmark",
            @class = "form-class",
            target = "_blank"
        }))
 {
     ... 
     <input type="submit" value="submit" />

 }
Run Code Online (Sandbox Code Playgroud)

Html.BeginForm将在您的表单中生成验证属性,而使用html <form>标签则不会.

此调用使用Html.BeginForm(actionName, controllerName, routeValues, FormMethod, htmlAttributes)重载,将所有路由归零并将操作指定为html属性.路由是通过使用Url.Action()完​​成的,我附加了我的书签.