c# - parameter - ¿Cómo publicar una matriz de objetos complejos con JSON, jQuery a ASP.NET MVC Controller?
send object ajax jquery mvc (6)
Mi código actual se parece a lo siguiente. ¿Cómo puedo pasar mi matriz al controlador y qué tipo de parámetros debe aceptar mi acción de controlador?
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");
};
Mi método de acción del controlador se ve como
public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets)
Action Filters, jquery stringify, bleh ...
Peter, esta funcionalidad es nativa de MVC. Esa es una de las cosas que hace MVC tan bueno.
$.post(''SomeController/Batch'', { ''ids'': [''1'', ''2'', ''3'']}, function (r) {
...
});
Y en la acción,
[HttpPost]
public ActionResult Batch(string[] ids)
{
}
Funciona de maravilla:
Si está utilizando jQuery 1.4+, entonces quiere ver cómo se configura el modo tradicional:
jQuery.ajaxSettings.traditional = true;
Como se describe aquí: http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters
Esto incluso funciona para objetos complejos. Si está interesado, debe consultar la documentación de MVC sobre Enlace de modelos: http://msdn.microsoft.com/en-us/library/dd410405.aspx
En .NET4.5
, MVC 5
no hay necesidad de widgets.
Javascript:
objeto en JS:
mecanismo que publica.
$(''.button-green-large'').click(function() {
$.ajax({
url: ''Quote'',
type: "POST",
dataType: "json",
data: JSON.stringify(document.selectedProduct),
contentType: ''application/json; charset=utf-8'',
});
});
DO#
Objetos:
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; }
}
Controlador:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}
Objeto recibido:
Espero que esto te ahorre algo de tiempo.
Encontré una solución. Utilizo una solución de Steve Gentile, jQuery y ASP.NET MVC - enviando JSON a una acción - Revisited .
Mi código de vista ASP.NET MVC se ve así:
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);
}
});
};
y mi acción de controlador está decorada con un atributo personalizado
[JsonFilter(Param = "widgets", JsonDataType = typeof(List<PageDesignWidget>))]
public JsonResult SaveOrUpdate(List<PageDesignWidget> widgets
El código para el atributo personalizado se puede encontrar here (el enlace está roto ahora).
Como el enlace está roto, este es el código de 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 es de Json.NET
Enlace: Serialización y deserialización de JSON con Json.NET
Hacia la segunda mitad de Create REST API usando ASP.NET MVC que habla tanto JSON como XML simple , para citar:
Ahora tenemos que aceptar la carga útil JSON y XML, entregada a través de HTTP POST. En ocasiones, es posible que su cliente desee cargar una colección de objetos de una vez para el procesamiento por lotes. Por lo tanto, pueden cargar objetos utilizando el formato JSON o XML. No existe soporte nativo en ASP.NET MVC para analizar automáticamente JSON o XML publicados y asignar automáticamente a los parámetros de Acción. Entonces, escribí un filtro que lo hace ".
Luego implementa un filtro de acción que mapea los objetos JSON a C # con el código mostrado.
Primero descargue este código JavaScript, JSON2.js , que nos ayudará a serializar el objeto en una cadena.
En mi ejemplo, estoy publicando las filas de un jqGrid través de 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");
}
}
});
Ahora en el controlador:
[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);
}
Crea una clase JsonFilter (gracias a la referencia 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;
}
}
}
Cree otra clase para que el filtro pueda analizar la cadena JSON en el objeto manipulable real: Esta clase comissionsJS son todas las filas de mi 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; }
}
Espero que este ejemplo ayude a ilustrar cómo publicar un objeto complejo.
[HttpPost]
public bool parseAllDocs([FromBody] IList<docObject> data)
{
// do stuff
}