Переопределение редактора по умолчанию для выбора шаблона в ASP.NET MVC 3 RC

Я создаю MVC-приложение, которое в настоящее время использует EditorFor для создания большого количества представлений. Весь вид в основном представляет собой просто 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.

Если я сейчас создам представление с моделью = "IApMusicProvider" и запущу Html.EditorForModel(), мне нужно найти шаблон "~Views\Shared\EditorTemplates\IApProvider.cshtml". Есть ли простой способ добиться этого?


person Alxandr    schedule 12.11.2010    source источник


Ответы (2)


Вы пытались использовать атрибут [TemplateHint]?

person John Farrell    schedule 12.11.2010
comment
Да, это работает, но это не решение проблемы (точнее, я фактически использовал атрибут [DataType]). Приложение, которое я делаю, будет запускать плагины, и мне нужно, чтобы оно работало только путем настройки интерфейса, а не принуждать всех разработчиков плагинов к пользователю [DataType("IAppProvider")]. - person Alxandr; 12.11.2010
comment
Попробуйте назвать шаблон так же, как интерфейс? Насколько я помню, это только два варианта. - person John Farrell; 12.11.2010
comment
Это тоже не сработает, потому что шаблон должен работать для всех IAppProvider. Я ищу способ переопределить это поведение по умолчанию, чтобы, если я предоставлю интерфейс, реализующий IAppProvider, он использовал шаблон IAppProvider. Это, вероятно, нужно закодировать где-то в MVC (какой-то компонент, который нужно изменить, например, вы можете сделать с ControllerFactory и т. д.), но я даже не знаю, с чего начать. - person Alxandr; 12.11.2010
comment
Я думаю, вы имеете в виду [UIHint]. TemplateHint кажется собственностью ModelMetadata. - person Sam; 10.07.2014

Вы можете попробовать изменить ModelMetadata.TemplateHint в файле ModelMetadataProvider. Один из способов сделать это с помощью шаблона декоратора:

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);
person Sam    schedule 10.07.2014