2011-01-03 8 views
5

ASP.Net MVC3(RC2)に問題があります。私はMVC3で暗黙の新しいJSONモデルのバインディング機能は、列挙型を持つプロパティにdeserializeしたくないことがわかりました。ASP.Net MVC3 - JSONモデルバインディングのデフォルトサポートが列挙型にデコードできないのはなぜですか?

ここではサンプルクラスと列挙タイプです:

public enum MyEnum { Nothing = 0, SomeValue = 5 } 
public class MyClass 
{ 
    public MyEnum Value { get; set; } 
    public string OtherValue { get; set; } 
} 

成功し、ユニットテストに合格し、次のコード、考えてみましょう:私は上記のobj1をシリアル化した場合

[TestMethod] 
public void Test() 
{ 
    var jss = new JavaScriptSerializer(); 
    var obj1 = new MyClass { Value = MyEnum.SomeValue }; 
    var json = jss.Serialize(obj1); 
    var obj2 = jss.Deserialize<MyClass>(json); 
    Assert.AreEqual(obj1.Value, obj2.Value); 
} 

を、その後のデータにすることを投稿MyClass型の単一のパラメータを持つMVC3コントローラ(以下の例)では、オブジェクトの他のプロパティはすべて正しくデシリアライズされますが、enum型のプロパティはデフォルト(ゼロ)の値にデシリアライズされます。

[HttpPost] 
public ActionResult TestAction(MyClass data) 
{ 
    return Content(data.Value.ToString()); // displays "Nothing" 
} 

私はCodePlexのからMVCのソースコードをダウンロードしましたが、私は、私はMicrosoftの人々が実行するために使用しているものをうまくできないことを意味しており、直列化復元を実行する実際のコードが発生する場所へと困惑デシリアライゼーションを行い、私が何か間違っているのか、回避策があるのか​​を判断します。

何か提案がありがとうございます。

+0

私はこのスレッドで役立つかもしれない答えを追加しました。 http://stackoverflow.com/questions/6051756/model-binding-to-enums-in-asp-net-mvc-3/9070963#9070963 – Difinity

答えて

9

回答が見つかりました。私はこれがMVC3 RTMで修正されることを願っていますが、本質的に何が起きるのかは、JsonValueProviderFactoryによって正しく内部的に逆シリアル化されます。JavaScriptSerializerを使用して作業を行います。これは、DeserializeObject()を使用して、値をデフォルトのモデルバインダーに戻すことができます。問題は、プロパティ型が列挙型の場合、デフォルトのモデルバインダーはint値を変換/割り当てしないことです。

ASP.Netフォーラムでこの議論がここにあります:
http://forums.asp.net/p/1622895/4180989.aspx

ソリューションはそうのようなデフォルトのモデルバインダーオーバーライドすることがあり議論:、Application_Startに続いて

public class EnumConverterModelBinder : DefaultModelBinder 
{ 
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 
    { 
     var propertyType = propertyDescriptor.PropertyType; 
     if(propertyType.IsEnum) 
     { 
      var providerValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
      if(null != providerValue) 
      { 
       var value = providerValue.RawValue; 
       if(null != value) 
       { 
        var valueType = value.GetType(); 
        if(!valueType.IsEnum) 
        { 
         return Enum.ToObject(propertyType, value); 
        } 
       } 
      } 
     } 
     return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); 
    } 
} 

を次の行を追加してください:

ModelBinders.Binders.DefaultBinder = new EnumConverterModelBinder(); 
+0

この問題はASP.NET MVCの次のリリースで修正される予定です。 – marcind

0

この行動をどのように呼びますか?試してみましたか:

$.post(
    '/TestAction', 
    JSON.stringify({ OtherValue : 'foo', Value: 5 }), 
    function(result) { 
     alert('ok'); 
    } 
); 
+0

私はウェブページから呼び出すことはありません。 'WebClient.UploadString()'を介して別のアプリケーションから呼び出しています。ポストプロセスは実際には機能しますが、逆シリアル化しないクラスのenumプロパティです。他のすべてのプロパティはうまくいきます。 –

+0

@Nathan、呼び出しコードを表示してもらえますか? –

+0

私はこの問題を発見しました。 DefaultModelBinderクラスはintをEnumに変換しません。 http://forums.asp.net/p/1622895/4180989.aspx –

関連する問題