Подтвердить что ты не робот

Asp.Net Web Api - ModelBinders

Мне нужно использовать собственный шаблонный привязчик, чтобы всегда обрабатывать входящие даты в формате UK, у меня есть настраиваемое связующее устройство и зарегистрировано так:

GlobalConfiguration.Configuration.BindParameter(typeof(DateTime), new DateTimeModelBinder());

Кажется, что это работает только для параметров запроса и работает только в том случае, если я укажу [ModelBinder] на свой параметр, например, есть ли способ заставить все действия использовать мое связующее устройство:

public IList<LeadsLeadRowViewModel> Get([ModelBinder]LeadsIndexViewModel inputModel)

Кроме того, как я могу получить мою опубликованную форму для моего контроллера Api, чтобы использовать мое связующее устройство?

4b9b3361

Ответ 1

Думаю, вам не нужна модель. Ваш подход неверен. Правильный подход к датам использует библиотеку глобализации на стороне клиента, такую ​​как globalize library, чтобы анализировать даты, отформатированные на любом языке, и преобразовывать их в объекты дат JavaScript. Затем вы можете сериализовать свои структуры данных datascript в json с помощью браузера JSON.stringify, и это должно сработать. Лучше использовать всегда стандартные форматы для дат и использовать вместо форматирования вместо форматирования. Доступные форматы также обрабатывают TimeZones правильно, если вы используете параметр вида ваших объектов С# DateTime, чтобы указать, будет ли время даты выражено в локальное время или в UTC.

Ответ 2

Вы можете зарегистрировать привязку модели по всему миру, внедряя ModelBinderProvider и вставляя ее в список сервисов.

Пример использования в Global.asax:

GlobalConfiguration.Configuration.Services.Insert(typeof(ModelBinderProvider), 0, new Core.Api.ModelBinders.DateTimeModelBinderProvider());

Ниже приведен пример кода, демонстрирующего ModelBinderProvider и реализацию ModelProvider, который преобразует аргументы DateTime в соответствии с культурой (используя текущую культуру потоков);

Выполнение DateTimeModelBinderProvider:

using System;
using System.Web.Http;
using System.Web.Http.ModelBinding;

...

public class DateTimeModelBinderProvider : ModelBinderProvider
{
    readonly DateTimeModelBinder binder = new DateTimeModelBinder();

    public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
    {
        if (DateTimeModelBinder.CanBindType(modelType))
        {
            return binder;
        }

        return null; 
    }
}

Реализация DateTimeModelBinder:

public class DateTimeModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        ValidateBindingContext(bindingContext);

        if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName) ||
            !CanBindType(bindingContext.ModelType))
        {
            return false;
        }

        bindingContext.Model = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName)
            .ConvertTo(bindingContext.ModelType, Thread.CurrentThread.CurrentCulture);

        bindingContext.ValidationNode.ValidateAllProperties = true;

        return true;
    }

    private static void ValidateBindingContext(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }

        if (bindingContext.ModelMetadata == null)
        {
            throw new ArgumentException("ModelMetadata cannot be null", "bindingContext");
        }
    }

    public static bool CanBindType(Type modelType)
    {
        return modelType == typeof(DateTime) || modelType == typeof(DateTime?);
    }
}

Ответ 3

Маршрутизация атрибутов, похоже, противоречит привязке модели. Если вы используете маршрутизацию атрибутов, вы можете обернуть конфигурацию global.asax в один вызов GlobalConfiguration.Config, чтобы избежать проблем с инициализацией:

GlobalConfiguration.Configure(config =>
{
    config.BindParameter(typeof(DateTime), new DateTimeModelBinder());
    config.MapHttpAttributeRoutes();
}

(Это может быть исправлено в предстоящем ASP.NET 5, если оно связано с ошибка # 1165.)

Ответ 4

Для этого вам не требуется настраиваемое связующее устройство. Вы должны быть хорошими, изменив культуру нитей в Великобританию или установите настройки web.config для Великобритании, если это то, что ваш сайт использует все время.

Если нет, вы можете поменять DateTimeFormatInfo для CurrentCulture на UK.

Существует также хорошая статья о привязках к модели доступных здесь Скоттом Гензельмом.

Вы можете поместить это в Global.asax:

ModelBinders.Binders[typeof(DateTime)] = new DateAndTimeModelBinder()