강력한 형식의 MVC3 뷰에서 모델을 전달하기 위해 jquery에서 AJAX Post를 사용하는 적절한 방법


100

저는 초보 웹 프로그래머이므로 제 "용어"중 일부가 올바르지 않으면 용서해주십시오. MVC3 프레임 워크를 사용하는 ASP.NET을 사용하는 프로젝트가 있습니다.

관리자가 장비 목록을 수정하는 관리자보기에서 작업 중입니다. 기능 중 하나는 MVC 컨트롤러에 게시물을 보낸 후 jquery를 사용하여 웹 페이지의 항목을 동적으로 편집하려는 "업데이트"버튼입니다.

이 접근 방식은 웹 페이지가 데이터베이스와 동기화되지 않을 염려가 거의없는 단일 관리자 설정에서 "안전"하다고 생각합니다.

강력한 형식의 뷰를 만들었으며 AJAX 게시물을 사용하여 모델 데이터를 MVC 컨트롤에 전달하려고했습니다.

다음 게시물에서 내가보고있는 것과 비슷한 것을 발견했습니다. JQuery Ajax 및 ASP.NET MVC3로 인해 null 매개 변수가 발생합니다.

위 게시물의 코드 샘플을 사용하겠습니다.

모델:

public class AddressInfo 
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

제어 장치:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Check(AddressInfo addressInfo)
    {
        return Json(new { success = true });
    }
}

View의 스크립트 :

<script type="text/javascript">
var ai = {
    Address1: "423 Judy Road",
    Address2: "1001",
    City: "New York",
    State: "NY",
    ZipCode: "10301",
    Country: "USA"
};

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: JSON.stringify(ai),
    contentType: 'application/json; charset=utf-8',
    success: function (data.success) {
        alert(data);
    },
    error: function () {
        alert("error");
    }
});
</script>

나는 아직 위의 것을 사용할 기회가 없었습니다. 하지만 이것이 AJAX를 사용하여 모델 데이터를 MVC 컨트롤로 다시 전달하는 "최고의"방법인지 궁금합니다.

모델 정보 노출에 대해 걱정해야합니까?

답변:


72

var 선언과 stringify를 건너 뛸 수 있습니다. 그렇지 않으면 잘 작동합니다.

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: {
        Address1: "423 Judy Road",
        Address2: "1001",
        City: "New York",
        State: "NY",
        ZipCode: "10301",
        Country: "USA"
    },
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
        alert(data.success);
    },
    error: function () {
        alert("error");
    }
});

약간의 조정을 지적 해 주셔서 감사합니다. 보안 관점에서 모델 구조를 노출하는 데 문제가 있습니까?
John Stone

나에게 보안 문제로 눈에 띄는 것은 없습니다. 그래도 정말 걱정된다면 mvc 쪽에서 사용자 지정 모델 바인더를 만들 수 있습니다.
Craig M

8
이것은 나를 위해 실패했습니다. MVC5에서 호출이 작동하려면 JSON.stringify ({...})를 사용해야했습니다.
Johncl

API 컨트롤러로 작업 할 때도 똑같이해야한다는 것을 알게되었습니다. 이 답변은 API 컨트롤러가 존재하기 전에 4 년 전에 작성되었습니다.
크레이그 M

1
젠장, 나는 contentType 대신 dataType을 가지고 있었는데, 항상 나를 얻는다!
Phil

175

이것을 구현하는 세 가지 방법을 찾았습니다.

C # 클래스 :

public class AddressInfo {
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

동작:

[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
    return Json(new { success = true });
}

JavaScript 는 세 가지 방법으로 수행 할 수 있습니다.

1) 쿼리 문자열 :

$.ajax({
    url: '/en/Home/Check',
    data: $('#form').serialize(),
    type: 'POST',
});

여기 데이터는 문자열입니다.

"Address1=blah&Address2=blah&City=blah&State=blah&ZipCode=blah&Country=blah"

2) 개체 배열 :

$.ajax({
    url: '/en/Home/Check',
    data: $('#form').serializeArray(),
    type: 'POST',
});

여기 데이터는 키 / 값 쌍의 배열입니다.

=[{name: 'Address1', value: 'blah'}, {name: 'Address2', value: 'blah'}, {name: 'City', value: 'blah'}, {name: 'State', value: 'blah'}, {name: 'ZipCode', value: 'blah'}, {name: 'Country', value: 'blah'}]

3) JSON :

$.ajax({
      url: '/en/Home/Check',
      data: JSON.stringify({ addressInfo:{//missing brackets
          Address1: $('#address1').val(),
          Address2: $('#address2').val(),
          City: $('#City').val(),
          State: $('#State').val(),
          ZipCode: $('#ZipCode').val()}}),
      type: 'POST',
      contentType: 'application/json; charset=utf-8'
});

여기 데이터는 직렬화 된 JSON 문자열입니다. 이름은 서버의 매개 변수 이름과 일치해야합니다 !!

='{"addressInfo":{"Address1":"blah","Address2":"blah","City":"blah","State":"blah", "ZipCode", "blah", "Country", "blah"}}'

