首页 > 解决方案 > 可空时自动解析自定义结构

问题描述

我有一个自定义结构,如下所示:

public struct Date
{
    private int _year;
    private int _month;
    private int _day;
    public Date(string myDate)
    {
        var date = DateTime.ParseExact(myDate, "yyyy-MM-dd");
        _year = date.Year;
        _month = date.Month;
        _day = date.Day;
    }
    public int Year => _year;
    public int Month => _month;
    public int Day => _day;
}

这是一个可以发布到我的 webApi 的模型,如下所示:

public class MyData
{
    public int? MyIntValue {get;set;}
    public string MyStringValue {get;set;}
    public Date? MyDateValue {get;set;}
}

其中不可为空的类型可以为空,因为它们对于此消息是可选的。

给出如下所示的消息,发布到我的 webApi

{
    "MyIntValue": 5,
    "MyStringValue": "Hello",
    "MyDateValue": "2019-03-29"
}

我希望能够获取该字符串,并将其解析到我的Date结构中。

我的第一个停靠点是TypeConverter装饰我的Date结构所以我编写了一个DateConverter如下所示的转换器。

public class DateConverter : TypeConverter
{
    public override bool CanConverterFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string stringValue)
        {
            return new Date(stringValue);
        }
        return base.ConvertFrom(context, culture, value);
    }
}

Date[TypeConverter(typeof(DateConverter))]

然而这不起作用。经过一些(漫长的)调查,我相信这是因为模型上的类型实际上是Nullable<T>. 因此,经过更多挖掘后,我发现了一个NullableConverter. 对我的修改TypeConverter使它现在看起来像这样

public class DateConverter : NullableConverter
{
    public DateConverter() : base(typeof(Date?)) {}

    public override bool CanConverterFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string stringValue)
        {
            return new Date(stringValue);
        }
        return base.ConvertFrom(context, culture, value);
    }
}

我现在看到DateConverter构造函数在发布消息时被击中(耶!),但是我陷入了一个导致 a 的循环,StackOverflowException因为我相信当NullableConverter在其构造函数中给出一个 Nullable 类型时,它会查看底层类型并解析它的 TypeConverter,如果有的话,并以这种方式继续。正如我NullableConverterDate结构上设置的那样,它不断地解决DateConverter并四处走动......

这是我的调查停止的地方。我可以找到关于NullableConverter现在的宝贵信息或它作为TypeConverter装饰类型的任何实际用途,我确信这是我需要使用的类。

我做错什么了吗?我是不是很接近但还没有完全超越驼峰......或者我在看这个完全错误的方面。

我的问题是这样的:

如何将给定的 Json 放入我的 WebAPI 中,并在其中MyDateValue正确解析为我的自定义类型

注意模型是生成的代码,因此我不想在我的模型上装饰成员(如果这甚至可以工作,我还没有尝试过)。但是,如果这是唯一可行的方法,我将向我身边的相关方提出这个改变,看看有什么吸收。

进一步的调查表明,如果我恢复到我以前的TypeConverter(Not NullableConverter) thenCanConvertFrom被调用,并返回 true,但ConvertFrom随后不会被调用。然后它似乎也不再打电话CanConvertFrom了。也许 Asp.Net 在内部缓存了该类型的结果。

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

解决方案


推荐阅读