Je construis une aide HTML MVC qui expose plusieurs propriétés d'une classe.Expression lambdas pour accéder aux sous-propriétés
C'est ma classe:
public class Foo {
public string Section { get; set; }
public string Value { get; set; }
}
Et voici mon aide:
public partial class FooBuilder<TModel> {
public MvcHtmlString DropDownFooListFor(Expression<Func<TModel, Foo>> expression, string optionLabel = null, IDictionary<string, object> htmlAttributes = null) {
var metadata = ModelMetadata.FromLambdaExpression(expression, Helper.ViewData);
var model = metadata.Model as Foo;
var items = FooUtility.GetFooValues(metadata.PropertyName).Select(x => new SelectListItem {
Text = x,
Value = x,
Selected = model != null && model.Value == x
});
var value = Expression.Lambda<Func<TModel, string>>(Expression.MakeMemberAccess(expression.Body, typeof(Foo).GetProperty("Value")), Expression.Parameter(typeof(TModel), "value"));
var list = Expression.Lambda<Func<TModel, string>>(Expression.MakeMemberAccess(expression.Body, typeof(Foo).GetProperty("Section")), Expression.Parameter(typeof(TModel), "section"));
//Helper.ViewContext.Writer.Write(
// Helper.HiddenFor(list, new { value = string.Format("{0}#{1}", FooUtility.GetCurrentSection(), metadata.PropertyName) })
//);
return Helper.DropDownListFor(value, items, optionLabel, htmlAttributes);
}
}
Puis, à l'intérieur de mon point de vue, j'appelle l'aide
@(Html.Foo().DropDownFooListFor(x => x.Bar))
Et voici ma Afficher le modèle:
public class Baz {
public Foo Bar { get; set; }
}
Mon problème est que si je décommenter les trois lignes commentées (i.e.: utiliser l'expression list
), il échoue lamentablement. Je ne comprends pas pourquoi utiliser value
fonctionne comme prévu, mais pas list
.
je reçois l'exception suivante:
variable 'x' de type 'Namespace.Baz' référencé de la portée '', mais il ne définit pas
Encore une fois, Baz
est mon voir le modèle.
Qu'est-ce que je fais mal?
Modifier: Ok, c'est pire que je pensais. Cela fonctionne si j'utilise l'une de mes expressions avec DropDownListFor
, mais pas avec HiddenFor
ou TextBoxFor
.
Edit 2: Voici comment Helper
est défini.
public partial class FooBuilder<TModel> {
public HtmlHelper<TModel> Helper { get; set; }
}
public static class FooHelpers {
public static FooBuilder<TModel> Foo<TModel>(this HtmlHelper<TModel> helper) {
return new FooBuilder<TModel> { Helper = helper };
}
}
Copie possible: http://stackoverflow.com/questions/6106283/memberexpression-invalidoperationexpression-variable-x-referenced-from-scope –
@NickLarsen Où puis-je créer différents paramètres portant le même nom? –
Par curiosité, le code commenté écrira un caché directement à la sortie, pourquoi faites-vous cela? Aussi, pouvez-vous mettre à jour ce code pour montrer où 'Helper' est défini? –