c# - parameter - send array ajax asp net mvc
ASP.NET 5/MVC 6 Ajax post modelo a controlador (5)
¿No debería ser?
var data = {
UserName: ''Test'',
Password: ''Test'',
RememberMe: true
};
En mi aplicación ASP.NET 5 MVC 6, quiero publicar con Ajax algunos datos en mi controlador. Ya hice esto con ASP.NET MVC 5 y probé exactamente el mismo código en un proyecto de ASP.NET MVC 5 en blanco y funcionó, pero con la nueva versión no puedo y no sé por qué. Con la llamada Ajax, puedo ir al controlador, se crea el modelo pero los campos son nulos (o falsos para el booleano). Aquí está mi código:
script.js:
var data = {
model: {
UserName: ''Test'',
Password: ''Test'',
RememberMe: true
}
};
$.ajax({
type: "POST",
url: "/Account/Login/",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Do something interesting here.
}
});
AccountController.cs:
[HttpPost]
public JsonResult Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
//var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
//if (result.Succeeded)
//{
// //return RedirectToLocal(returnUrl);
//}
ModelState.AddModelError("", "Identifiant ou mot de passe invalide");
return Json("error-model-wrong");
}
// If we got this far, something failed, redisplay form
return Json("error-mode-not-valid");
}
LoginViewModel.cs:
public class LoginViewModel
{
[Required]
[Display(Name = "UserName")]
[EmailAddress]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Algunas ideas ? Gracias
Necesitas usar FromBody explícitamente en MVC6 si estás usando json
public JsonResult Login([FromBody]LoginViewModel model)
EDITAR
Creo que estás mezclando diferentes errores. Intentaré describir cómo debe hacer la solicitud:
el tipo de contenido debe ser : application / json
el cuerpo de su solicitud debe estar en formato JSON (como sugirió JasonLind):
{
UserName: ''Test'',
Password: ''Test'',
RememberMe: true
};
esto es lo que debería ver al inspeccionar la solicitud (a través de las herramientas de depuración de chrome F12) o al utilizar un inspector de solicitudes como Fiddler.
Si ve algo en la forma de UserName=Test&Password=Test&RememberMe=true
de UserName=Test&Password=Test&RememberMe=true
entonces lo está haciendo mal, ese es el formato de formulario.
No necesitas la variable model
. Si ve su solicitud con un "contenedor", entonces debe eliminarlo.
Ok, encontré la solución, pero aún es extraño para mí ... Solo tienes que eliminar el content-type
de content-type
de la solicitud.
$.ajax({
type: "POST",
url: "Account/Login",
data: data,
success: function (msg) {
// Do something interesting here.
}
});
He encontrado la solución gracias al observador :) Observé la variable de solicitud y encontré que Request.Form siempre fue una excepción. Dijo que usé un tipo de contenido incorrecto, así que eliminé el content-type
de content-type
de mi publicación de ajax y funcionó a la perfección. Creo que, para cada publicación de ajax que hagas, debes tener cuidado de que tu solicitud. Formulario se llene correctamente
EDITAR : esta solución funciona solo cuando se pueden publicar datos que no sean de json (datos muy simples), como datos de conexión. Pero si quiero publicar datos complejos, como una lista, ya no funciona ...
Su problema no es MVC6 es jQuery. $ .ajax () verifica los "datos" y conoce su formato, así establece el tipo de contenido para usted, y también debería usar $ .ajax de manera prometedora
ver promesas de ventajas here
y también selecciona la forma y solo conviértete en objeto, como
$(''.anyForm'').on(''submit'', fucntion(){
//you have the form in JSON format
var data = $(this).serializeObject()
})
y here está el método serializeObject (), no está en jQuery por defecto.
Usted puede implementar BindModel usted mismo! obtener la cadena json y deserializar a su entidad.
[DataContract]
public class LoginViewModel
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public bool RememberMe { get; set; }
}
y configurar el JsonBinder en el método de publicación como
[HttpPost] public JsonResult Login([ModelBinder(typeof(JsonBinder<LoginViewModel>))] LoginViewModel model) { if (ModelState.IsValid) { //var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); //if (result.Succeeded) //{ // //return RedirectToLocal(returnUrl); //} ModelState.AddModelError("", "Identifiant ou mot de passe invalide"); return Json("error-model-wrong"); } // If we got this far, something failed, redisplay form return Json("error-mode-not-valid"); }
la otra solución
Descubrí que podría establecer DataContract en la clase de Modelo y establecer DataMember en las Propiedades de la clase.
edita la clase como esta
[DataContract] public class LoginViewModel { [DataMember] public string UserName { get; set; } [DataMember] public string Password { get; set; } [DataMember] public bool RememberMe { get; set; } }
y debe agregar la referencia de la biblioteca "System.Runtime.Serialization"
Espero que pueda trabajar para ti.