【问题标题】:How can I create a 'generic' control in Asp.Net MVC Razor?如何在 Asp.Net MVC Razor 中创建“通用”控件?
【发布时间】:2013-07-03 05:33:33
【问题描述】:

我正在尝试编写一个通用的(意味着在许多地方都很有用)控件,我可以在整个公司中重复使用它。

我的视图和视图模型中的实际 C# 泛型存在问题。

这是我正在尝试做的一个示例:

通用局部视图:(_Control.cshtml)

@model SimpleExample<dynamic> 

@Model.HtmlTemplate(Model.Data)

查看数据:(SimpleExample.cs)

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

用法示例:(FullView.cshtml)

@model Foo.MyViewData

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

我正在寻找的功能的重要部分是消费者在编写其 Html 内联时获得一个类型化的对象,以便他们可以使用 Intellisense(如FullView.cshtml)。

一切编译正常,智能感知工作正常,但运行时出现错误:

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]'.

我读到我可能可以在我的泛型类型上使用协方差来使其工作,但我不知道该怎么做。

能否请您指导我如何使其正常工作?

【问题讨论】:

    标签: c# asp.net-mvc-3 generics razor


    【解决方案1】:

    更改_Control.cshtml中的定义:

    @model SimpleExample&lt;dynamic&gt;@model dynamic

    它会工作,但会失去SimpleExample 的智能感知,MyViewData 的智能感知仍然有效。

    我认为这是因为动态类型会在运行时知道,但泛型的类型

    需要一个较早的时间(可能是编译时间),此时只有object是已知的。

    【讨论】:

    • 这对我有用,但我在 _Control :( 中失去了智能感知
    【解决方案2】:

    您可以使用通用对象,然后使用反射来呈现该对象的属性(使用帮助程序列出属性)。这与 Twitter Bootstrap 用于 MVC 4 的方法相同(为方便起见,此代码的其中部分已被复制):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>
    }
    

    Helper.cs

    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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 2011-11-14
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      相关资源
      最近更新 更多