MVC后退按钮有问题

时间:2014-11-14 14:10:46

标签: c# asp.net-mvc html5 razor kendo-grid

我想要一个“后退”按钮,将用户返回到带有网格/表格的页面,但我遇到了一些麻烦。后退按钮的目的是允许我的用户的网格设置在查看记录之间保持不变。 “后退”按钮指向的链接取决于用户来自哪个URL。 url在控制器方法中设置。当Url看起来如下......

http://localhost:49933/OpenOrder

...让后退按钮工作的问题很少。但是,当URL看起来像这样......

http://localhost:49933/OpenOrder?grid-sort=&grid-page=1&grid-pageSize=1000&grid-group=&grid-filter=CustomerName~contains~'TEST'

...有时“后退”按钮根本不起作用。我正在使用Telerik Kendo MVC网格,这是用户过滤页面时URL所发生的情况。

我注意到,如果没有表单标记(例如@Html.BeginForm()),视图中的以下代码将在所有链接上保持一致...

查看

<a href='@Url.Content(@ViewBag.PreviousReferrer)' style="display:none;">
    <input type="button" value="Back" />
</a>

但是对于具有表单标记的Views,这不适用。我得到的只是一个我可以点击的后退按钮,但绝对没有。它甚至没有出现在Fiddler中。

我尝试过的其他事情包括......

<input type="button" value="Back" onclick="@("window.location.href='" + @Url.Content(ViewBag.PreviousReferrer) + "'");" />
<input type="button" value="Back2" onclick="window.location.href = '@Url.Content(@ViewBag.PreviousReferrer)'" />
<input type="button" value="Back3" onclick="javascript:window.location=('@Url.Content(@ViewBag.PreviousReferrer)')" />

如前所述,ViewBag.PreviousReferrer属性在控制器中设置。根据用户是获取还是发布,它将使用Request.PreviousReferrer或我设置的会话变量。我不会包含我的所有控制器代码,因为其余的页面工作正常,但是当我在gets和posts中设置ViewBag.PreviousReferrer时,它就像是这样。在任何帖子之前至少会有一个GET,因此会话变量将始终设置为某个。

控制器

GET
string urlReferrer = Request.UrlReferrer == null ? string.Empty : Request.UrlReferrer.AbsoluteUri.ToUpper();
if (!string.IsNullOrEmpty(urlReferrer) && urlReferrer.Contains("OPENORDER"))
{
    ViewBag.PreviousReferrer = Request.UrlReferrer.AbsoluteUri;
    Session["OpenOrderPreviousReferrer"] = Request.UrlReferrer.AbsoluteUri;
}
else
{
    ViewBag.PreviousReferrer = "~/OpenOrder";
}


POST
ViewBag.PreviousReferrer = Session["OpenOrderPreviousReferrer"] ?? "~/OpenOrder";

理想情况下,这就是我想要的:一种标记样式,用于转到PreviousReferrer中的链接,无论该按钮是在表单标签的内部还是外部。

我认为问题可能与HTML转义序列有关,但我不知道这是否是它的技术术语。

1 个答案:

答案 0 :(得分:1)

我必须创建按钮链接,这样做浏览器&#34;很多&#34;在一个项目中,创建了这个HtmlHelper扩展名:

public static class ActionLinkButtonHelper
{
    /// <summary>
    /// Add a back button that generates a Javascript browser-back 
    /// </summary>
    /// <param name="htmlHelper">HtmlHelper we are extending</param>
    /// <param name="buttonText">Text to display on back button - defaults to "Back"</param>
    /// <param name="actionName">Name of action to execute on click</param>
    /// <param name="controller">Name of optional controller to send action to</param>
    /// <returns></returns>
    public static MvcHtmlString BackButton(this HtmlHelper htmlHelper, string buttonText="Back", string actionName="index", string controller=null, object routeValuesObject = null)
    {
        // Note: "Index is provided as a default
        return ActionLinkButton(htmlHelper, buttonText, actionName, controller, routeValuesObject, new { onclick = "history.go(-1);return false;" });
    }
}

并在页面中使用它:

@Html.BackButton()

或者这个:

@Html.BackButton("Button text", "action", "controller", new {id=routevalues})

它生成一个带有一小段JS的按钮,导致浏览器返回,因此除非禁用JavaScript,否则不需要实际链接。

支持方法(ActionLink作为按钮):

public static MvcHtmlString ActionLinkButton(this HtmlHelper htmlHelper, string buttonText, string actionName, string controllerName, object routeValuesObject = null, object htmlAttributes = null)
{
    // For testing - create links instead of buttons
    //return System.Web.Mvc.Html.LinkExtensions.ActionLink(htmlHelper, buttonText, actionName, controllerName, routeValues, htmlAttributes);

    if (string.IsNullOrEmpty(controllerName))
    {
        controllerName = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
    }
    RouteValueDictionary routeValuesDictionary = new RouteValueDictionary(routeValuesObject);
    RouteValueDictionary htmlAttr = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    TagBuilder tb = new TagBuilder("input");
    tb.MergeAttributes(htmlAttr, false);
    string href = UrlHelper.GenerateUrl("default", actionName, controllerName, routeValuesDictionary, RouteTable.Routes, htmlHelper.ViewContext.RequestContext, false);

    tb.MergeAttribute("type", "button");
    tb.MergeAttribute("value", buttonText);
    if (!tb.Attributes.ContainsKey("onclick"))
    {
        tb.MergeAttribute("onclick", "location.href=\'" + href + "\';return false;");
    }
    return new MvcHtmlString(tb.ToString(TagRenderMode.Normal).Replace("&#39;", "\'").Replace("&#32;"," "));
}

Views / Web.config更改:

要在视图中使用上述Intellisense / auto-complete,您需要在Views/web.config文件<namespaces>中添加一个新条目,如下所示:

  <namespaces>
    ... [SNIP]  ...
    <add namespace="My.Lib.Name" />
  </namespaces>

My.Lib.Name是您放置上面显示的ActionLinkButtonHelper的命名空间。