JSON, jQuery를 사용하여 복잡한 개체 배열을 ASP.NET MVC 컨트롤러에 게시하는 방법은 무엇입니까?


92

내 현재 코드는 다음과 같습니다. 어레이를 컨트롤러에 전달하려면 어떻게해야하며 컨트롤러 작업이 허용해야하는 매개 변수의 종류는 무엇입니까?

function getplaceholders() {
    var placeholders = $('.ui-sortable');
    var result = new Array();
    placeholders.each(function() {
        var ph = $(this).attr('id');
        var sections = $(this).find('.sort');
        var section;

        sections.each(function(i, item) {
            var sid = $(item).attr('id');

            result.push({ 'SectionId': sid, 'Placeholder': ph, 'Position': i });
        });
    });
    alert(result.toString());
    $.post(
        '/portal/Designer.mvc/SaveOrUpdate',
        result,
        function(data) {
            alert(data.Result);
        }, "json");
};

내 컨트롤러 작업 방법은 다음과 같습니다.

public JsonResult SaveOrUpdate(IList<PageDesignWidget> widgets)

답변:


84

해결책을 찾았습니다. 나는 Steve Gentile, jQuery 및 ASP.NET MVC 의 솔루션을 사용합니다 . – JSON을 Action으로 전송 – Revisited .

내 ASP.NET MVC보기 코드는 다음과 같습니다.

function getplaceholders() {
        var placeholders = $('.ui-sortable');
        var results = new Array();
        placeholders.each(function() {
            var ph = $(this).attr('id');
            var sections = $(this).find('.sort');
            var section;

            sections.each(function(i, item) {
                var sid = $(item).attr('id');
                var o = { 'SectionId': sid, 'Placeholder': ph, 'Position': i };
                results.push(o);
            });
        });
        var postData = { widgets: results };
        var widgets = results;
        $.ajax({
            url: '/portal/Designer.mvc/SaveOrUpdate',
            type: 'POST',
            dataType: 'json',
            data: $.toJSON(widgets),
            contentType: 'application/json; charset=utf-8',
            success: function(result) {
                alert(result.Result);
            }
        });
    };

내 컨트롤러 작업은 사용자 정의 속성으로 장식되어 있습니다.

[JsonFilter(Param = "widgets", JsonDataType = typeof(List<PageDesignWidget>))]
public JsonResult SaveOrUpdate(List<PageDesignWidget> widgets

사용자 정의 속성에 대한 코드는 여기 에서 찾을 수 있습니다 (지금 링크가 끊어짐).

링크가 끊어 졌기 때문에 이것은 JsonFilterAttribute에 대한 코드입니다.

public class JsonFilter : ActionFilterAttribute
{
    public string Param { get; set; }
    public Type JsonDataType { get; set; }
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
        {
            string inputContent;
            using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
            {
                inputContent = sr.ReadToEnd();
            }
            var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
            filterContext.ActionParameters[Param] = result;
        }
    }
}

JsonConvert.DeserializeObject는 Json.NET에서 가져온 것입니다.

링크 : Json.NET으로 JSON 직렬화 및 역 직렬화


보기 좋습니다. 블로그 게시물과 사용자 지정 속성 코드 링크가 더 이상 작동하지 않습니다. 다시 게시 할 수 있습니까?
— littlechris

4
이 솔루션에는 클라이언트 및 서버 측에서 변경이 필요합니다. 오래 전에이 작업이 필요하다는 것을 알고 있지만 Javascript 객체를 기본 모델 바인더가 이해하고 모델이 매개 변수에 바인딩하는 형식으로 변환 할 수있는 간단한 jQuery 플러그인을 사용하는 다른 접근 방식에 대한 링크를 제공 할 수도 있습니다. 필터가 필요하지 않습니다. erraticdev.blogspot.com/2010/12/… 검증 오류를 어떻게 해결했는지 모르겠지만 이에 대한 해결책도 있습니다. erraticdev.blogspot.com/2010/11/…
— Robert Koritnik 2011

3
JavaScriptConvert.DeserializeObject의 소스 / 원점을 제공 할 수 있습니까?
— Matthieu

Newtonsoft Json 라이브러리입니다. Nuget 패키지 관리자를 열고 Newtonsoft에서 검색하면 표시됩니다 (현재 2016 년). 아마도 이것은 이제 분명하지만 누군가 궁금해하는 경우를 대비하여.
— Robb Sadler 2016

22

액션 필터, jquery stringify, bleh ...

Peter,이 기능은 MVC의 기본 기능입니다. 이것이 MVC를 훌륭하게 만드는 요소 중 하나입니다.

$.post('SomeController/Batch', { 'ids': ['1', '2', '3']}, function (r) {
   ...
});

그리고 행동에서

[HttpPost]
public ActionResult Batch(string[] ids)
{
}

매력처럼 작동 :

여기에 이미지 설명 입력

jQuery 1.4 이상을 사용하는 경우 기존 모드 설정을 살펴보고 싶습니다.

jQuery.ajaxSettings.traditional = true;

여기에 설명 된대로 : http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters

이것은 복잡한 개체에도 적용됩니다. 관심이 있으시면 모델 바인딩에 대한 MVC 설명서를 참조 하십시오 . http://msdn.microsoft.com/en-us/library/dd410405.aspx


1
당신이 옳을 수도 있지만 JSON 모델 바인더는 MVC3의 새로운 기능이며 2008 년에 이것이 지원되지 않았을 때 질문을 받았습니다. 답변에서 언급 할 가치가 있습니다.
— Piotr Owsiak 2011

3
이것이 복잡한 객체 의 배열을 전달하는 예는 무엇입니까?
— DuckMaestro

