繁体   English   中英

ASP.NET 5 / MVC 6 Ajax将模型发布到Controller

[英]ASP.NET 5 / MVC 6 Ajax post Model to Controller

在我的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变量。 如果您使用“包装器”看到您的请求,则应将其删除。

你可以自己实现BindModel! 获取json字符串并反序列化到您的实体。

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

并将JsonBinder设置为post方法

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

另一个解决方案

我发现你可以将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”

希望它对你有用。

不应该是:

 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总是抛出异常。 它说我使用了错误的内容类型,所以我只是从我的ajax帖子中删除了content-type ,它就像一个魅力。 我认为,对于你将要制作的每个ajax帖子,你必须要小心你的Request.Form被正确填充

在此输入图像描述

编辑 :此解决方案仅在您发布非json数据(非常简单的数据)时才有效,例如连接数据。 但是,如果我想发布复杂的数据,如列表,它就不再起作用......

你的问题不是MVC6是jQuery。 $ .ajax()检查“数据”并知道其格式,以便为您设置内容类型,并且您应该以承诺方式使用$ .ajax

在这里检查承诺优势

并选择表格,然后转向对象,如

 $('.anyForm').on('submit', fucntion(){
        //you have the form in JSON format
        var data = $(this).serializeObject()

    })

这里是serializeObject()方法,默认情况下它不在jQuery上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM