自定义模型活页夹仅适用于application / x-www-form-urlencoded,但不适用于application / json

时间:2019-03-05 22:32:46

标签: c# ajax asp.net-web-api model-binding content-type

我有一个针对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中都映射良好。

0 个答案:

没有答案