Я сделал ТОЛЬКО то, что тебе нужно!
Я создал помощник HTML для этого. Помощник принимает те же параметры, что и обычный помощник. Тем не менее, он сохраняет текущие значения из URL. Я сделал это для URL helper
как ActionLink helper
.
Это заменяет: Url.Action()
<a href='<%= Html.UrlwParams("TeamStart","Inschrijvingen", new {modID=item.Mod_ID}) %>' title="Selecteer">
<img src="<%= Url.Content("~/img/arrow_right.png") %>" alt="Selecteer" width="16" /></a>
и это заменяет Html.ActionLink()
<%: Html.ActionLinkwParams("Tekst of url", "Action", new {test="yes"}) %>
Вот помощник:
using System;
using System.Web.Mvc;
using System.Web.Routing;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Web.Mvc.Html;
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 = RouteValues.MergeRouteValues(r, extra);
//return System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, linktext, action, controller, m, htmlAtts);
return helper.ActionLink(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);
}
}
public static class UrlwParamsExtensions {
public static string UrlwParams(this HtmlHelper helper, string action, string controller, object extraRVs) {
NameValueCollection c = helper.ViewContext.RequestContext.HttpContext.Request.QueryString;
RouteValueDictionary r = RouteValues.optionalParamters(c);
RouteValueDictionary extra = new RouteValueDictionary(extraRVs);
RouteValueDictionary m = RouteValues.MergeRouteValues(r, extra);
string s = UrlHelper.GenerateUrl("", action, controller, m, helper.RouteCollection, helper.ViewContext.RequestContext, false);
return s;
}
public static string UrlwParams(this HtmlHelper helper, string action) {
return UrlwParams(helper, action, null, null);
}
public static string UrlwParams(this HtmlHelper helper, string action, string controller) {
return UrlwParams(helper, action, controller, null);
}
public static string UrlwParams(this HtmlHelper helper, string action, object extraRVs) {
return UrlwParams(helper, action, null, extraRVs);
}
}
}
Как это работает?
Вызовы такие же, как для Html.ActionLink()
, поэтому вы можете просто их заменить.
Метод выполняет следующие действия:
Он берет все необязательные параметры из текущего URL и помещает их в RouteValueDictionary
.
Он также помещает htmlattributes
в словарь.
Затем он берет дополнительные значения маршрута, которые вы указали вручную, и помещает их в RouteValueDictionary
.
Тогда ключ должен объединить те из URL и те, которые указаны вручную.
Это происходит в классе RouteValues.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Collections.Specialized;
using System.Web.Mvc;
namespace MVC2_NASTEST {
public static class RouteValues {
public static RouteValueDictionary optionalParamters() {
return optionalParamters(HttpContext.Current.Request.QueryString);
}
public static RouteValueDictionary optionalParamters(NameValueCollection c) {
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys) {
r.Add(s, c[s]);
}
return r;
}
public static RouteValueDictionary MergeRouteValues(this RouteValueDictionary original, RouteValueDictionary newVals) {
// Create a new dictionary containing implicit and auto-generated values
RouteValueDictionary merged = new RouteValueDictionary(original);
foreach (var f in newVals) {
if (merged.ContainsKey(f.Key)) {
merged[f.Key] = f.Value;
} else {
merged.Add(f.Key, f.Value);
}
}
return merged;
}
public static RouteValueDictionary MergeRouteValues(this RouteValueDictionary original, object newVals) {
return MergeRouteValues(original, new RouteValueDictionary(newVals));
}
}
}
Это все довольно просто. В конце концов, actionlink
создается с объединенными значениями маршрутов. Этот код также позволяет удалять значения из URL.
Примеры:
Ваш URL-адрес localhost.com/controller/action?id=10&foo=bar
. Если на этой странице вы разместите этот код
<%: Html.ActionLinkwParams("Tekst of url", "Action", new {test="yes"}) %>
URL, возвращаемый в этом элементе, будет localhost.com/controller/action?id=10&foo=bar&test=yes
.
Если вы хотите удалить элемент, вы просто устанавливаете элемент в виде пустой строки. Например,
<%: Html.ActionLinkwParams("Tekst of url", "Action", new {test="yes", foo=""}) %>
вернет URL в элементе : localhost.com/controller/action?id=10&test=yes
Полагаю, это все, что вам нужно?
Если у вас есть дополнительные вопросы, просто спросите.
Дополнительно:
Иногда вы захотите также сохранить свои значения внутри своего действия, когда будете перенаправлять на другое действие. С моим классом RouteValues это можно сделать очень легко:
public ActionResult Action(string something, int? somethingelse) {
return RedirectToAction("index", routeValues.optionalParamters(Request.QueryString));
}
Если вы все еще хотите добавить некоторые дополнительные параметры, нет проблем!
public ActionResult Action(string something, int? somethingelse) {
return RedirectToAction("index", routeValues.optionalParamters(Request.QueryString).MergeRouteValues(new{somethingelse=somethingelse}));
}
Я думаю, что это охватывает почти все, что вам нужно.