7

我正在创建一个当前使用 EditorFor 生成大量视图的 MVC 应用程序。整个视图基本上只是一个 EditorForModel,而且效果很好。但是,我遇到了一个小问题,我似乎无法找到解决方案,重要的是它按我需要的方式工作,那就是在尝试渲染 EditorFor 界面时。绑定和类似的一切都已处理,但问题是 EditorFor 认为它是一个接口,并默认为“对象”模板。我需要它来查看接口,看看它是否可以找到具有该名称的模板,如果不能,我需要它查看所有存在的接口,看看它是否与其中任何一个匹配。为了更简单地解释它,请看这个例子:

接口:

public interface IAppProvider
{
    string Name { get; set; }
}

public interface IAppMusicProvider : IAppProvider
{
    int GetPlaylistCount();
} // Yeah, I know, this interface is not smart, but it's only for show.

如果我现在使用 model = "IAppMusicProvider" 创建一个视图并运行Html.EditorForModel(),我需要它来找到 "~Views\Shared\EditorTemplates\IAppProvider.cshtml" 模板。有什么简单的方法可以实现吗?

4

2 回答 2

2

您可以尝试ModelMetadata.TemplateHintModelMetadataProvider. 一种方法是使用装饰器模式:

public class AbstractTypeTemplateSupportingModelMetadataProvider : ModelMetadataProvider
{
    private readonly ModelMetadataProvider wrapped;

    public AbstractTypeTemplateSupportingModelMetadataProvider(ModelMetadataProvider wrapped)
    {
        this.wrapped = wrapped;
    }

    public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType)
    {
        var result = this.wrapped.GetMetadataForProperties(container, containerType).ToList();
        result.ForEach(ChangeTemplateHint);

        return result;
    }

    public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
    {
        var result = this.wrapped.GetMetadataForProperty(modelAccessor, containerType, propertyName);
        ChangeTemplateHint(result);

        return result;
    }

    public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType)
    {
        var result = this.wrapped.GetMetadataForType(modelAccessor, modelType);
        ChangeTemplateHint(result);

        return result;
    }

    private void ChangeTemplateHint(ModelMetadata source)
    {
        if (source.Model is IAppProvider) //Or use source.ModelType if you want to support the model being null.
            source.TemplateHint = typeof(IAppProvider).Name;
    }
}

在您的启动逻辑中:

ModelMetadataProviders.Current = new AbstractTypeTemplateSupportingModelMetadataProvider(ModelMetadataProviders.Current);
于 2014-07-10T07:07:34.877 回答
1

您是否尝试使用该[TemplateHint]属性?

于 2010-11-12T02:36:32.587 回答