In my ASP.NET 5 MVC 6 application, I want to post with Ajax some data to my controller. I already done this with ASP.NET MVC 5 and I tested the exact same code in an blank ASP.NET MVC 5 project and it worked, but with the new version I can't and I don't know why. With the Ajax call, I can go to the controller, the model is created but the fields are null (or false for the boolean). Here is my code :
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; } }
Any ideas ? Thanks
In this article series, we will learn two methods to send the data from View to Controller using the ajax post method in the ASP.NET Core application. We will use the following methods to submit the form data in this article series: JSON Form Serialization. Without form serialization.
The MVC Framework contains built-in support for unobtrusive Ajax. You can use the helper methods to define your Ajax features without adding a code throughout all the views. This feature in MVC is based on the jQuery features. To enable the unobtrusive AJAX support in the MVC application, open the Web.
You need to explicit use FromBody on MVC6 if you are using json
public JsonResult Login([FromBody]LoginViewModel model)
EDIT
I think you are mixing different errors. I will try to describe how you should make the request:
content-type must be: application/json
your request body must be in JSON format (as JasonLind suggested):
{ UserName: 'Test', Password: 'Test', RememberMe: true };
this is what you should see when inspecting the request (via chrome debugger tools F12) or using a request inspector like fiddler.
If you see something in the form of UserName=Test&Password=Test&RememberMe=true
then you are doing it wrong, that's form format.
you don't need the model
variable. if you see your request with a "wrapper" then you should remove it.
You can implement BindModel yourself! get the json string and deserialize to your entity.
public class JsonBinder<T> : System.Web.Mvc.IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { using (var reader = new System.IO.StreamReader(controllerContext.HttpContext.Request.InputStream)) { //set stream position 0, maybe previous action already read the stream. controllerContext.HttpContext.Request.InputStream.Position = 0; string json = reader.ReadToEnd(); if (string.IsNullOrEmpty(json) == false) { JavaScriptSerializer serializer = new JavaScriptSerializer(); object jsonData = serializer.DeserializeObject(json); return serializer.Deserialize<T>(json); } else { return null; } } } }
and set the JsonBinder to the post method like
[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"); }
the other solution
I found that you could set DataContract to the class of Model, and set DataMember to the Properties of the class.
edit the class like this
[DataContract] public class LoginViewModel { [DataMember] public string UserName { get; set; } [DataMember] public string Password { get; set; } [DataMember] public bool RememberMe { get; set; } }
and you should add library reference "System.Runtime.Serialization"
Hope it can works for u.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With