1
내가 아직 알지 못했던 질문을 해결 한이 훌륭하고 철저한 답변을 방금 발견했습니다. +1, 감사합니다!
SeanKilleen

# 2는 내가 찾던 것이었다. 이것이 답이되어야합니다.
TheGeekZn 2013

편집 : data: $('input, textarea, select').serialize(),내 작업 을 위해 사용해야 했습니다.
TheGeekZn 2013

안녕 Jazaret !! 세 번째 접근 방식으로 모델에 날짜를 전달하는 방법 ??
Guruprasad Rao

1
@GuruprasadRao 지연 죄송합니다. 날짜를 전달하려면 날짜 및 시간을 자바 스크립트 코드의 문자열로 사용할 수 있으며 MVC는이를 DateTime 객체로 변환합니다.
Jazaret 2015 년

12

이것이 나를 위해 일한 방식입니다.

$.post("/Controller/Action", $("#form").serialize(), function(json) {       
        // handle response
}, "json");

[HttpPost]
public ActionResult TV(MyModel id)
{
    return Json(new { success = true });
}

8

당신이 가진 것은 괜찮습니다. 그러나 타이핑을 저장하기 위해 당신의 데이터에 간단히 사용할 수 있습니다.

데이터 : $ ( '# formId'). serialize ()

자세한 내용은 http://www.ryancoughlin.com/2009/05/04/how-to-use-jquery-to-serialize-ajax-forms/ 를 참조 하십시오 . 구문은 매우 기본적입니다.


직렬화 함수를 사용하려면 클래스의 각 멤버를 양식 객체에서 사용해야한다는 것을 이해합니다. 그것이 맞다면 나는 SOL일지도 모른다.
John Stone

1
아 예 .. 그렇지 않으면 직렬화를 사용할 수 없습니다. 그래도 항상 DOM을 조작하고 해당 요소로 양식을 만들고 직렬화 할 수 있습니다.하지만 ... 수동으로 필드를 입력하는 것이 더 깔끔 할 것입니다.
Adam Tuliper-MSFT

@TahaRehmanSiddiqui serialize는 실제로 IE에서 작동하지만 작동하지 않는 것은 무엇입니까? 오류가 발생합니까?
Adam Tuliper-MSFT 2013 년

내 모델의 모든 속성은 null을오고있다
타하 레흐만 시디키를

@TahaRehmanSiddiqui 양식 필드의 '이름'이 모델 속성의 이름과 일치합니까?
MongooseNX 2011

0

MVC 5를 사용하는 경우이 솔루션을 읽으십시오!

나는 MVC 3에 대해 특별히 요구 한 질문을 알고 있지만 MVC 5 로이 페이지를 우연히 발견하고 내 상황에있는 다른 사람을위한 솔루션을 게시하고 싶었습니다. 위의 솔루션을 시도했지만 저에게 효과가 없었고 액션 필터에 도달하지 않았고 이유를 알 수 없었습니다. 내 프로젝트에서 버전 5를 사용하고 있으며 다음 작업 필터로 끝났습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Filters;

namespace SydHeller.Filters
{
    public class ValidateJSONAntiForgeryHeader : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            string clientToken = filterContext.RequestContext.HttpContext.Request.Headers.Get(KEY_NAME);
            if (clientToken == null)
            {
                throw new HttpAntiForgeryException(string.Format("Header does not contain {0}", KEY_NAME));
            }

            string serverToken = filterContext.HttpContext.Request.Cookies.Get(KEY_NAME).Value;
            if (serverToken == null)
            {
                throw new HttpAntiForgeryException(string.Format("Cookies does not contain {0}", KEY_NAME));
            }

            System.Web.Helpers.AntiForgery.Validate(serverToken, clientToken);
        }

        private const string KEY_NAME = "__RequestVerificationToken";
    }
}

- 만들기의 노트 using System.Web.Mvcusing System.Web.Mvc.Filters아닌 http라이브러리 (나는 그 MVC의 V5로 변경하는 것 중 하나라고 생각합니다. -

그런 다음 [ValidateJSONAntiForgeryHeader]작업 (또는 컨트롤러)에 필터 를 적용하면 올바르게 호출됩니다.

바로 위의 내 레이아웃 페이지에서 </body>내가 가진@AntiForgery.GetHtml();

마지막으로 내 Razor 페이지에서 다음과 같이 ajax 호출을 수행합니다.

var formForgeryToken = $('input[name="__RequestVerificationToken"]').val();

$.ajax({
  type: "POST",
  url: serviceURL,
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  data: requestData,
  headers: {
     "__RequestVerificationToken": formForgeryToken
  },
     success: crimeDataSuccessFunc,
     error: crimeDataErrorFunc
});

1
모든 양식 값을 수동으로 검색하고 있습니까? 왜 안돼 data: $("#the-form").serialize()?
Sinjai

1
@Sinjai 나는 내 코드를 다시보아야 할 것이지만 거기에서 다른 처리도하고 있다고 생각합니다. ".serialize ()"는 입력 값만 필요한 경우에도 작동합니다
blubberbo

걱정 마세요, 그냥 궁금했습니다.
Sinjai
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.