Pregunta interesante (+1). Supongo que el objetivo es utilizar el enlace de modelo predeterminado para vincular los parámetros de la cadena de consulta a los parámetros Action
.
Fuera de la caja no creo que el método ActionLink
haga esto por usted (por supuesto, no hay nada que le impida rodar el suyo). Mirando en el reflector podemos ver que cuando se agrega el object
al RouteValueDictionary
, solo se agregan pares de valores clave. Este es el código que agrega los pares de valores clave y, como puede ver, no se cruzan las propiedades del objeto.
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
{
object obj2 = descriptor.GetValue(values);
this.Add(descriptor.Name, obj2);
}
Así que para su objeto
var values = new { Filter = new Filter { MessageFilter = item.Message } }
la clave que se añade es Filter
y el valor es su Filter
objeto que evaluará al nombre completo de su tipo de objeto.
El resultado de esto es Filter=Youre.Namespace.Filter
.
Editarsolución posible en función de sus necesidades exactas Método
Extensiónhace el trabajo
Note que usa los métodos marco estático ExpressionHelper
y ModelMetadata
(que también son utilizados por los ayudantes existentes) para determinar los nombres apropiados que el el encuadernador de modelo predeterminado comprenderá y valorará la propiedad, respectivamente.
public static class ExtentionMethods
{
public static MvcHtmlString ActionLink<TModel, TProperty>(
this HtmlHelper<TModel> helper,
string linkText,
string actionName,
string controllerName,
params Expression<Func<TModel, TProperty>>[] expressions)
{
var urlHelper = new UrlHelper(helper.ViewContext.HttpContext.Request.RequestContext);
var url = urlHelper.Action(actionName, controllerName);
if (expressions.Any())
{
url += "?";
foreach (var expression in expressions)
{
var result = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, helper.ViewData);
url = string.Concat(url, result, "=", metadata.SimpleDisplayText, "&");
}
url = url.TrimEnd('&');
}
return new MvcHtmlString(string.Format("<a href='{0}'>{1}</a>", url, linkText));
}
}
modelos de ejemplo
public class MyViewModel
{
public string SomeProperty { get; set; }
public FilterViewModel Filter { get; set; }
}
public class FilterViewModel
{
public string MessageFilter { get; set; }
}
acción
public ActionResult YourAction(MyViewModel model)
{
return this.View(
new MyViewModel
{
SomeProperty = "property value",
Filter = new FilterViewModel
{
MessageFilter = "stuff"
}
});
}
de uso
Se puede agregar cualquier cantidad de propiedades de su modelo de vista a la cadena de consulta a través del último parámetro params
del método.
@this.Html.ActionLink(
"Your Link Text",
"YourAction",
"YourController",
x => x.SomeProperty,
x => x.Filter.MessageFilter)
marcado
<a href='/YourAction/YourController?SomeProperty=some property value&Filter.MessageFilter=stuff'>Your Link Text</a>
En lugar de utilizar string.Format
podría utilizar TagBuilder
, la cadena de consulta debe ser codificado para ser aprobado de forma segura en una URL y este método de extensión necesitaría una validación adicional, pero Creo que podría ser útil. Tenga en cuenta también que, aunque este método de extensión está diseñado para MVC 4, podría modificarse fácilmente para las versiones anteriores. No me di cuenta de que una de las etiquetas MVC era para la versión 3 hasta ahora.
+1 una buena pregunta –
gracias por la edición; Refactoré la respuesta y en el reemplazo olvidé agregar el 'prefijo' –
@AndrasZoltan No hay problema. – DaveShaw