MVC ActionLink добавить все (необязательно) параметры из текущего url
известный 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. Это должно пройти намного легче.
вопрос: Как вернуть все параметры текущего URL-адреса в ActionLink
как необязательные RouteValues
.
я ищу Request.QueryString
. С этим что-то должно быть. Я думал написать какой-то статический метод в Global.asax
делать работу, но пока не повезло. Может быть, есть простой способ сделать это, о котором я не знаю?
Edit: это то, что я придумал (что работает)
In глобальные.асакс:
public static RouteValueDictionary optionalParamters(NameValueCollection c) {
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys) {
r.Add(s, c[s]);
}
return r;
}
подробности.aspx:
<%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
где лучше всего поместить этот код? не в Global.asax
Я думаю...
Edit 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") %>
5 ответов
вот как я, наконец, исправил его, и я горжусь, потому что он работает очень хорошо и очень сухой.
вызов в представлении:
<%: Html.ActionLinkwParams("Back to List", "Index")%>
но с перегрузками это может быть все, что принимает обычная ActionLink.
Помощник:
помощник берет все параметры из url, которые не находятся в маршруте. Например: этот 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 у меня есть postalCode paramters с некоторым значением. мой код принимает все из них в URL, установив его в строку.Пустой, я удаляю этот параметр из списка.
комментарии или идеи приветствуются по ее оптимизации.
создать ToRouteValueDictionary () метод расширения для запроса.QueryString для использования 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;
}
}
}
чтобы использовать метод расширения в вашем представлении, см. Этот вопрос и ответ: как использовать метод расширения в ASP.NET вид MVC?
это проще и требует гораздо меньше кода, чем принято ответ.
вот метод расширения для 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.Действие
@Html.ActionLink("5", "Index", "Product",
ViewContext.GetCombinedRouteValues(new { Page = 5 }),
new Dictionary<string, object> { { "class", "page-link" } })
если параметр Page не существует в URL-адресе запроса, он будет добавлен в созданный URL-адрес. Если он существует, его значение будет изменено на 5.
в этой статье более подробное объяснение моего решения.
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
возможно, лучший способ-написать свой собственный помощник html, где вы пересекаете предыдущий словарь значений маршрута и добавляете значения маршрута к текущей ссылке действия, кроме параметра действия off course.
изменить: Вы можете написать HTML helper следующим образом:
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
}