1

ASP.NET Web APIプロジェクトには、次のように、文字列変換のtoとfromを処理するTypeConverterを備えたカスタムタイプがあります。

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

それでおしまい。フィドラーを使用して両方を試してみてください。Locationは、コンバーターを使用して、XMLではなくJsonでこのような1行のコンマ区切り形式(Three = "111,222")にシリアル化することに注意してください。

4

0 に答える 0