route parameter mvc htmlattributes data asp all c# asp.net asp.net-mvc actionlink routevalues

c# - mvc - html.actionlink parameters



MVC ActionLink agrega todos los parĂ¡metros(opcionales) de la url actual (5)

El famoso ActionLink :

<%: Html.ActionLink("Back to List", "Index")%>

Ahora, este enlace está en mi vista de detalles. La vista de índice es una página de búsqueda. La URL de que se ve así:

http://localhost:50152/2011-2012/Instelling/Details/76?gemeente=Dendermonde&postcode=92**&gebruikerscode=VVKSO114421&dossiernr=114421%20&organisatie=CLB

Como puedes ver, bastante la cantidad de parámetros. Obviamente, quiero mantener todos estos parámetros cuando regrese a la página Índice, por lo que necesito agregarlos en el ActionLink .

Ahora, estoy cansado de hacerlo manualmente, está bien para 1, pero no para 6. Esto debería ser mucho más fácil.

Pregunta: ¿Cómo devuelvo todos los parámetros de la URL actual a ActionLink como RouteValues opcional RouteValues

He estado buscando en Request.QueryString . Tiene que ser algo con eso. Estaba pensando en escribir algún método estático en Global.asax haciendo el trabajo, pero aún no he tenido suerte. Tal vez hay una manera fácil de hacer esto que no conozco?

Editar: Esto es lo que se me ocurrió (que funciona)

En 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))%>

¿Dónde pongo mejor este código? no en Global.asax , supongo ...

Edición 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") %>


Aquí hay un método de extensión para ViewContext que crea un RouteValueDictionary basado en los valores de la ruta de solicitud y la cadena de consulta.

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

Puede pasar el RouteValueDictionary creado a Html.ActionLink o Url.Action

@Html.ActionLink("5", "Index", "Product", ViewContext.GetCombinedRouteValues(new { Page = 5 }), new Dictionary<string, object> { { "class", "page-link" } })

Si el parámetro Página no existe en la URL de solicitud, se agregará en la URL generada. Si existe, su valor será cambiado a 5.

Este artículo tiene una explicación más detallada de mi solución.


Así es como finalmente lo arreglé, y estoy bastante orgulloso porque está funcionando muy bien y muy SECO.

La llamada en la vista:

<%: Html.ActionLinkwParams("Back to List", "Index")%>

pero con las sobrecargas puede ser cualquier cosa que tome un ActionLink normal.

El ayudante

El ayudante toma todos los parámetros de la url que no están en la ruta. Por ejemplo: esta url:

http://localhost:50152/2011-2012/myController/Details/77?postalCode=9***&org=CLB

Así que tomará el código postal y la organización y lo colocará en el nuevo ActionLink. Con la sobrecarga, se pueden agregar parámetros adicionales y los parámetros de la URL existente se pueden eliminar.

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

En la vista usando sobrecargas:

<%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>

En la URL tengo los parámetros postalCode con algún valor. mi código los toma a todos en la URL, al establecerlos en string.Empty, elimino este parámetro de la lista.

Los comentarios o ideas son bienvenidos para optimizarlo.


Cree un método de extensión ToRouteValueDictionary () para que Request.QueryString use Html.ActionLink tal como está y simplifique el marcado de su vista:

<%: Html.ActionLink("Back to List", "Index", Request.QueryString.ToRouteValueDictionary())%>

Su método de extensión podría verse así:

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

Para usar el método de extensión en su vista, vea esta pregunta y respuesta: ¿Cómo uso un método de extensión en una vista de ASP.NET MVC?

Esto es más simple e implica mucho menos código que la respuesta aceptada.


Quizás la mejor manera es escribir su propio ayudante html donde recorre el diccionario de valor de ruta anterior y agregue los valores de ruta al enlace de acción actual, excepto el parámetro de acción fuera de curso.

Edición: Puedes escribir el ayudante html así:

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 }


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

He probado esto y su funcionamiento. Se pueden adquirir parámetros opcionales de la cadena de consulta HTH