2012-03-19 9 views
8

リストを含む複雑なJSONオブジェクトをバインドするためのASP.NET MVC3の取得に関する問題があります。MVC3コンプレックスJSONリストバインディング

私のオブジェクトの構造は次のとおりです。さらに別の構成されたクラスを複製する必要ので、私はあなたがあなたの想像を使用することができます理解:)

ここでPOST呼び出しを行うことJavascriptを/ jQueryの -

public class PageModel 
{ 
    public PageModel() { } 
    public CustomObject1 CustomObject { get; set; } 
    public IEnumerable<CustomObject2> Objects { get; set; } 

} 

public class CustomObject1 
{ 
    public CustomObject1() { } 
    [Required] 
    public int CustomId1 { get; set; } 
    public string CustomName { get; set; } 
} 

public class CustomObject2 
{ 
    public CustomObject2() { } 
    [Required] 
    public int Custom2Id { get; set; } 
    public CustomObject3 SubItem { get; set; } 
    public int SubItemId { get; set; } 
} 

あなたはCustomObject3を取ることができるが、同様の構造ではありません(すべてのJSはこれに至るまでが正しいデータを提供仮定):

//$obj1 has all data for the first object 
var firstObj = { }; 
firstObj.CustomId1 = $obj1.Id; 
firstObj.CustomName = $obj1.Name; 

var i = 0; 

//$objects is an array with all the data 
$.each($objects, function() { 
    objsArray[i] = { 
    Custom2Id: $(this).Id, 
    SubItemId: $(this).itemId 
    }; 

    ++i; 
}); 

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    data: { CustomObject: firstObj, Objects: objsArray }, 
    //Success/error handlers here 
}); 

そして最後に(私は、かなりいくつかのコードを知っている)、ここで私が持っている方法の概要です:

は、
public class ActionController : Controller { 
    public JsonResult Method(PageModel model) { 
     //Gets here - model.CustomObject is filled correctly, and model.Objects has a correct count of whatever data I passed to the method - but all of the properties are empty! 
    } 
} 

私が言ったように、最初のオブジェクトは満たされ、デバッグとステップスルーのときにすべてのデータがそこにあります。 JSONオブジェクト内のObjects配列内の2つのオブジェクトを渡すと、とSubItemIdは空ですが、Countは2です。何がありますか?

contentTypeがコールに'application/json'と指定された場合、MVCは渡されるデータについて不平を言います。また、MVCメソッドのmodelパラメータを2つの別々のパラメータに分割してみましたが、うまくいきません。

何か助けていただければ幸いです。

答えて

5

ので、この特定の問題を解決するには、SOに他の場所で見つかった二つ以上のソリューションを組み合わせたものです(そのうちの一つは、おそらくジェネリックコレクション型の使用を中心ヤクブの答えであること - IEnumerable - より具体的に対立するものとして1 - List)。

まず、サーバー側のコードを変更する必要はありません。すべてがそのフロントにあります。変更する必要があるのはすべてクライアント側であり、具体的にはjQueryとJavascriptがどのようにしてサーバーにデータを送信するのかです。

ここに古いのJavascriptです:ここ

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    data: { CustomObject: firstObj, Objects: objsArray }, 
    //Success/error handlers here 
}); 

まず問題はJavascriptが、それは、バイナリであることは、パラメータの組み合わせである、またはある(あなたが送っている正確に何'/Action/Method'でサーバーに通知されていないということですそれはJSONですか?)ので、contentType: 'application/json'行を追加するとその目的に役立ちます。これを行うと、サーバーはJSONをデコードする必要があることを知ります...

しかし、今のところデコードは失敗し、コードはメソッドに入る前に例外がスローされます( "Invalid JSON primitive") MVCはデコードとバインディングを処理します)。上記のAJAX呼び出しでは、$.ajaxオプションで新しいJSONオブジェクトを作成していましたが、送信されるJSONがJSONバリデータを渡しませんでした(James Kyburzは素晴らしいJSONバリデータ:JSONLint Validator)。代わりに、$.ajax呼び出しの前にJSONオブジェクトを作成し、オブジェクトを適切なJSON形式になるように文字列化します。 `IEnumerable`、` IList`、 `List`はすべて同じ結果を生成する - - そのオブジェクトの正しい数を持つリスト私はこれで周り果たしている

var dataObj = { CustomObject: firstObj, Objects: objsArray }; 

$.ajax({ 
    type: 'POST', 
    url: '/Action/Method', 
    contentType: 'application/json', 
    data: JSON.stringify(dataObj), 
    //Success/error handlers here 
}); 
+0

これは多くの助けてくれてありがとう! – Rookian

+0

完全に機能するコードを探し求めてから、これが私の問題を解決しました!ありがとう!! –

3

変更public IEnumerable<CustomObject2> Objects { get; set; }

List<CustomObject2>にモデルバインダーは IEnumerableインターフェースのインスタンスを作成する方法を知らない、それはより多くの何かコンクリートを必要とします。

はまた、これを変更する必要があります:

data: { CustomObject: firstObj, Objects: objsArray }

data: { model: { CustomObject: firstObj, Objects: objsArray } }

model一部は、あなたのアクションでパラメータの名前と一致します。

+0

:要するに、ここでのAJAX呼び出しがどのように見えるかです値はありません。 – Mattygabe

+0

私はあなたの2番目の部分に同意しません。MVC3は、特定のインスタンスで役立つかもしれませんが、渡すデータが自分の 'model'パラメータに属することを分かりやすく知ることができます。私が上で説明した実用的な解決策は、MVCを和らげる余分なオブジェクトレイヤーを指定していません - それは私が何をしているのかを識別することができます。 – Mattygabe

関連する問題