Пользовательская модель Binder работает только для application / x-www-form-urlencoded, но не для application / json - PullRequest
0 голосов
/ 06 марта 2019

У меня есть пользовательское связующее для модели TimeSpan.Я использую jQuery AJAX POST и по умолчанию отправляет contentType как appplication/x-www-form-urlencoded, и это работает.Я переключаюсь на axios, и методы post отправляют данные формы как application/json, а привязка пользовательской модели не запускается.

public sealed class TimeSpanModelBinder : IModelBinder
    {
        private const DateTimeStyles _dateTimeStyles = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeLocal | DateTimeStyles.NoCurrentDateDefault;

        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(TimeSpan))
            {
                return false;
            }

            var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (val == null)
            {
                return false;
            }

            var key = val.RawValue as string;
            if (key == null)
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Wrong value type for TimeSpan");
                return false;
            }

            try
            {
                TimeSpan time;
                TryParseTime(key, out time);

                bindingContext.Model = time;
                //bindingContext.Model = System.Xml.XmlConvert.ToTimeSpan(key);
                return true;
            }
            catch (Exception e)
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value to TimeSpan: " + e.Message);
                return false;
            }
        }

        public static bool TryParseTime(string text, out TimeSpan time)
        {
            if (text == null)
                throw new ArgumentNullException("text");

            var formats = new[] {
                    "HH:mm", "HH.mm", "HHmm", "HH,mm", "HH",
                    "H:mm", "H.mm", "H,mm",
                    "hh:mmtt", "hh.mmtt", "hhmmtt", "hh,mmtt", "hhtt",
                    "h:mmtt", "h.mmtt", "hmmtt", "h,mmtt", "htt"
                };

            text = Regex.Replace(text, "([^0-9]|^)([0-9])([0-9]{2})([^0-9]|$)", "$1$2:$3$4");
            text = Regex.Replace(text, "^[0-9]$", "0$0");

            foreach (var format in formats)
            {
                DateTime value;
                if (DateTime.TryParseExact(text, format, CultureInfo.InvariantCulture, _dateTimeStyles, out value))
                {
                    time = value.TimeOfDay;
                    return true;
                }
            }
            time = TimeSpan.Zero;
            return false;
        }
    }

Это установлено в WebApiConfig

config.Services.Insert(typeof(ModelBinderProvider), 0, new SimpleModelBinderProvider(typeof(TimeSpan), new TimeSpanModelBinder()));

Я использовал Fiddler для проверки заголовков.

Content-Type: application/x-www-form-urlencoded;charset=UTF-8 работает

Content-Type: application/json;charset=UTF-8 не работает

Проблема связана только с привязками пользовательских моделей,Все остальные свойства карты отлично в обоих Content-Type.

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