【问题标题】:Translate JSON field into controller DateTime parameter .NET WEB API将 JSON 字段转换为控制器 DateTime 参数 .NET WEB API
【发布时间】:2021-08-25 11:40:33
【问题描述】:

当发出下面的 web api 请求时,

指示的 Json 字段将绑定到以下属性

public DateTime AidCurrentPlannedDate { get; set; }
public DateTime AidNewPlannedDate { get; set; }

提交请求时,以下值将绑定到控制器参数属性,请注意,不是使用以下格式“dd/MM/yyyy HH:mm:ss”进行翻译,而是使用以下格式"MM/dd/yyyy HH:mm:ss"。

尝试了以下方法以我们期望的方式强制日期时间绑定(格式“dd/MM/yyyy HH:mm:ss”)

using System;
using System.Globalization;
using System.Web.Mvc;

public class DateTimeBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (controllerContext == null)
            throw new ArgumentNullException("controllerContext", "controllerContext is null.");
        if (bindingContext == null)
            throw new ArgumentNullException("bindingContext", "bindingContext is null.");

        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (value == null)
            throw new ArgumentNullException(bindingContext.ModelName);

        CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
        cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy HH:mm:ss";

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

        try
        {
            var date = value.ConvertTo(typeof(DateTime), cultureInf);

            return date;
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
            return null;
        }
    }
}
using SadegeRestApi.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace SadegeRestApi
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
            ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeBinder());
        }
    }
}

但是,值绑定没有改变。

当字段绑定到控制器参数时,是否可以控制将 JSON 字段转换为 DateTime 属性的方式?怎么可能实现?

【问题讨论】:

  • 来自 Model Binding in ASP.NET Core :请注意,此 [BindRequired] 行为适用于来自已发布表单数据的模型绑定,而不适用于请求正文中的 JSON 或 XML 数据。请求正文数据由输入格式化程序处理。
  • 简而言之,模型绑定不用于 HTTP 内容(表单内容除外)。您需要在解串器设置中指定预期的日期时间格式。
  • 这是经典的 ASP.NET?我不知道,但我想是同上。
  • @vernou,这是一个目标为 .NET Framework 4.5 的 Web api 项目。您能否进一步指导我如何/在何处更改此解串器设置?

标签: c# .net asp.net-web-api


【解决方案1】:

在下面的示例代码中,目的是使用以下格式/掩码“dd/MM/yyyy HH:mm:ss”将字符串转换为 DateTime。

为了控制如何将字符串从 JSON 反序列化为 C# DateTime 数据类型,创建了以下类

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Globalization;

public class DateTimeConverter : DateTimeConverterBase
{
    private string _dateFormat;

    public DateTimeConverter(string dateFormat)
    {
        _dateFormat = dateFormat;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            if (reader.Value != null && reader.Value.ToString().Trim() != string.Empty)
                return DateTime.ParseExact(reader.Value.ToString(), _dateFormat, CultureInfo.InvariantCulture);
        }
        catch
        {
        }
        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(((DateTime)value).ToString(_dateFormat));
    }
}

以下行被添加到文件“.../App_Start/WebApiConfig.cs”中的方法“Register”

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new DateTimeConverter("dd/MM/yyyy HH:mm:ss"));

所以文件“.../App_Start/WebApiConfig.cs”看起来像这样

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;

namespace SadegeRestApi
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            //config.SuppressDefaultHostAuthentication();
            //config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            
            config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
             new DateTimeConverter("dd/MM/yyyy HH:mm:ss"));
        }

    }
}

【讨论】:

    猜你喜欢
    • 2016-08-30
    • 2010-11-04
    • 2023-03-11
    • 2019-05-15
    • 2017-05-17
    • 2015-01-03
    • 2015-10-24
    • 2020-06-21
    • 1970-01-01
    相关资源
    最近更新 更多