Passing DateTimeOffset as WebAPI query string

前端 未结 8 601
感动是毒
感动是毒 2020-12-11 15:49

I\'ve got a WebAPI action that looks like so:

[Route(\"api/values/{id}\")]
public async Task Delete(string id, DateTimeOffset date         


        
8条回答
  •  -上瘾入骨i
    2020-12-11 16:29

    Create a custom type converter as follows:

    public class DateTimeOffsetConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
    
            return base.CanConvertFrom(context, sourceType);
        }
    
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(DateTimeOffset))
                return true;
    
            return base.CanConvertTo(context, destinationType);
        }
    
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            var s = value as string;
    
            if (s != null)
            {
                if (s.EndsWith("Z", StringComparison.OrdinalIgnoreCase))
                {
                    s = s.Substring(0, s.Length - 1) + "+0000";
                }
    
                DateTimeOffset result;
                if (DateTimeOffset.TryParseExact(s, "yyyyMMdd'T'HHmmss.FFFFFFFzzz", CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
                {
                    return result;
                }
            }
    
            return base.ConvertFrom(context, culture, value);
        }
    

    In your startup sequence, such as WebApiConfig.Register, add this type converter dynamically to the DateTimeOffset struct:

    TypeDescriptor.AddAttributes(typeof(DateTimeOffset),
                                 new TypeConverterAttribute(typeof(DateTimeOffsetConverter)));
    

    You can now just pass DateTimeOffset values in the compact form of ISO8601, which omits hyphens and colons that interfere with the URL:

    api/values/20171231T012345-0530
    api/values/20171231T012345+0000
    api/values/20171231T012345Z
    

    Note that if you have fractional seconds, you may need to include a trailing slash in the url.

    api/values/20171231T012345.1234567-0530/
    

    You could also put it in the querystring if you like:

    api/values?foo=20171231T012345-0530
    

提交回复
热议问题