2008-11-26 31 views
88

Mã hiện tại của tôi trông giống như sau. Làm thế nào tôi có thể vượt qua mảng của tôi để điều khiển và những loại thông số phải hành động điều khiển của tôi chấp nhận?Làm thế nào để đăng một mảng các đối tượng phức tạp với JSON, jQuery đến ASP.NET MVC Controller?

function getplaceholders() { 
    var placeholders = $('.ui-sortable'); 
    var result = new Array(); 
    placeholders.each(function() { 
     var ph = $(this).attr('id'); 
     var sections = $(this).find('.sort'); 
     var section; 

     sections.each(function(i, item) { 
      var sid = $(item).attr('id'); 

      result.push({ 'SectionId': sid, 'Placeholder': ph, 'Position': i }); 
     }); 
    }); 
    alert(result.toString()); 
    $.post(
     '/portal/Designer.mvc/SaveOrUpdate', 
     result, 
     function(data) { 
      alert(data.Result); 
     }, "json"); 
}; 

phương pháp hành động điều khiển của tôi trông giống như

public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets) 

Trả lời

83

Tôi đã tìm thấy một giải pháp. Tôi sử dụng một dung dịch . Steve Gentile, jQuery and ASP.NET MVC – sending JSON to an Action – Revisited

My ASP.NET MVC xem mã trông giống như:

function getplaceholders() { 
     var placeholders = $('.ui-sortable'); 
     var results = new Array(); 
     placeholders.each(function() { 
      var ph = $(this).attr('id'); 
      var sections = $(this).find('.sort'); 
      var section; 

      sections.each(function(i, item) { 
       var sid = $(item).attr('id'); 
       var o = { 'SectionId': sid, 'Placeholder': ph, 'Position': i }; 
       results.push(o); 
      }); 
     }); 
     var postData = { widgets: results }; 
     var widgets = results; 
     $.ajax({ 
      url: '/portal/Designer.mvc/SaveOrUpdate', 
      type: 'POST', 
      dataType: 'json', 
      data: $.toJSON(widgets), 
      contentType: 'application/json; charset=utf-8', 
      success: function(result) { 
       alert(result.Result); 
      } 
     }); 
    }; 

và điều khiển của tôi hành động được trang trí với một attri tùy chỉnh bute

[JsonFilter(Param = "widgets", JsonDataType = typeof(List<PageDesignWidget>))] 
public JsonResult SaveOrUpdate(List<PageDesignWidget> widgets 

Mã cho thuộc tính tùy chỉnh có thể được tìm thấy here (liên kết bị hỏng bây giờ).

Bởi vì vào liên kết bị phá vỡ này là mã cho JsonFilterAttribute

public class JsonFilter : ActionFilterAttribute 
{ 
    public string Param { get; set; } 
    public Type JsonDataType { get; set; } 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.ContentType.Contains("application/json")) 
     { 
      string inputContent; 
      using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream)) 
      { 
       inputContent = sr.ReadToEnd(); 
      } 
      var result = JsonConvert.DeserializeObject(inputContent, JsonDataType); 
      filterContext.ActionParameters[Param] = result; 
     } 
    } 
} 

JsonConvert.DeserializeObject là từ Json.NET

Link: Serializing and Deserializing JSON with Json.NET

+0

Làm việc tốt ở đây! – jeffreypriebe

+0

Có vẻ tuyệt vời - Bài đăng trên blog và liên kết mã thuộc tính tùy chỉnh không hoạt động nữa - bạn có thể đăng lại không? – littlechris

+4

Giải pháp này yêu cầu thay đổi ở phía máy khách và phía máy chủ. Tôi biết bạn cần điều này từ lâu, nhưng tôi cũng có thể cung cấp một liên kết đến một cách tiếp cận khác, sử dụng một plugin jQuery đơn giản giúp chuyển đổi bất kỳ đối tượng Javascript nào thành dạng mà trình mô hình hóa mặc định hiểu và mô hình liên kết với các tham số. Không cần bộ lọc. http://erraticdev.blogspot.com/2010/12/sending-complex-json-objects-to-aspnet.html Tôi không biết cách bạn giải quyết các lỗi xác thực nhưng tôi cũng có giải pháp cho điều đó: http://erraticdev.blogspot.com/2010/11/handling-validation-errors-on-ajax.html –

8

Hướng tới nửa cuối Create REST API using ASP.NET MVC that speaks both JSON and plain XML, trích dẫn:

Bây giờ chúng ta cần phải chấp nhận JSON và XML tải trọng, được gửi qua HTTP POST. Đôi khi, khách hàng của bạn có thể muốn tải lên bộ sưu tập các đối tượng trong một lần chụp để xử lý theo lô. Vì vậy, họ có thể tải lên các đối tượng bằng cách sử dụng định dạng JSON hoặc XML. Không có hỗ trợ gốc trong ASP.NET MVC để tự động phân tích cú pháp được đăng JSON hoặc XML và tự động ánh xạ tới các tham số Hành động. Vì vậy, tôi đã viết một bộ lọc nào đó."

Sau đó, ông thực hiện một bộ lọc hành động mà bản đồ các JSON để C# đối tượng với mã được hiển thị.

+0

Tôi vừa viết bài đăng anwser của mình. Nhưng tôi sẽ đăng nó anyway ;-) – JSC

+0

Yah, có vẻ như Steve Gentile cũng đọc bài của Omar! – anonymous

+0

Vâng tôi cũng đã đọc bài viết của Omar – JSC

7

Đầu tiên tải về mã JavaScript này, JSON2.js, điều đó sẽ giúp chúng tôi tuần tự hóa đối tượng thành một chuỗi.

