JSON配列をMVCコントローラーに投稿しようとしています。しかし、何を試しても、すべてが0またはnullです。
テキストボックスを含むこのテーブルがあります。これらすべてのテキストボックスから、オブジェクトとしてのIDと値が必要です。
これは私のJavaScriptです:
$(document).ready(function () {
$('#submitTest').click(function (e) {
var $form = $('form');
var trans = new Array();
var parameters = {
TransIDs: $("#TransID").val(),
ItemIDs: $("#ItemID").val(),
TypeIDs: $("#TypeID").val(),
};
trans.Push(parameters);
if ($form.valid()) {
$.ajax(
{
url: $form.attr('action'),
type: $form.attr('method'),
data: JSON.stringify(parameters),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (result) {
$('#result').text(result.redirectTo)
if (result.Success == true) {
return fase;
}
else {
$('#Error').html(result.Html);
}
},
error: function (request) { alert(request.statusText) }
});
}
e.preventDefault();
return false;
});
});
これは私のビューコードです:
<table>
<tr>
<th>trans</th>
<th>Item</th>
<th>Type</th>
</tr>
@foreach (var t in Model.Types.ToList())
{
{
<tr>
<td>
<input type="hidden" value="@t.TransID" id="TransID" />
<input type="hidden" value="@t.ItemID" id="ItemID" />
<input type="hidden" value="@t.TypeID" id="TypeID" />
</td>
</tr>
}
}
</table>
これは、データを受信しようとするコントローラーimです。
[HttpPost]
public ActionResult Update(CustomTypeModel ctm)
{
return RedirectToAction("Index");
}
何が悪いのですか?
コードには多くの問題があります。マークアップから始めましょう。テーブルがあり、このテーブルの各行内に非表示フィールドが含まれています。ただし、これらの非表示要素のid
属性をハードコードした場合を除き、マークアップ内に同じIDを持つ複数の要素が存在する可能性があり、無効なマークアップが発生する可能性があります。
まず、マークアップを修正するところから始めましょう。
@foreach (var t in Model.Types.ToList())
{
<tr>
<td>
<input type="hidden" value="@t.TransID" name="TransID" />
<input type="hidden" value="@t.ItemID" name="ItemID" />
<input type="hidden" value="@t.TypeID" name="TypeID" />
</td>
</tr>
}
さて、今あなたは有効なマークアップを持っています。次に、submitTest
ボタンがクリックされたときにトリガーされるjavascriptイベントに移りましょう。これがフォームの送信ボタンである場合、フォームの送信ボタンの.submit
イベントではなく、フォームの.click
イベントにサブスクライブすることをお勧めします。これは、たとえば、フォーカスが入力フィールド内にあるときにユーザーがEnterキーを押すと、フォームが送信される可能性があるためです。この場合、クリックイベントはトリガーされません。
そう:
$(document).ready(function () {
$('form').submit(function () {
// code to follow
return false;
});
});
次は、テーブル内にある非表示要素の値を取得し、それらをjavascriptオブジェクトに入れて、JSONシリアル化してAJAXの一部として送信する必要があります。 =サーバーへのリクエスト。
先に進みましょう:
var parameters = [];
// TODO: maybe you want to assign an unique id to your table element
$('table tr').each(function() {
var td = $('td', this);
parameters.Push({
transId: $('input[name="TransID"]', td).val(),
itemId: $('input[name="ItemID"]', td).val(),
typeId: $('input[name="TypeID"]', td).val()
});
});
これまでにパラメーターを入力したので、今度はそれらをサーバーに送信します。
$.ajax({
url: this.action,
type: this.method,
data: JSON.stringify(parameters),
contentType: 'application/json; charset=utf-8',
success: function (result) {
// ...
},
error: function (request) {
// ...
}
});
それでは、サーバー側に移りましょう。いつものように、ビューモデルを定義することから始めます。
public class MyViewModel
{
public string TransID { get; set; }
public string ItemID { get; set; }
public string TypeID { get; set; }
}
そして、このモデルのコレクションを取得するコントローラーアクション:
[HttpPost]
public ActionResult Update(IList<MyViewModel> model)
{
...
}
そして、これが最終的なクライアントサイドコードです:
$(function() {
$('form').submit(function () {
if ($(this).valid()) {
var parameters = [];
// TODO: maybe you want to assign an unique id to your table element
$('table tr').each(function() {
var td = $('td', this);
parameters.Push({
transId: $('input[name="TransID"]', td).val(),
itemId: $('input[name="ItemID"]', td).val(),
typeId: $('input[name="TypeID"]', td).val()
});
});
$.ajax({
url: this.action,
type: this.method,
data: JSON.stringify(parameters),
contentType: 'application/json; charset=utf-8',
success: function (result) {
// ...
},
error: function (request) {
// ...
}
});
}
return false;
});
});
明らかに、ビューモデルが異なる場合(質問でそれを示していない場合)、構造に一致するようにコードを調整する必要がある場合があります。そうでない場合、デフォルトのモデルバインダーはJSONを逆シリアル化できません。
別の簡単な方法があります。クエリ文字列を使用してデータを送信します。 JSON配列のデータ型がstring
ではなくCustomTypeModel
であるため、興味をそそられた場合、現在のアプローチは正しくありません。
まず、data
ajaxオプションを削除します。それはもう必要ありません。
次に、コントローラーを次のように変更します。
[HttpPost]
public ActionResult Update(string json)
{
// this line convert the json to a list of your type, exactly what you want.
IList<CustomTypeModel> ctm =
new JavaScriptSerializer().Deserialize<IList<CustomTypeModel>>(json);
return RedirectToAction("Index");
}
注1:CustomTypeModel
プロパティの名前は、JSON要素として入力する名前と同じであることが重要です。したがって、CustomTypeModel
は次のようになります。
public class CustomTypeModel
{
// int, or maybe string ... whatever you want.
public int TransIDs { get; set; }
public int ItemIDs { get; set; }
public int TypeIDs { get; set; }
}
注2:この方法は、クエリ文字列を使用してデータを送信する場合に便利です。したがって、URLは次のようになります。
url: '/controller/action?json=' + JSON.stringify(trans)