Переопределение редактора по умолчанию для выбора шаблона в ASP.NET MVC 3 RC - PullRequest
7 голосов
/ 12 ноября 2010

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

Если я сейчас создаю View с model = "IAppMusicProvider" и запускаю Html.EditorForModel(), мне нужно этонайдите шаблон «~ Views \ Shared \ EditorTemplates \ IAppProvider.cshtml».Есть ли какой-нибудь простой способ добиться этого?

Ответы [ 2 ]

2 голосов
/ 10 июля 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);
1 голос
/ 12 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...