그렇지는 않지만 예제는 여전히 적용됩니다 (MVC 3+). 매개 변수 이름이 예상되는 모델과 일치하는 한 아무런 문제가 없습니다.
— J. Mitchell

여기서 핵심은 메소드 매개 변수 이름 ( "ids")으로 JSON 객체를 생성 한 다음 그 안에 복잡한 객체 배열을 배치하는 것입니다. 또한 세 번째 매개 변수를 "true"로 설정하면 기존 모드를 처리하게됩니다.
— redwards510

11

에서 .NET4.5, MVC 5위젯 필요가 없습니다.

자바 스크립트 :

JS의 객체 : 여기에 이미지 설명 입력

게시하는 메커니즘.

    $('.button-green-large').click(function() {
        $.ajax({
            url: 'Quote',
            type: "POST",
            dataType: "json",
            data: JSON.stringify(document.selectedProduct),
            contentType: 'application/json; charset=utf-8',
        });
    });

씨#

사물:

public class WillsQuoteViewModel
{
    public string Product { get; set; }

    public List<ClaimedFee> ClaimedFees { get; set; }
}

public partial class ClaimedFee //Generated by EF6
{
    public long Id { get; set; }
    public long JourneyId { get; set; }
    public string Title { get; set; }
    public decimal Net { get; set; }
    public decimal Vat { get; set; }
    public string Type { get; set; }

    public virtual Journey Journey { get; set; }
}

제어 장치:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

받은 물건 :

여기에 이미지 설명 입력

이것이 시간을 절약하기를 바랍니다.


8

JSON과 일반 XML을 모두 사용하는 ASP.NET MVC를 사용하여 REST API 만들기의 후반부에는 다음과 같이 인용합니다.

이제 HTTP POST를 통해 전달되는 JSON 및 XML 페이로드를 수락해야합니다. 때로는 클라이언트가 일괄 처리를 위해 한 번에 개체 모음을 업로드하려고 할 수 있습니다. 따라서 JSON 또는 XML 형식을 사용하여 객체를 업로드 할 수 있습니다. ASP.NET MVC에서는 게시 된 JSON 또는 XML을 자동으로 구문 분석하고 작업 매개 변수에 자동으로 매핑하는 기본 지원이 없습니다. 그래서 그것을하는 필터를 썼습니다. "

그런 다음 표시된 코드를 사용하여 JSON을 C # 개체에 매핑하는 작업 필터를 구현합니다.


나는 단지 내 anwser를 쓰고 있었다. 하지만 어쨌든 게시하겠습니다 ;-)
— JSC

7

먼저이 JavaScript 코드 JSON2.js를 다운로드 하면 객체를 문자열로 직렬화하는 데 도움이됩니다.

내 예에서는 Ajax를 통해 jqGrid 의 행을 게시하고 있습니다 .

    var commissions = new Array();
    // Do several row data and do some push. In this example is just one push.
    var rowData = $(GRID_AGENTS).getRowData(ids[i]);
    commissions.push(rowData);
    $.ajax({
        type: "POST",
        traditional: true,
        url: '<%= Url.Content("~/") %>' + AREA + CONTROLLER + 'SubmitCommissions',
        async: true,
        data: JSON.stringify(commissions),
        dataType: "json",
        contentType: 'application/json; charset=utf-8',
        success: function (data) {
            if (data.Result) {
                jQuery(GRID_AGENTS).trigger('reloadGrid');
            }
            else {
                jAlert("A problem ocurred during updating", "Commissions Report");
            }
        }
    });

이제 컨트롤러에서 :

    [HttpPost]
    [JsonFilter(Param = "commissions", JsonDataType = typeof(List<CommissionsJs>))]
    public ActionResult SubmitCommissions(List<CommissionsJs> commissions)
    {
        var result = dosomething(commissions);
        var jsonData = new
        {
            Result = true,
            Message = "Success"
        };
        if (result < 1)
        {
            jsonData = new
            {
                Result = false,
                Message = "Problem"
            };
        }
        return Json(jsonData);
    }

JsonFilter 클래스를 만듭니다 (JSC 참조 덕분에).

    public class JsonFilter : ActionFilterAttribute
    {
        public string Param { get; set; }
        public Type JsonDataType { get; set; }
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
            {
                string inputContent;
                using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
                {
                    inputContent = sr.ReadToEnd();
                }
                var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
                filterContext.ActionParameters[Param] = result;
            }
        }
    }

필터가 JSON 문자열을 실제 조작 가능한 객체로 구문 분석 할 수 있도록 다른 클래스를 만듭니다.이 클래스 comissionsJS는 내 jqGrid의 모든 행입니다.

    public class CommissionsJs
    {
        public string Amount { get; set; }

        public string CheckNumber { get; set; }

        public string Contract { get; set; }
        public string DatePayed { get; set; }
        public string DealerName { get; set; }
        public string ID { get; set; }
        public string IdAgentPayment { get; set; }
        public string Notes { get; set; }
        public string PaymentMethodName { get; set; }
        public string RowNumber { get; set; }
        public string AgentId { get; set; }
    }

이 예제가 복잡한 개체를 게시하는 방법을 설명하는 데 도움이되기를 바랍니다.


0

세상에. 특별한 일을 할 필요가 없습니다. 게시물 섹션에서만 다음을 수행하십시오.

    $.post(yourURL,{ '': results})(function(e){ ...}

서버에서 다음을 사용하십시오.

   public ActionResult MethodName(List<yourViewModel> model){...}

이 링크 는 당신을 도와줍니다 ...


-1
    [HttpPost]
    public bool parseAllDocs([FromBody] IList<docObject> data)
    {
        // do stuff

    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.