Trong ví dụ của tôi Tôi đăng các hàng của một jqGrid qua Ajax:

var commissions = new Array(); 
    // Do several row data and do some push. In this example is just one push. 
    var rowData = $(GRID_AGENTS).getRowData(ids[i]); 
    commissions.push(rowData); 
    $.ajax({ 
     type: "POST", 
     traditional: true, 
     url: '<%= Url.Content("~/") %>' + AREA + CONTROLLER + 'SubmitCommissions', 
     async: true, 
     data: JSON.stringify(commissions), 
     dataType: "json", 
     contentType: 'application/json; charset=utf-8', 
     success: function (data) { 
      if (data.Result) { 
       jQuery(GRID_AGENTS).trigger('reloadGrid'); 
      } 
      else { 
       jAlert("A problem ocurred during updating", "Commissions Report"); 
      } 
     } 
    }); 

Bây giờ trên bộ điều khiển:

[HttpPost] 
    [JsonFilter(Param = "commissions", JsonDataType = typeof(List<CommissionsJs>))] 
    public ActionResult SubmitCommissions(List<CommissionsJs> commissions) 
    { 
     var result = dosomething(commissions); 
     var jsonData = new 
     { 
      Result = true, 
      Message = "Success" 
     }; 
     if (result < 1) 
     { 
      jsonData = new 
      { 
       Result = false, 
       Message = "Problem" 
      }; 
     } 
     return Json(jsonData); 
    } 

Tạo một Class JsonFilter (nhờ Công ty cổ phần tài liệu tham khảo).

public class JsonFilter : ActionFilterAttribute 
    { 
     public string Param { get; set; } 
     public Type JsonDataType { get; set; } 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.HttpContext.Request.ContentType.Contains("application/json")) 
      { 
       string inputContent; 
       using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream)) 
       { 
        inputContent = sr.ReadToEnd(); 
       } 
       var result = JsonConvert.DeserializeObject(inputContent, JsonDataType); 
       filterContext.ActionParameters[Param] = result; 
      } 
     } 
    } 

Tạo một lớp khác để bộ lọc có thể phân tích chuỗi JSON thành đối tượng có thể thao tác thực tế: Lớp học này là tất cả các hàng của jqGrid của tôi.

public class CommissionsJs 
    { 
     public string Amount { get; set; } 

     public string CheckNumber { get; set; } 

     public string Contract { get; set; } 
     public string DatePayed { get; set; } 
     public string DealerName { get; set; } 
     public string ID { get; set; } 
     public string IdAgentPayment { get; set; } 
     public string Notes { get; set; } 
     public string PaymentMethodName { get; set; } 
     public string RowNumber { get; set; } 
     public string AgentId { get; set; } 
    } 

Tôi hy vọng ví dụ này giúp minh họa cách đăng đối tượng phức tạp.

+0

Thực tế là câu trả lời! ; D –

22

Bộ lọc hành động, jquery stringify, bleh ...

Peter, chức năng này có nguồn gốc từ MVC. Đó là một trong những điều khiến MVC trở nên tuyệt vời.

$.post('SomeController/Batch', { 'ids': ['1', '2', '3']}, function (r) { 
    ... 
}); 

Và trong hành động,

[HttpPost] 
public ActionResult Batch(string[] ids) 
{ 
} 

trình như một say mê:

enter image description here

Nếu bạn đang sử dụng jQuery 1.4+, sau đó bạn muốn xem xét thiết lập truyền thống chế độ:

jQuery.ajaxSettings.traditional = true; 

Như được mô tả ở đây: http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters

Điều này thậm chí làm việc cho các đối tượng phức tạp. Nếu bạn quan tâm, bạn nên xem tài liệu về MVC về Mô hình ràng buộc: http://msdn.microsoft.com/en-us/library/dd410405.aspx

+1

bạn có thể đúng, nhưng chất kết dính mô hình JSON là mới đối với MVC3 và câu hỏi đã được hỏi vào năm 2008 khi điều này không được hỗ trợ. Nó sẽ là đáng nói đến trong câu trả lời của bạn. –

+3

Đây là ví dụ về việc truyền một mảng các đối tượng _complex_ như thế nào? – DuckMaestro

+0

Nó không phải nhưng ví dụ vẫn áp dụng (MVC 3+). Miễn là tên tham số của bạn khớp với mô hình bạn mong đợi, bạn sẽ không gặp phải bất kỳ vấn đề nào. –

10

Trong .NET4.5, MVC 5 không cần vật dụng.

Javascript:

đối tượng trong JS: enter image description here

cơ chế mà không đường bưu điện.

$('.button-green-large').click(function() { 
     $.ajax({ 
      url: 'Quote', 
      type: "POST", 
      dataType: "json", 
      data: JSON.stringify(document.selectedProduct), 
      contentType: 'application/json; charset=utf-8', 
     }); 
    }); 

C#

Đối tượng:

public class WillsQuoteViewModel 
{ 
    public string Product { get; set; } 

    public List<ClaimedFee> ClaimedFees { get; set; } 
} 

public partial class ClaimedFee //Generated by EF6 
{ 
    public long Id { get; set; } 
    public long JourneyId { get; set; } 
    public string Title { get; set; } 
    public decimal Net { get; set; } 
    public decimal Vat { get; set; } 
    public string Type { get; set; } 

    public virtual Journey Journey { get; set; } 
} 

Bộ điều khiển:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Quote(WillsQuoteViewModel data) 
{ 
.... 
} 

Object nhận:

enter image description here

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.

-1
[HttpPost] 
    public bool parseAllDocs([FromBody] IList<docObject> data) 
    { 
     // do stuff 

    } 
Các vấn đề liên quan