非常着名的ActionLink
:
<%: Html.ActionLink("Back to List", "Index")%>
现在,此链接位于我的详细信息视图中。索引视图是搜索页面。其URL如下所示:
http://localhost:50152/2011-2012/Instelling/Details/76?gemeente=Dendermonde&postcode=92**&gebruikerscode=VVKSO114421&dossiernr=114421%20&organisatie=CLB
正如你所看到的,相当多的参数。显然,当我返回索引页面时,我想保留所有这些参数,因此我需要在ActionLink
中添加它们。
现在,我已经厌倦了手动操作,1可以,但不适合6.这应该会更容易。
问题:如何将当前网址的所有参数作为可选ActionLink
返回RouteValues
。
我一直在寻找Request.QueryString
。它必须是那样的东西。我正在考虑在Global.asax
中编写一些静态方法来完成工作,但还没有运气。也许有一种简单的方法可以做到这一点我不知道?
编辑:这就是我提出的(有效)
在 global.asax:
中 public static RouteValueDictionary optionalParamters(NameValueCollection c) {
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys) {
r.Add(s, c[s]);
}
return r;
}
Details.aspx:
<%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
我最好把这段代码放在哪里?不在Global.asax
我猜...
编辑2:
using System;
using System.Web.Mvc;
namespace MVC2_NASTEST.Helpers {
public static class ActionLinkwParamsExtensions {
public static MvcHtmlString CustomLink(this HtmlHelper helper, string linktext) {
//here u can use helper to get View context and then routvalue dictionary
var routevals = helper.ViewContext.RouteData.Values;
//here u can do whatever u want with route values
return null;
}
}
}
<%@ Import Namespace="MVC2_NASTEST.Helpers" %>
...
<%: Html.ActionLinkwParams("Index") %>
答案 0 :(得分:20)
这就是我最终修复它的方式,我很自豪,因为它工作得非常好而且非常干燥。
视图中的来电:
<%: Html.ActionLinkwParams("Back to List", "Index")%>
但是对于重载,它可以是普通ActionLink所采用的任何东西。
帮助者:
帮助程序从URL中获取不在路径中的所有参数。 例如:这个网址:
http://localhost:50152/2011-2012/myController/Details/77?postalCode=9***&org=CLB
所以它将采用postalCode和Org并将其放在新的ActionLink中。 通过过载,可以添加其他参数,并且可以删除现有URL中的参数。
using System;
using System.Web.Mvc;
using System.Web.Routing;
using System.Collections.Specialized;
using System.Collections.Generic;
namespace MVC2_NASTEST.Helpers {
public static class ActionLinkwParamsExtensions {
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller, object extraRVs, object htmlAttributes) {
NameValueCollection c = helper.ViewContext.RequestContext.HttpContext.Request.QueryString;
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys) {
r.Add(s, c[s]);
}
RouteValueDictionary htmlAtts = new RouteValueDictionary(htmlAttributes);
RouteValueDictionary extra = new RouteValueDictionary(extraRVs);
RouteValueDictionary m = Merge(r, extra);
return System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, linktext, action, controller, m, htmlAtts);
}
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action) {
return ActionLinkwParams(helper, linktext, action, null, null, null);
}
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller) {
return ActionLinkwParams(helper, linktext, action, controller, null, null);
}
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, object extraRVs) {
return ActionLinkwParams(helper, linktext, action, null, extraRVs, null);
}
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller, object extraRVs) {
return ActionLinkwParams(helper, linktext, action, controller, extraRVs, null);
}
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, object extraRVs, object htmlAttributes) {
return ActionLinkwParams(helper, linktext, action, null, extraRVs, htmlAttributes);
}
static RouteValueDictionary Merge(this RouteValueDictionary original, RouteValueDictionary @new) {
// Create a new dictionary containing implicit and auto-generated values
RouteValueDictionary merged = new RouteValueDictionary(original);
foreach (var f in @new) {
if (merged.ContainsKey(f.Key)) {
merged[f.Key] = f.Value;
} else {
merged.Add(f.Key, f.Value);
}
}
return merged;
}
}
}
在使用重载的视图中
<%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>
在URL中我有paramters postalCode有一些值。我的代码在URL中获取所有这些代码,通过将其设置为string.Empty,我从列表中删除此参数。
欢迎评论或想法进行优化。
答案 1 :(得分:10)
为Request.QueryString创建 ToRouteValueDictionary()扩展方法,以便按原样使用Html.ActionLink并简化视图标记:
<%: Html.ActionLink("Back to List", "Index", Request.QueryString.ToRouteValueDictionary())%>
您的扩展方法可能如下所示:
using System.Web.Routing;
using System.Collections.Specialized;
namespace MyProject.Extensions
{
public static class CollectionExtensions
{
public static RouteValueDictionary ToRouteValueDictionary(this NameValueCollection collection)
{
var routeValueDictionary = new RouteValueDictionary();
foreach (var key in collection.AllKeys)
{
routeValueDictionary.Add(key, collection[key]);
}
return routeValueDictionary;
}
}
}
要在视图中使用扩展方法,请参阅此问题并回答:How do I use an extension method in an ASP.NET MVC View?
这比接受的答案更简单,代码少得多。
答案 2 :(得分:6)
这是ViewContext的扩展方法,它根据请求路由值和查询字符串创建RouteValueDictionary。
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyMvcApplication.Utilities
{
public static class ViewContextExtensions
{
/// <summary>
/// Builds a RouteValueDictionary that combines the request route values, the querystring parameters,
/// and the passed newRouteValues. Values from newRouteValues override request route values and querystring
/// parameters having the same key.
/// </summary>
public static RouteValueDictionary GetCombinedRouteValues(this ViewContext viewContext, object newRouteValues)
{
RouteValueDictionary combinedRouteValues = new RouteValueDictionary(viewContext.RouteData.Values);
NameValueCollection queryString = viewContext.RequestContext.HttpContext.Request.QueryString;
foreach (string key in queryString.AllKeys.Where(key => key != null))
combinedRouteValues[key] = queryString[key];
if (newRouteValues != null)
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(newRouteValues))
combinedRouteValues[descriptor.Name] = descriptor.GetValue(newRouteValues);
}
return combinedRouteValues;
}
}
}
您可以将创建的RouteValueDictionary传递给Html.ActionLink或Url.Action
@Html.ActionLink("5", "Index", "Product",
ViewContext.GetCombinedRouteValues(new { Page = 5 }),
new Dictionary<string, object> { { "class", "page-link" } })
如果请求URL中不存在Page参数,则会将其添加到生成的URL中。如果确实存在,则其值将更改为5.
This article对我的解决方案有更详细的解释。
答案 3 :(得分:1)
public static class Helpers
{
public static MvcHtmlString CustomLink(this HtmlHelper helper,string LinkText, string actionName)
{
var rtvals = helper.ViewContext.RouteData.Values;
var rtvals2 = helper.RouteCollection;
RouteValueDictionary rv = new RouteValueDictionary();
foreach (string param in helper.ViewContext.RequestContext.HttpContext.Request.QueryString.AllKeys)
{
rv.Add(param, helper.ViewContext.RequestContext.HttpContext.Request.QueryString[param]);
}
foreach (var k in helper.ViewContext.RouteData.Values)
{
rv.Add(k.Key, k.Value);
}
return helper.ActionLink(LinkText, actionName, rv);
}
}
我测试了这个和它的工作。可以从查询字符串中获取可选参数 HTH
答案 4 :(得分:0)
也许最好的方法是在遍历前一个路由值字典的地方编写自己的html帮助程序,并将路由值添加到当前操作链接,但当前操作参数除外。
编辑: 您可以像这样编写html帮助器:
public static MvcHtmlString CustomLink(this HtmlHelper helper,string linktext)
{
//here you can use helper to get View context and then routvalue dictionary
var routevals = helper.ViewContext.RouteData.Values;
//here you can do whatever you want with route values
}