Interessante domanda (+1). Suppongo che lo scopo sia quello di utilizzare il modello predefinito di associazione per associare i parametri di querystring ai parametri Action
.
Fuori dalla scatola Non credo che il metodo ActionLink
faccia questo per voi (ovviamente non c'è nulla che vi impedisca di farvi da soli). Guardando nel riflettore possiamo vedere che quando lo viene aggiunto allo RouteValueDictionary
, vengono aggiunte solo coppie di valori chiave. Questo è il codice che aggiunge le coppie di valori chiave e come puoi vedere non c'è attraversamento delle proprietà dell'oggetto.
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
{
object obj2 = descriptor.GetValue(values);
this.Add(descriptor.Name, obj2);
}
Così per l'oggetto
var values = new { Filter = new Filter { MessageFilter = item.Message } }
la chiave che viene aggiunto è Filter
e il valore è il vostro Filter
oggetto che valuterà il nome completo del tipo di oggetto.
Il risultato è Filter=Youre.Namespace.Filter
.
Modificapossibile soluzione a seconda delle vostre esigenze Metodo
estensionefa il lavoro
Nota che utilizza i metodi quadro statici ExpressionHelper
e ModelMetadata
(che vengono utilizzati anche dagli helper esistenti) per determinare i nomi appropriati che il il raccoglitore modello predefinito comprenderà e il valore della proprietà, rispettivamente.
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));
}
}
modelli di esempio
public class MyViewModel
{
public string SomeProperty { get; set; }
public FilterViewModel Filter { get; set; }
}
public class FilterViewModel
{
public string MessageFilter { get; set; }
}
azione
public ActionResult YourAction(MyViewModel model)
{
return this.View(
new MyViewModel
{
SomeProperty = "property value",
Filter = new FilterViewModel
{
MessageFilter = "stuff"
}
});
}
utilizzo
Qualsiasi numero delle proprietà del modello di visualizzazione può essere aggiunto alla querystring tramite l'ultimo parametrodel metodo.
@this.Html.ActionLink(
"Your Link Text",
"YourAction",
"YourController",
x => x.SomeProperty,
x => x.Filter.MessageFilter)
Markup
<a href='/YourAction/YourController?SomeProperty=some property value&Filter.MessageFilter=stuff'>Your Link Text</a>
Invece di utilizzare string.Format
è possibile utilizzare TagBuilder
, querystring dovrebbe essere codificato da passare in modo sicuro in un URL e questo metodo di estensione avrebbe bisogno di un po 'di un'ulteriore convalida, ma Penso che potrebbe essere utile. Si noti inoltre che, sebbene questo metodo di estensione sia stato creato per MVC 4, potrebbe essere facilmente modificato per le versioni precedenti. Non mi rendevo conto che uno dei tag MVC era per la versione 3 fino ad ora.
+1 una buona domanda –
grazie per la modifica; Ho rifattorizzato la risposta e nella sostituzione ho dimenticato di aggiungere il 'prefisso'! –
@AndrasZoltan Nessun problema. – DaveShaw