c# - Web API - 如何在 Controller DateTime ('dd/MM/yyyy' 中接收作为 Url 参数?

标签 c# datetime asp.net-web-api url-parameters

每当我的 Controller 收到一个日期为 dd/MM/yyyy 时,它就会解码为 MM/dd/yyyy。是否可以告诉 Controller 如何解码url的参数?

我在 Controller 中的方法:

[HttpGet]
public JsonResult<IList<Callers>> GetListOfCallers(DateTime startDate, DateTime endDate)
        {
            // myCode....
        }

我的javascript:

var $startDate = $('#startDate').val();
var $endDate = $('#endDate').val();

$.get(rootUrl + "api/report/GetListOfCallers?startDate=" + $startDate + "&endDate=" + $endDate, function (data) {
                // myCode....
            });

我知道我可以在 Controller 中接收日期作为字符串,然后解析它,或者在我的 javascript 中将它更改为 ISO8601,然后再输入 url,但我想知道我是否可以告诉我的 Controller 如何解码接收到的参数.

编辑:我使用的是 MVC Controller ,这不是问题,在我更改为 ApiController 后它开始解码不正确,所以代码可以正常工作,我希望保持原样。

最佳答案

我按照@Jakotheshadows 和@Amy 的建议使用模型绑定(bind)设法解决了我的问题。

我使用了 this answer 中的代码关于 Web Api 中的 ModelBinders 以及来自 this answer 的一些调整(它是葡萄牙语,但代码很清楚)。

所以我现在的代码:

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

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

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

            var modelName = bindingContext.ModelName;
            var attemptedValue = bindingContext.ValueProvider
                .GetValue(modelName).AttemptedValue;

            try
            {
                bindingContext.Model = DateTime.Parse(attemptedValue);
            }
            catch (FormatException e)
            {
                bindingContext.ModelState.AddModelError(modelName, e);
            }

            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?);
        }
    }
}

我按照第二个链接中的建议使用了 tryDateTime.Parse,因为即使使用 try 和 catch,第一个总是抛出异常。

我按照他的建议使用的ModelBinderProvider:

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

namespace Site.Services
{
    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;
        }
    }
}

然后我按照建议进行配置here (也是第一个链接的答案),但在我的 WebApiConfig.cs 中(在 Global.asax 中不起作用),像这样:

using Site.Services;
using System;
using System.Web.Http;

namespace Site
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.BindParameter(typeof(DateTime), new DateTimeModelBinder());
            config.BindParameter(typeof(DateTime?), new DateTimeModelBinder());

            //Rest of my code
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

我认为 Web.configuiCulturecultureglobalization 必须设置为你想要的文化和 enableClientBasedCulture 被设置为 true 作为建议 here , 但我不确定,因为我不想更改代码来测试它。

关于c# - Web API - 如何在 Controller DateTime ('dd/MM/yyyy' 中接收作为 Url 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46083357/

相关文章:

c# - 转换时拆分 DateTime 字符串

python - 根据一周的标记分区拆分日期时间间隔

c# - 请求的资源不支持 HTTP 方法 GET

c# - MySql 和 SQlite 类实现接口(interface)

unix - UNIX 时间是否通用

c# - LINQ查询优化: specifically, let子句的位置重要吗?

c# - WebAPI 2 OData - 没有 '~/entityset/key/$links/navigation' 的路由约定

c# - 在 AngularJS $http 中传递日期到 ASP.NET Web Api

c# - 在字符串中使用二进制数据时数据是 "lost"吗?

c# - 无法从 chrome 设置默认下载目录