2010-05-17 20 views
46

HtmlHelper.WysiwygFor (lambda) gibi bir şey söyleyebilirim ve CKEditor'ı görüntülemek için HtmlHelper için kirli küçük bir uzantı yöntemi yazıyorum.HtmlHelper için bir uzantı yönteminde geçirilen bir lambda ifadesinden özellik değerini almanın en kolay yolu nedir?

Şu an çalışıyorum ama tercih ettiğimden biraz daha hantal görünüyor. Bunu yapmanın daha yalın bir yolu olduğunu umuyorum.

Şimdiye dek sahip olduğum şeyler.

public static MvcHtmlString WysiwygFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) 
{ 
    return MvcHtmlString.Create(string.Concat("<textarea class=\"ckeditor\" cols=\"80\" id=\"", 
             expression.MemberName(), "\" name=\"editor1\" rows=\"10\">", 
             GetValue(helper, expression), 
             "</textarea>")); 
} 

private static string GetValue<TModel, TProperty>(HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) 
{ 
    MemberExpression body = (MemberExpression)expression.Body; 
    string propertyName = body.Member.Name; 
    TModel model = helper.ViewData.Model; 
    string value = typeof(TModel).GetProperty(propertyName).GetValue(model, null).ToString(); 
    return value; 
} 

private static string MemberName<T, V>(this Expression<Func<T, V>> expression) 
{ 
    var memberExpression = expression.Body as MemberExpression; 
    if (memberExpression == null) 
      throw new InvalidOperationException("Expression must be a member expression"); 

    return memberExpression.Member.Name; 
} 

Teşekkürler! Böyle

+0

Getvalue yönteminizi test ettim ve yardımcı bir seçim listesi olduğunda iyi yanıtlar aldım. Buradaki diğer yöntemler bu durumda başarısız oldu. – calterras

cevap

72

Dene:

public static MvcHtmlString Try<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TProperty>> expression 
) 
{ 
    var builder = new TagBuilder("textarea"); 
    builder.AddCssClass("ckeditor"); 
    builder.MergeAttribute("cols", "80"); 
    builder.MergeAttribute("name", "editor1"); 
    builder.MergeAttribute("id", expression.Name); // not sure about the id - verify 
    var value = ModelMetadata.FromLambdaExpression(
     expression, htmlHelper.ViewData 
    ).Model; 
    builder.SetInnerText(value.ToString()); 
    return MvcHtmlString.Create(builder.ToString()); 
} 
Ben bu eski bir iplik ama her ihtimale karşı birisi arıyorsa bilin
+6

Ben çoğunlukla bu satırdan ilgileniyordu - var value = ModelMetadata.FromLambdaExpression ( ifade, htmlHelper.ViewData ) .Model; harika çalıştı! Ifadeni buldum.Name null değerini döndürdü. Kimlik için çalışanı almak için ÜyelikAdı yöntemine işaret etmek için bunu değiştirdim. Ayrıca, ID özniteliğini eklemek için bir TagBuilder.GenerateId() olduğunu buldum. Teşekkürler. Yaklaşan kitabımda (ASP.NET MVC Yemek Kitabı - http://groups.google.com/group/aspnet-mvc-2-cookbook-review) –

+0

Merhaba, size açıklayabilir misiniz? bu hat? 'var value = ModelMetadata.FromLambdaExpression ( ifade, htmlHelper.ViewData ) .Model;' –

20
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
Object value = metadata.Model; 
String name = metadata.PropertyName; 
+0

Bu benim için çalışıyor ve expression.Name null değerini döndürdüğü PropertyName özelliği özelliğini doğru şekilde alıyor. Eklemek için Düzenle - Önemli olan durumda MVC5 çalıştırıyorum –

8

, kimliği/ad özniteliği oluşturmak için bir yol da:

System.Web.Mvc.ExpressionHelper.GetExpressionText(expression); 

Bunu uzantılarımda kullanıyorum ve hiçbir sorunla karşılaşmadım. Aynı zamanda yuvalanmış özellikleri ile harika çalışıyor.

+1

Bu özellik Mülkün adını alacak, ancak Değerini değil – bjan

3

ASP.NET MVC 3 Futures bunun için bir yardımcı içerir.

public static class ExtensionMethods 
{ 

    public static object Value<TModel, TProperty>(this Expression<Func<TModel, TProperty>> expression, ViewDataDictionary<TModel> viewData) 
    { 
     return ModelMetadata.FromLambdaExpression(expression, viewData).Model; 
    } 

} 

Yani çağıran sözdizimi::

5

kolay yoludur uzatma yönteminde hepsini tamamlamayı olduğunu

expression.Value(htmlHelper.ViewData) 
1

Bu Peter veya Büyükannenin cevabı biri tarafından ele alınmamıştır ama her ikisini birleştirir.

Sonra
public ModelMetadata GetModelMetadata<TModel, TProperty>(TModel model, Expression<Func<TModel, TProperty>> expression) 
{ 
    ViewData.Model = model; //model is null in Controller; you must set it here (or earlier) in order to extract values from the returned ModelMetadata. 
    return ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary<TModel>(ViewData)); 
} 

Eğer modeli meta verilerinden gerekenleri okuyabilirsiniz: Eğer bir HtmlHelper örneğine erişimi olmayan bir denetleyici yönteminde, bu arama yapacaksanız sadece böyle bir temel denetleyicisi yöntemi oluşturmak her zaman oldugu gibi;

var mm = GetModelMetaData(model, m => m.SomeProperty); 
string name = mm.PropertyName; 
object value = mm.Model; 
İlgili konular