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.