2012-04-25 59 views
0

我使用的Web API有一個請求端點:網頁API JSON序列化失敗

public HttpResponseMessage Create(IList<SlideContent> l) 
    { 
     ... 
    } 

我送參數作爲JSON和Web API將其序列化爲IList的

SlideContent是:

public abstract class SlideItem 
    { 
     ... 
    } 

和我有專門的課

public class TitleSlideItem : SlideItem 
    { 
     ... 
    } 


    public class ParagraphSlideItem : SlideItem 
    { 
     ... 
    } 

只是想,我不能調用Create函數,因爲我得到一個

missingmethodexception:無法創建抽象類

,所以我不能反序列化JSON的參數。如果我刪除抽象修飾符,那麼我沒有專門的對象,每個對象的類型將是SlideContent。 我甚至把註釋放在json中,但它也沒有幫助。

如果我沒有錯,我將不得不爲自己的抽象類寫一個自定義綁定,但我該怎麼做?

此致

佐利

回答

1

一種可能性是代替內置的JSON序列與如圖中following blog post使用JSON.NET自定義格式。

public class JsonNetFormatter : MediaTypeFormatter 
{ 
    private JsonSerializerSettings _jsonSerializerSettings; 

    public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings) 
    { 
     _jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings(); 

     // Fill out the mediatype and encoding we support 
     SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); 
     Encoding = new UTF8Encoding(false, true); 
    } 

    protected override bool CanReadType(Type type) 
    { 
     if (type == typeof(IKeyValueModel)) 
     { 
      return false; 
     } 

     return true; 
    } 

    protected override bool CanWriteType(Type type) 
    { 
     return true; 
    } 

    protected override Task<object> OnReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext) 
    { 
     // Create a serializer 
     JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings); 

     // Create task reading the content 
     return Task.Factory.StartNew(() => 
     { 
      using (StreamReader streamReader = new StreamReader(stream, Encoding)) 
      { 
       using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader)) 
       { 
        return serializer.Deserialize(jsonTextReader, type); 
       } 
      } 
     }); 
    } 

    protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext, TransportContext transportContext) 
    { 
     // Create a serializer 
     JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings); 

     // Create task writing the serialized content 
     return Task.Factory.StartNew(() => 
     { 
      using (JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(stream, Encoding)) { CloseOutput = false }) 
      { 
       serializer.Serialize(jsonTextWriter, value); 
       jsonTextWriter.Flush(); 
      } 
     }); 
    } 
} 

然後在Application_Start註冊格式化時,你可以配置串行的JSON使用類型的信息:

var formatters = GlobalConfiguration.Configuration.Formatters; 
formatters.Remove(formatters.XmlFormatter); 
formatters.Remove(formatters.JsonFormatter); 

var serializerSettings = new JsonSerializerSettings(); 
serializerSettings.TypeNameHandling = TypeNameHandling.Objects; 
serializerSettings.Converters.Add(new IsoDateTimeConverter()); 
formatters.Add(new JsonNetFormatter(serializerSettings)); 

,然後你可以發佈以下JSON:

[ 
    { 
     "$type":"AppName.Models.TitleSlideItem, AppName", 
     "Id":1, 
     "Title":"some title" // this is a specific property of the TitleSlideItemclass 
    }, 
    { 
     "$type":"AppName.Models.ParagraphSlideItem, AppName", 
     "Id":2, 
     "Paragraph":"some paragraph" // this is a specific property of the ParagraphSlideItem class 
    } 
] 

它將在這個動作內部成功反序列化:

public HttpResponseMessage Post(IList<SlideItem> l) 
{ 
    ... 
} 
+0

謝謝你,但我想用自定義粘結劑來做。 – 2012-04-25 12:20:37