2011-08-01 2 views
2

ASP MVC3用のProtobuf ValueProviderFactoryを作成しようとしています。私はhow to add the factoriesを解決することができましたが、今はもっと緊急の問題に遭遇しました。現在の直列化は、デシリアライゼーションは、あらゆる種類の情報なしに達成されるのでタイプ情報が必要なMVC3 ValueProviderFactoriesの作成

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

JsonValueProviderFactory.csで行われる場所。ここ はありますか?どのような種類のオブジェクトDeserializeObjectが返されますか?ダイナミック?データの種類をどのように知っていますか?私はここにprotobuf-netを挿入することを望んでいましたが、明らかにその魔法を行うタイプが必要です!

私はすべてのMVC3ソースを調べていませんが、タイプへのマッピングは最終段階で行われていると思いますが、ValueProviderFactoriesの型を知る方法はありませんか?

私はアクションで変換をやめなければなりませんか?

+1

再タイプが - それは 'type'がインスタンスを必要としていることに注意していますが、一般的なAPIを使用する必要はありません。これは、 'ParameterInfo'のようなものから' Type'を推論することができれば可能であることを意味します。 –

答えて

2

ここにはいくつか質問があります。

JavaScriptSerializerの仕組みについては、documentationをお読みください。クラスは、基本型(int、bool、dateなど)の型を推測しようとし、より複雑な場合はDictionary<string, object>を返します。さらに、JSONブロブに "__type"という特別なプロパティが含まれている場合、デシリアライザはそのタイプのオブジェクトの作成を試みます。

これはMVCでどのように動作するかを示しています。要求からコントローラに使用されているオブジェクトインスタンスに値をマッピングするプロセスは、モデルバインディングと呼ばれます。これは、ModelBinderとValueProvidersの2つのコンポーネントに分割されています。モデルバインダーはターゲットタイプ(Productなど)を認識し、そのインスタンスを作成しようとし、そのプロパティに要求の値を入力しようとします。それはValueProvidersに尋ねることによってそうする。たとえば、ProductインスタンスのNameプロパティを設定するには、値プロバイダに "Name"の値を問い合わせます。値プロバイダは順番に照会され、照会文字列、投稿データ、JSONリクエストボディなどから一致を返します。

ウェブ上でこれに関する多くの情報がありますが、短期的なプロバイダでは実際にタイプに関係するべきではありません。

+0

何らかの理由で私はModelBindersを割り引いたが、もっと意味をなさない... – Tim

1

ここでは、Marcindの示唆しているように、ModelBinderを使用するソリューションでの簡単なスタブです。それはテストされていませんが、それはスタートです。この場合、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>()); 
関連する問題