1

在 ASP.NET Web API 项目中,我有一个带有 TypeConverter 的自定义类型,用于处理字符串转换的 to 和 from,如下所述:

http://blogs.msdn.com/b/jmstall/archive/2012/04/20/how-to-bind-to-custom-objects-in-action-signatures-in-mvc-webapi.aspx

自定义类型在我的模型中用作属性,效果很好。我的模型对象的 json 包含我的自定义对象作为从我的 TypeConverter 创建的字符串值。

因此,我将请求切换为接受 XML,并且不再调用 TypeConverter,并且我的对象被错误地序列化。

如何让 XML 序列化程序像 JSON 一样使用 TypeConverter。引用的文章听起来像是 TypeConverters 的使用,如果存在的话,是一个可预测的功能。如果这完全是序列化程序的心血来潮,那么以一致的方式制作以 XML 和 JSON 表示数据的 API 几乎是不可能的。


文章中的示例代码,以及一些上下文:

[TypeConverter(typeof(LocationTypeConverter))]
public class Location
{        
    public int X { get; set; }
    public int Y { get; set; }

    // Parse a string into a Location object. "1,2" --> Loc(X=1,Y=2)
    public static Location TryParse(string input)
    {
        var parts = input.Split(',');
        if (parts.Length != 2)
        {
            return null;
        }

        int x,y;
        if (int.TryParse(parts[0], out x) && int.TryParse(parts[1], out y))
        {
            return new Location { X = x, Y = y };                
        }

        return null;
    }

    public override string ToString()
    {
        return string.Format("{0},{1}", X, Y);
    }
}

public class LocationTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, 
       System.Globalization.CultureInfo culture, object value)
    {
        if (value is string)
        {
            return Location.TryParse((string) value);
        }

        return base.ConvertFrom(context, culture, value);
    }
}

使用该类创建模型:

public class SampleModel
{
   public int One { get; set;}
   public string Two { get; set;}
   public Location Three { get; set;}
}

使用如下方法创建一个 ApiController:

public SampleModel Get()
{
   return new SapleModel { One = 1, Two = "Two", Three = new Location { X = 111, Y = 222 } };
}

而已。使用 fiddler 并同时尝试它们,并注意 Location 使用转换器将其序列化为单行逗号分隔格式,例如使用 Json 但不使用 XML 的单行逗号分隔格式 (Three="111,222")。

4

0 回答 0