开发者

ASP.NET MVC - Post form to html bookmark?

When using a form like this:

<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.E开发者_StackOverflowulaId)%>


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

I need the page to scroll to #errors when it posts. The Model.EulaHtml contains some length EULA text and I'd prefer that the user not have to manually scroll down to see an error message if they post the page without accepting the agreement.

If the controller detects ModelState.IsValid on Post, it redirects to another page. If not, I need to stay on this page, but scroll to the #errors bookmark anchor tag.

I've thought about just adding '#errors' to the end of the url in the form action, but I receive errors along the line of a potentially dangerous .... ('%'). It's possible that I'm incorrectly encoding the hash mark. Anyone else had to deal with this? We're dealing with pretty restrictive requirements for browser compatibility (IE6+ and everything else under the sun) so I try to avoid using JavaScript whenever possible.

Update

The error I'm receiving is:

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

I modifed the Html.BeginForm() call to

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

And the resulting URL is:

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

I also noticed that a few queryString parameters that were being passed through disappear when I set the action attribute in this way. (Not surprising, but no fix for that is immediately obvious to me)


Try like this:

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

You could also write a custom HTML helper that will do the job:

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);
    }
}

And then:

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


Updated MVC 4 solution to the problem:

 @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 will generate the validation attributes in your form, using the html <form> tag will not.

This call is using the Html.BeginForm(actionName, controllerName, routeValues, FormMethod, htmlAttributes) overload, nulling all the routing and assigning the action as an html attribute instead. The routing is accomplished by using Url.Action(), to which I append my bookmark.


I came up with a solution a bit different to this, using an action filter:

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

It modifies the HTML buffer and outputs a small piece of javascript to instruct the browser to append the bookmark.

Hope it helps :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