2013-07-03 19 views
9

Şirketim boyunca yeniden kullanabileceğim bir genel (birçok yerde yararlı) denetimi yazmaya çalışıyorum.Asp.Net MVC Razor'da 'genel' kontrol nasıl oluşturabilirim?

Görünüm ve viewmodelimde gerçek C# jeneriklerle ilgili sorunlar yaşıyorum. İşte

ben yapmaya çalışıyorum şeyin bir örnektir:

Jenerik kısmi görünümü: (_Control.cshtml)

@model SimpleExample<dynamic> 

@Model.HtmlTemplate(Model.Data) 

ViewData: (SimpleExample.cs)

public class SimpleExample<T> 
{ 
    public T Data; 
    public Func<T, System.Web.WebPages.HelperResult> HtmlTemplate; 
} 

Örnek kullanım: (FullView.cshtml)

@model Foo.MyViewData 

@Html.Partial("_Control", new SimpleExample<MyViewData> 
{ 
    Data = Model, 
    HtmlTemplate = @<div>@item.SomeProperty</div> 
}) 

Aradığım işlevin önemli bir kısmı, kullanıcıların Html satır içi yazımlarını yazarken Intellisense'i (FullView.cshtml'da olduğu gibi) yazmaları için yazılan bir nesne almalarıdır.

Her şey iyi derler ve intellisense çalışıyor ama hatasına çalışma zamanını alıyorum:

The model item passed into the dictionary is of type 
'AnytimeHealth.Web.ViewData.SimpleExample`1[Foo.MyViewData]', 
but this dictionary requires a model item of type 
'AnytimeHealth.Web.ViewData.SimpleExample`1[System.Object]'. 

Ben bu almak için benim jenerik türüne kullanım eğilimlerini kullanmak mümkün olabilir okudum Çalış, ama bunu nasıl yapacağımı bilmiyorum.

Bu işe nasıl başlayabileceğimi öğretir misiniz? _Control.cshtml tanımladığınız

cevap

3

Değişimi:

Değişim bu @model SimpleExample<dynamic>

@model dynamic için

ve eserlerini alırım ama SimpleExample ve

MyViewData ait intellisense olacak hala çalışır

ait intellisense kaybedersiniz.

Dinamik tip çalışma zamanında bilinen edilecektir yüzünden olduğunu düşünüyorum, ama jenerik

tipi bir erken zaman gerektiren bu noktada, (belki derleme süresi ise), sadece object bilinmelidir edilir.

+0

Bu benim için çalışıyor, zira _Control 'de intellisense kaybettim: (' – jjnguy

3

Genel bir nesne kullanabilir ve yansıma kullanarak bu nesnenin özelliklerini (özelliklerin listelenmesi için bir yardımcı kullanarak) oluşturabilirsiniz.

public static string GetLabel(this PropertyInfo propertyInfo) 
{ 
    var meta = ModelMetadataProviders.Current.GetMetadataForProperty(null, propertyInfo.DeclaringType, propertyInfo.Name); 
    return meta.GetDisplayName(); 
} 

public static PropertyInfo[] VisibleProperties(this IEnumerable Model) 
{ 
    var elementType = Model.GetType().GetElementType(); 
    if (elementType == null) 
    { 
     elementType = Model.GetType().GetGenericArguments()[0]; 
    } 
    return elementType.GetProperties().Where(info => info.Name != elementType.IdentifierPropertyName()).ToArray(); 
} 

public static PropertyInfo[] VisibleProperties(this Object model) 
{ 
    return model.GetType().GetProperties().Where(info => info.Name != model.IdentifierPropertyName()).ToArray(); 
} 
Helper.cs

http://nuget.org/packages/twitter.bootstrap.mvc4

_Control.cshtml

@model Object 
@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>@Model.GetLabel()</legend> 
     @foreach (var property in Model.VisibleProperties()) 
     { 
      using(Html.ControlGroupFor(property.Name)){ 
       @Html.Label(property.Name) 
       @Html.Editor(property.Name) 
       @Html.ValidationMessage(property.Name, null) 
      } 
     } 
     <button type="submit">Submit</button> 
    </fieldset> 
} 

: Bu MVC 4 için Heyecan Bootstrap tarafından kullanılan aynı yaklaşımı (Bu kodun wich bölümünden kolaylık, kopyalanmış durumda) 'dir