2008-11-26 6 views
88

Mój obecny kod wygląda następująco. Jak mogę przekazać moją tablicę do kontrolera i jakie parametry musi zaakceptować moja akcja kontrolera?Jak wysłać tablicę złożonych obiektów za pomocą JSON, jQuery do kontrolera ASP.NET MVC?

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"); 
}; 

Moja metoda działania kontrolera wygląda

public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets) 

Odpowiedz

83

mam znaleźć rozwiązanie. Używam roztworu . Steve Gentile, jQuery and ASP.NET MVC – sending JSON to an Action – Revisited

My ASP.NET MVC widok kod wygląda następująco:

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); 
      } 
     }); 
    }; 

i mój kontroler działania ozdobione niestandardowych attri Bute

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

kod dla atrybutu niestandardowego można znaleźć here (link jest uszkodzony teraz).

Ponieważ link jest uszkodzony to jest kod na 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 wynosi od Json.NET

Link: Serializing and Deserializing JSON with Json.NET

+0

Dobra robota tutaj! – jeffreypriebe

+0

Wygląda świetnie - posty na blogu i niestandardowe linki do kodów atrybutów już nie działają - czy możesz je ponownie opublikować? – littlechris

+4

To rozwiązanie wymaga zmian po stronie klienta i serwera. Wiem, że potrzebowałeś tego dawno temu, ale równie dobrze mogę podać link do innego podejścia, które wykorzystuje prostą wtyczkę jQuery, która umożliwia konwersję dowolnego obiektu JavaScript w formę, którą domyślny model bindownicy rozumie i model wiąże z parametrami. Nie wymaga filtrów. http://erraticdev.blogspot.com/2010/12/sending-complex-json-objects-to-aspnet.html Nie wiem, jak rozwiązać błędy sprawdzania poprawności, ale mam również rozwiązanie tego problemu: http://erraticdev.blogspot.com/2010/11/handling-validation-errors-on-ajax.html –

8

kierunku drugiej połowie Create REST API using ASP.NET MVC that speaks both JSON and plain XML, zacytować:

Teraz musimy akceptować JSON i XML ładowność, dostarczane za pośrednictwem HTTP POST. Czasami klient może przesłać kolekcję obiektów w jednym ujęciu do przetwarzania wsadowego. Mogą więc przesyłać obiekty przy użyciu formatu JSON lub XML. W środowisku ASP.NET MVC nie ma natywnej obsługi, aby automatycznie parsować napisy JSON lub XML i automatycznie mapować do parametrów akcji. Więc napisałem filtr, który to robi.”

Potem realizuje filtr działania, który mapuje JSON do C# obiektów z kodem pokazane.

+0

Właśnie pisałem mojego anwsera. Ale i tak to opublikuję ;-) – JSC

+0

Yah, wygląda na to, że Steve Gentile także czytał post Omar! – anonymous

+0

Tak, czytałem także posta Omar'a – JSC

7

Najpierw pobierz kod JavaScript, JSON2.js, to pomoże nam serializować obiekt w łańcuch.

W moim przykładzie mam opublikowania wiersze o jqGrid poprzez 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"); 
      } 
     } 
    }); 

Teraz na kontrolerze:

[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); 
    } 

utworzyć klasę JsonFilter (dzięki nawiązaniu JSC).

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; 
      } 
     } 
    } 

Utwórz kolejną klasę więc filtr można analizować ciąg JSON do rzeczywistej manipulowanego obiektu tej klasy comissionsJS są wszystkie wiersze mojego jqGrid.

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; } 
    } 

Mam nadzieję, że ten przykład pomoże zilustrować, jak opublikować złożony obiekt.

+0

De facto odpowiedź! ; D –

22

Filtry akcji, jQuery stringify, bleh ...

Peter, ta funkcjonalność jest rodzimy MVC. To jedna z rzeczy, która czyni MVC tak świetnym.

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

A w działaniu,

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

działa jak czar:

enter image description here

Jeśli używasz jQuery 1.4+, potem zajrzeć do ustawiania tradycyjny tryb:

jQuery.ajaxSettings.traditional = true; 

Jak opisano tutaj: http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters

Działa to nawet w przypadku złożonych obiektów. Jeśli jesteś zainteresowany, powinieneś zajrzeć do dokumentacji MVC dotyczącej wiązania modelu: http://msdn.microsoft.com/en-us/library/dd410405.aspx

+1

możesz mieć rację, ale spinacz modelu JSON jest nowy dla MVC3 i pytanie zostało zadane w 2008 roku, kiedy nie było to obsługiwane. W swojej odpowiedzi warto wspomnieć. –

+3

Jak to jest przykładem przekazania tablicy obiektów _complex_? – DuckMaestro

+0

Nie jest, ale przykład nadal obowiązuje (MVC 3+). Dopóki twoje nazwy parametrów pasują do oczekiwanego modelu, nie będziesz mieć problemu. –

10

W .NET4.5, MVC 5 nie ma potrzeby używania widżetów.

Javascript:

obiekt w JS: enter image description here

mechanizm, który robi post.

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

C#

obiektów:

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; } 
} 

Kontroler: otrzymane

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

obiektu

enter image description here

Mam nadzieję, że to zaoszczędzi ci trochę czasu.

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

    }