【问题标题】:ASP.NET MVC - Post form to html bookmark?ASP.NET MVC - 将表单发布到 html 书签?
【发布时间】:2013-10-12 05:46:00
【问题描述】:

当使用这样的表单时:

<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>

我需要页面在发布时滚动到#errorsModel.EulaHtml 包含一些长度的 EULA 文本,如果用户在不接受协议的情况下发布页面,我希望用户不必手动向下滚动以查看错误消息。

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

我曾考虑在表单操作中将“#errors”添加到 url 的末尾,但我收到了 a potentially dangerous .... ('%') 的错误。我可能错误地编码了哈希标记。其他人必须处理这个吗?我们正在处理对浏览器兼容性(IE6+ 和其他所有东西)的非常严格的要求,所以我尽量避免使用 JavaScript。

更新

我收到的错误是:

A potentially dangerous Request.Path value was detected from the client (%).

我将Html.BeginForm() 调用修改为

<% using (Html.BeginForm(new { @action="#errors" }))
   { %>

得到的网址是:

http://..../TheControllerName/Eula/%2523errors/

我还注意到,当我以这种方式设置 action 属性时,正在传递的一些 queryString 参数消失了。 (不足为奇,但对我来说没有立即明显的解决方法)

【问题讨论】:

  • 您遇到的确切错误是什么?正确的做法是将#errors 添加到url 的末尾。重定向到末尾带有#errors 的URL 后,您在浏览器的地址栏中看到正确的地址了吗?
  • 更新了错误的问题和生成的 url

标签: asp.net-mvc


【解决方案1】:

试试这样:

<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>

您还可以编写一个自定义的 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);
    }
}

然后:

<% using (Html.MyBeginForm("index", "home", "errors")) { %>
    ...
<% }

【讨论】:

  • 这很有趣:现在,在发布到#errors 之后,我在页面的内容 div 中看到的唯一内容是验证摘要和表单内容。其余页面内容的 HTML 仍然存在,但不会显示。 Grr。啊。
  • 好吧,您解决了书签问题,但我发现每当我链接到书签时,大部分内容都会从页面上消失。我会接受这个并为此提出另一个问题。
【解决方案2】:

更新了 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" />

 }

Html.BeginForm 将在您的表单中生成验证属性,使用 html &lt;form&gt; 标记不会。

此调用使用Html.BeginForm(actionName, controllerName, routeValues, FormMethod, htmlAttributes) 重载,将所有路由置空并将操作分配为html 属性。路由是通过使用 Url.Action() 完成的,我在其中添加了书签。

【讨论】:

    【解决方案3】:

    我想出了一个与此有点不同的解决方案,使用动作过滤器:

    http://spikehd.blogspot.com/2012/01/mvc3-redirect-action-to-html-bookmark.html

    它修改 HTML 缓冲区并输出一小段 javascript 来指示浏览器附加书签。

    希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 2023-04-09
      • 1970-01-01
      • 2013-11-10
      • 2018-09-19
      • 2017-05-08
      • 2012-06-03
      相关资源
      最近更新 更多