2011-08-01 45 views
2

我正在嘗試爲ASP MVC3編寫Protobuf ValueProviderFactory。我已經設法解決了how to add the factories,但現在我偶然發現了一個更緊迫的問題。 這裏就是當前的序列發生在JsonValueProviderFactory.cs創建需要類型信息的MVC3 ValueProviderFactory?

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
    object jsonData = serializer.DeserializeObject(bodyText); 
    return jsonData; 

所以反序列化是沒有任何類型的信息來完成? DeserializeObject返回什麼樣的對象?動態?它如何知道數據的類型?我希望在這裏插入protobuf-net,但它顯然需要一種類型來實現它的魔力!

我沒有看過所有的MVC3源碼,但我猜測映射到類型發生在最後階段,並且沒有辦法知道ValueProviderFactories中的類型?

我必須放棄並在行動中進行轉換嗎?

+1

重新類型 - 請注意,它需要一個'Type'實例,但你不必使用通用API。這意味着如果你可以從'ParameterInfo'之類的東西推斷'Type',它應該是可能的。 –

回答

2

這裏有幾個問題。

如何使用JavaScriptSerializer您應該閱讀documentation。該類嘗試推斷基本類型(int,bool,date等)的類型,併爲更復雜的情況返回Dictionary<string, object>。另外,如果JSON blob包含一個名爲「__type」的特殊屬性,那麼解串器將嘗試創建該類型的對象。

現在該如何在MVC中工作。將請求中的值映射到控制器中使用的對象實例的過程稱爲模型綁定。這分成兩個組件:ModelBinder和ValueProviders。模型聯編程序知道目標類型(例如Product),嘗試創建它的實例,然後使用請求中的值填充其屬性。它通過詢問ValueProviders來做到這一點。例如,要在Product實例上設置Name屬性,它會向Value Provider詢問「Name」的值。值提供程序按順序查詢並返回匹配項(從查詢字符串,發佈數據,JSON請求主體等)。

網絡上有很多這方面的資源,但在短期內,提供商不應該真正關心類型。

+0

出於某種原因,我打折ModelBinders,但他們更有意義... – Tim

1

這是一個使用ModelBinder的解決方案,如marcind所示。它沒有經過測試,但這是一個開始。在這種情況下,FromProtobuf<T>是對象擴展方法的簡單byte[]

public class ProtobufModelBinder<T> : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/x-protobuf", StringComparison.OrdinalIgnoreCase)) 
      return null; 

     using (MemoryStream ms = new MemoryStream()) 
     { 
      controllerContext.HttpContext.Request.InputStream.CopyTo(ms); 
      return ms.ToArray().FromProtobuf<T>(); 
     } 
    } 
} 

這可能是設置如下:

ModelBinders.Binders.Add(typeof(MyClass), new ProtobufModelBinder<MyClass>());