• 【AspNetCore】【WebApi】扩展Webapi中的RouteConstraint中,让DateTime类型,支持时间格式化(DateTimeFormat)


    扩展Webapi中的RouteConstraint中,让DateTime类型,支持时间格式化(DateTimeFormat)

    一、背景

    大家在使用WebApi时,会用到DateTime为参数,类似于这样:

    //url: xxx/2016-09-08
    [HttpGet("{date:datetime}")]
    public string Get(DateTime date)
    {
        return date.ToString("yyyyMMdd");
    }
    

    但是":datetime" 支持这样的格式:

    12/25/2009
    11:45:00 PM
    11:45:00
    11:45
    Apr 5 2009 11:45:00 PM
    April 5 2009 11:45:00 PM
    12/25/2009 11:45:00 PM
    11:45:00 PM
    2009-05-12T11:45:00Z
    

    但我们有的时候想要的是类似这样的格式:

    20091225
    091225
    12252009
    

    或是各种自定义的时间格式。

    二、目的

    用简单的办法来自定义这个时间格式。比如正则":regex"是支持参数的,我们让默认的":datetime"来支持一个参数。 比如":datetime(yyyyMMdd)"

    三、实现

    要做一个自定义的 RouteConstraint ,我们要实现一个接口 IRouteConstraint


    但我们可以偷个懒,我们找到DateTimeRouteConstraint的源码,做一些修改。

    Routing 源码地址 :https://github.com/aspnet/Routing

    找到 Routing/src/Microsoft.AspNetCore.Routing/Constraints/DateTimeRouteConstraint.cs

    源码:

    public class DateTimeRouteConstraint : IRouteConstraint
    {
        /// <inheritdoc />
        public bool Match(
            HttpContext httpContext,
            IRouter route,
            string routeKey,
            RouteValueDictionary values,
            RouteDirection routeDirection)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }
            if (route == null)
            {
                throw new ArgumentNullException(nameof(route));
            }
            if (routeKey == null)
            {
                throw new ArgumentNullException(nameof(routeKey));
            }
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }
            object value;
            if (values.TryGetValue(routeKey, out value) && value != null)
            {
                if (value is DateTime)
                {
                    return true;
                }
                DateTime result;
                var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
                return DateTime.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
            }
            return false;
        }
    }
    

    我们来对这个做一点修改。给他增加两个构造函数。

    一个有一个string参数,用来接受DateTimeFormat。
    一个无参数的,用来兼容默认无参的情况。
    

    别的不多说了,直接上代码。

    DateTimeExRouteConstraint.cs

    public class DateTimeExRouteConstraint : IRouteConstraint
    {
        private readonly string _dateTimeformat;
        public DateTimeExRouteConstraint(string p_dateTimeformat)
        {
            _dateTimeformat = p_dateTimeformat;
        }
        public DateTimeExRouteConstraint()
        {
        }
        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }
            if (route == null)
            {
                throw new ArgumentNullException(nameof(route));
            }
            if (routeKey == null)
            {
                throw new ArgumentNullException(nameof(routeKey));
            }
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }
            object value;
            if (values.TryGetValue(routeKey, out value) && value != null)
            {
                if (value is DateTime)
                {
                    return true;
                }
                DateTime result;
                var valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
                if (!string.IsNullOrEmpty(_dateTimeformat))
                {
                    var success = DateTime.TryParseExact(valueString, _dateTimeformat, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
                    if (success)
                    {
                        values[routeKey] = result;
                    }
                    return success;
                }
                return DateTime.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
            }
            return false;
        }
    }
    

    然后我们用这个新的 DateTimeExRouteConstraint 来替换默认的 RouteConstraint

    找到 Startup.csConfigureServices 方法,添加

    services.Configure<RouteOptions>(options => options.ConstraintMap["datetime"] = typeof(DateTimeExRouteConstraint));
    

    四、使用

    实现以后,我们就可以愉快的使用的DateTimeFormat 的方式了。


    比如这样

    //url: xxx/20160908
    [HttpGet("{date:datetime(yyyyMMdd)}")]
    public string Get(DateTime date)
    {
        return date.ToString();
    }
    

    或者这样

    //url: xxx/160908
    [HttpGet("{date:datetime(yyMMdd)}")]
    public string Get(DateTime date)
    {
        return date.ToString();
    }
    

    再或者这样

    //url: xxx/09082016
    [HttpGet("{date:datetime(MMddyyyy)}")]
    public string Get(DateTime date)
    {
        return date.ToString();
    }
    

    全看你喜欢了。

    本文地址:
    http://www.cnblogs.com/gaoshang212/p/5855931.html

  • 相关阅读:
    wgcloud问题处理——被监控的客户机掉线
    WGCLOUD下发指令时候如何屏蔽linux敏感字符
    WGCLOUD左侧菜单如何保持展开状态
    zerotier 实现 minecraft 局域网联机 | 我的世界联机教程 | minecraft联机
    [ UVa 12096 详解] The Set Stack Computer 集合栈计算机 | map、set、vector、stack、宏函数等知识点简单应用
    [ Uva 101 详解 ] the block problem 木块问题
    Python操作数据库基本操作-sqlalchemy
    统计目录下程序源程序的行数之和-Python
    凯撒密码C++实现
    【题解】[AGC036F] Square Constraints
  • 原文地址:https://www.cnblogs.com/gaoshang212/p/5855931.html
Copyright © 2020-2023  润新知