Ввод DateTime для десериализации из пользовательской культуры вместо серверной. Ядро ASP.NET - PullRequest
0 голосов
/ 02 мая 2019

У меня есть информация о культуре пользователя, сохраненная в cookie.Я хочу использовать культуру при преобразовании данных datetime.

До сих пор я был в состоянии сделать это для запросов запросов, но для форм-кодированных и json запросов он всегда использует культуру сервера.

Для строки запроса я использовал следующий код, как описано в https://vikutech.blogspot.com/2017/05/elegantly-dealing-with-timezones-in-mvc-core-webapi.html:

public class DateTimeBinder: IModelBinder
    {   
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {            
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var valueProviderResult = bindingContext.ValueProvider
              .GetValue(bindingContext.ModelName);
            if (string.IsNullOrEmpty(valueProviderResult.FirstValue))
            {
                return TaskCache.CompletedTask;
            }
            CultureInfo culture = GetCulturefromCookie();
            DateTime datetime;
            // if couldnot parse by user culture then parse by default culture
            if (DateTime.TryParse(valueProviderResult.FirstValue, culture, DateTimeStyles.RoundtripKind, out datetime) || DateTime.TryParse(valueProviderResult.FirstValue, CultureInfo.CurrentCulture, DateTimeStyles.RoundtripKind, out datetime))
            {
                bindingContext.Result =
                    ModelBindingResult.Success(datetime);
            }
            else
            {
                // TODO: [Enhancement] Could be implemented in better way.  
                bindingContext.ModelState.TryAddModelError(
                    bindingContext.ModelName,
                    bindingContext.ModelMetadata
                    .ModelBindingMessageProvider.AttemptedValueIsInvalidAccessor(
                      valueProviderResult.ToString(), nameof(DateTime)));
            }
            return TaskCache.CompletedTask;
        }
    }
public class DateTimeBinderProvider: IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (context.Metadata.UnderlyingOrModelType == typeof(DateTime))
            {
                return new DateTimeBinder();
            }
            return null; // TODO: Find alternate.  
        }
    }

В файле startup.cs

services.AddMvc(option=> option.ModelBinderProviders.Insert(0, new DateTimeBinderProvider()))

Проблема с этим кодом: if (context.Metadata.UnderlyingOrModelType == typeof(DateTime)), не работает для классов.Я также пытаюсь сделать его глобальным связующим звеном, чтобы мне не нужно было добавлять настраиваемые атрибуты для каждого свойства datetime.

Я пытаюсь сделать это для версий .net core 1, но ответы .net core 2также приветствуются.

Обновление: вот исходный код, если вы хотите попробовать его самостоятельно.https://github.com/ruchanb/AspNetCoreCultureModelBind

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