ASP.NET 5 / MVC 6 Ajax将模型发布到控制器
在我的ASP.NET 5 MVC 6应用程序中,我想用Ajax将一些数据发布到我的控制器。 我已经使用ASP.NET MVC 5完成了这项工作,并且我在一个空白的ASP.NET MVC 5项目中测试了完全相同的代码并且它可以工作,但是新版本我不能,我不知道为什么。 通过Ajax调用,我可以转到控制器,创建模型但字段为空(或布尔值为false)。 这是我的代码:
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; } }
有任何想法吗 ? 谢谢
如果使用json,则需要在MVC6上显式使用FromBody
public JsonResult Login([FromBody]LoginViewModel model)
编辑
我认为你混合了不同的错误。 我将尝试描述您应该如何提出请求:
content-type 必须是 :application / json
您的请求正文必须是 JSON格式(如JasonLind建议的那样):
{ UserName: 'Test', Password: 'Test', RememberMe: true };
这是您在检查请求时(通过chrome调试工具F12)或使用请求检查器(如fiddler)时应该看到的内容。
如果您看到UserName=Test&Password=Test&RememberMe=true
那么您做错了,这就是表单格式。
你不需要model
变量。 如果您使用“包装器”看到您的请求,则应将其删除。
不应该是:
var data = { UserName: 'Test', Password: 'Test', RememberMe: true };
好的我找到了解决方案,但对我来说仍然很奇怪……你只需要从请求中删除content-type
。
$.ajax({ type: "POST", url: "Account/Login", data: data, success: function (msg) { // Do something interesting here. } });
我已经找到了解决方案,感谢观察者:)我看了Request变量,我发现Request.Form总是抛出exception。 它说我使用了错误的内容类型,所以我只是从我的ajaxpost中删除了content-type
,它就像一个魅力。 我认为,对于你要制作的每个ajaxpost,你必须要小心你的Request.Form被正确填充
编辑 :此解决方案仅在您可以发布非json数据(非常简单的数据)时才有效,例如连接数据。 但如果我想发布复杂数据,如列表,它就不再起作用了……
你的问题不是MVC6是jQuery。 $ .ajax()检查“数据”并知道其格式,以便为您设置内容类型,并且您应该以承诺方式使用$ .ajax
在这里检查承诺优势
并选择表格,然后转向对象,就像
$('.anyForm').on('submit', fucntion(){ //you have the form in JSON format var data = $(this).serializeObject() })
这里是serializeObject()方法,默认情况下它不在jQuery上。
你可以自己实现BindModel! 获取json字符串并反序列化到您的实体。
public class JsonBinder : 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 (json); } else { return null; } } } }
并将JsonBinder设置为post方法
[HttpPost] public JsonResult Login([ModelBinder(typeof(JsonBinder))] 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"); }
另一个解决方案
我发现你可以将DataContract设置为Model类,并将DataMember设置为类的Properties。
像这样编辑类
[DataContract] public class LoginViewModel { [DataMember] public string UserName { get; set; } [DataMember] public string Password { get; set; } [DataMember] public bool RememberMe { get; set; } }
你应该添加库引用“System.Runtime.Serialization”
希望它对你有用。