2012-12-08 111 views
10

我想發佈一個JSON數組到MVC控制器。但不管我嘗試什麼,一切都是0或者爲空。發佈JSON數組到mvc控制器

我有這張包含文本框的表。我需要從所有這些文本框中將它作爲對象的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> 

這是控制器即時通訊試圖接收數據:

[HttpPost] 
public ActionResult Update(CustomTypeModel ctm) 
{ 


    return RedirectToAction("Index"); 
} 

什麼時我做錯了?

+1

請說明你的'CustomTypeModel'的樣子。 –

+0

您正在使用哪個版本的mvc? –

+0

好像你可能會缺少'name'屬性和你想要POST的屬性的名字。你能發佈你發佈的實際數據嗎?實際的POST請求? – rae1

回答

50

你的代碼有很多問題。讓我們從標記開始。你有一張桌子,裏面的每一行裏面都有隱藏的字段。除此之外,您已對這些隱藏元素的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> 
} 

好了,現在你有有效的標記。現在讓我們繼續討論javascript事件,點擊一些submitTest按鈕後會觸發這個事件。如果這是表單的提交按鈕,我建議您訂閱表單的.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反序列化。

+0

我正在測試你的代碼。 – Yustme

+4

我見過的最佳答案之一。不是因爲複雜性,而是因爲能夠通過答案走向人,並向他們展示如何正確地做某件事。 –

-1

我覺得你對MVC世界的做法有點不對勁。 如果你有一個合適的模型來綁定你的數據 - 你最好使用助手從框中而不是使用「手工製作」的JavaScript。如果您需要異步調用,請查看HtmlHelper或AjaxHelper。

並將您的數據綁定到使用@Html.TextBoxFor()@Html.BeginForm塊內的表示法這將簡化您的代碼並減少javascript的數量,這對維護更好。

在服務器部件上,您需要實現自定義模型聯編程序並更改設置,以便通過模型聯編程序爲當前控制器操作提出處理請求。它會讓你編寫一些服務器端代碼,但靜態類型代碼看起來更容易編碼和測試,而且它更適合你的應用程序需要,因爲我更喜歡JavaScript做它應該做的事情=>管理UI,但不構建模型在服務器端正確解析。它更適合單一職責原則。

看到這個video,這是簡單的教程如何做到這一點

+0

它是一個複雜的類型。不能這樣綁定,至少我還沒有想出如何。 javascript現在適用於我。但是對於記錄來說,沒有關於InputFor的@ Html.InputFor() – Yustme

+0

Thx,我上次編碼java並且很難正確記住所有名稱。我編輯我的答案,你可以看看它。 – Ph0en1x

+0

聽起來不錯,但我已經嘗試了很多東西來避免JavaScript。這是一個複雜的模型。另外,我確實使用了@ Html.TextBoxFor(),但我不知道如何使用javascript從數據中獲取數據。 – Yustme

6

還有一種更簡單的方法:使用查詢字符串來發送數據。如果您感興趣, 您目前的方法是錯誤的,因爲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: '/controller/action?json=' + JSON.stringify(trans) 
+1

爲我工作。謝謝 –

相關問題