programing

ASP.NET 5 / MVC 6 Ajax 모델에서 컨트롤러까지

testmans 2023. 11. 1. 22:13
반응형

ASP.NET 5 / MVC 6 Ajax 모델에서 컨트롤러까지

ASP에서.NET 5 MVC 6 application, Ajax와 함께 내 컨트롤러에 데이터를 게시하고 싶습니다.ASP로 이미 해놨습니다.NET MVC 5와 저는 빈 ASP에서 정확히 동일한 코드를 테스트했습니다.NET MVC 5 프로젝트는 성공했지만, 새로운 버전에서는 할 수 없고, 왜 그런지 모르겠습니다.Ajax 호출을 사용하면 컨트롤러로 이동하여 모델이 생성되지만 필드가 null(또는 부울의 경우 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이어야 합니다.

요청 기관은 Jason Lind가 제안한 대로 JSON 형식이어야 합니다.

{
    UserName: 'Test',
    Password: 'Test',
    RememberMe: true
};

요청을 검사할 때(Chrome debugger tool F12를 통해) 또는 fidder와 같은 요청 검사기를 사용할 때 주의해야 할 사항입니다.

만약 당신이 어떤 형태의 것을 본다면,UserName=Test&Password=Test&RememberMe=true그러면 잘못하시는 거죠, 그게 양식이에요.

당신은 필요하지 않습니다.model변수.요청에 "wrapper"가 표시된 경우 해당 요청을 제거해야 합니다.

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

Json Binder를 Post method로 설정합니다.

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

라이브러리 참조 "시스템"을 추가해야 합니다.런타임.직렬화"

당신에게 도움이 되길 바랍니다.

그래야 하지 않을까요?

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

watcher 덕분에 해결책을 찾았습니다 :) Request 변수를 보고 Request를 찾았습니다.항상 예외적으로 던져지는 양식입니다.콘텐츠 타입을 잘못 썼다고 해서 그냥 삭제했습니다.content-type내 아약스 포스트를 보니 정말 매력적이었어요.앞으로 작성할 모든 아약스 게시물에 대해서는 요청 사항에 대해 주의를 기울여야 한다고 생각합니다.양식이 올바르게 작성되었습니다.

enter image description here

편집: 이 솔루션은 연결 데이터와 같이 j가 아닌 데이터(아주 간단한 데이터)를 게시할 수 있는 경우에만 작동합니다.하지만 목록처럼 복잡한 데이터를 게시하고 싶다면 더 이상 작동하지 않습니다.

당신의 문제는 MVC6가 jQuery가 아니라는 것입니다.$.ajax()은 "데이터"를 확인하고 형식을 알고 있으므로 컨텐츠 유형을 설정할 수 있으며 $.ajax를 약속 방식으로 사용해야 합니다.

여기서 약속을 확인합니다.

그리고 또한 양식을 선택하고 그냥 객체로 바꿉니다. 예를 들어.

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

    })

그리고 여기 serializeObject() 메서드가 있습니다. 기본적으로 jQuery에는 없습니다.

언급URL : https://stackoverflow.com/questions/28782928/asp-net-5-mvc-6-ajax-post-model-to-controller

반응형