2016-09-16 3 views
0

클래스에 대한 레코드를 보여주는 강력한 유형의 면도기 뷰가 있습니다. 이보기는 사용자가 레코드를 업데이트하는 데 사용할 수있는 양식 (드롭 다운, 몇 개의 확인란 및 몇 개의 텍스트 상자)을 표시합니다. 사용자가 컨트롤의 값을 변경하여 필드를 수정하면 즉시 해당 필드를 업데이트하기 위해 웹 API로 아약스 호출이 전송됩니다. 나는이 기능은 더 일반적인하고 싶다, 그러나Web API 요청에 대한 양식 데이터 직렬화 MVC 5

$(document).ready(function() { 
    $(this).on("change", function (e) { 
     var editRecordURL = $("#editRecordURL").val(); 
     var key = $("#AccessVM_Id").val(); 
     var mode = $("#AccessVM_AccessMode").val(); 
     var failLim = $("#AccessVM_LoginFailLimit").val(); 
     var cap = $("#AccessVM_PwdWCap").is(':checked'); 
     ... 
     var rec = { 
      Id: key, 
      AccessMode: mode, 
      LoginFailLimit: failLim, 
      PwdWCap: cap, 
      .... 
     }; 

     $.ajax({ 
      type: "PUT", 
      url: editRecordURL, 
      data: JSON.stringify(rec), 
      contentType: 'application/json; charset=utf-8', 
      success: function (msg) { 
       bootbox.alert("Success: Record updated successfully!"); 
      }, 
      error: function (XMLHttpRequest, textStatus, errorThrown) { 
       bootbox.alert("Error: " + errorThrown); 
      } 
     }); 
    }); 
}); 

를 그래서 (특히 더 많은 데이터와 그 업데이트) 다른 형태의 재사용 할 수있는 다음 Ajax 호출 잘 작동합니다. 이상적으로 녹화 객체는 다음과 같이 채워 것 :

var rec = $("#form").serializeArray(); 

불행하게도이 때문에 예상 된 JSON 문자열을 반환하지 않습니다 JSON.stringify()rec에 적용한 후 작동하지 않습니다. 대신이 같은 일련의 이름/값 쌍으로 전송 :이 때문에 문자열이 보이는 수정 어떻게 그래서

[{"name":"__RequestVerificationToken","value":"qVedWHJ6HIrqtLJpTxp4m5D2ehZ_AdjCOvQtz4Jyzlg0cdocsWqcTCiE2jzIEB7UsJPwuSZeZF7y1GsluHNrNCDV1wrHjU1UJO5vMMGTLB41"},{"name":"AccessVM.Id","value":"1"},{"name":"AccessVM.AccessMode","value":"1"},{"name":"AccessVM.LoginFailLimit","value":"10"},{"name":"AccessVM.PwdWCap","value":"true"},{"name":"AccessVM.PwdWCap","value":"false"},{"name":"AccessVM.PwdWNum","value":"true"},{"name":"AccessVM.PwdWNum","value":"false"},{"name":"AccessVM.PwdWSC","value":"true"},{"name":"AccessVM.PwdWSC","value":"false"},{"name":"AccessVM.PwdMinLen","value":"6"},{"name":"AccessVM.PwdMaxLen","value":"25"},{"name":"AccessVM.PwdChange","value":"90"},{"name":"AccessVM.PwdPrevUsedLimit","value":"10"}] 

을 같은 :

[{"AccessVM.Id": 1, "AccessVM.AccessMode": 1, "AccessVM.LoginFailLimit": 10, "AccessVM.PwdWCap": true, "AccessVM.PwdWNum": true, "AccessVM.PwdWSC": false, "AccessVM.PwdMinLen": 6, "AccessVM.PwdMaxLen": 25, "AccessVM.PwdChange": 90, "AccessVM.PwdPrevUsedLimit": 10}] 

웹 API 컨트롤러 :

public class PoliciesController : ApiController 
{ 
    .... 
    // PUT: api/policies/1 
    [ResponseType(typeof(void))] 
    public IHttpActionResult PutPolicy(int id, AccessItemViewModel polDto) 
    { 
     .... 
    } 
    .... 
} 

모델보기

public class PolicyViewModel 
{ 
    public AccessItemViewModel AccessVM { get; set; } 
    .... 
} 

public class AccessItemViewModel 
{ 
    public int Id { get; set; } 
    public int AccessMode { get; set; } 
    public int LoginFailLimit { get; set; } 
    public bool PwdWCap { get; set; } 
    .... 
} 

면도기보기 :

@model App.Web.ViewModels.PolicyViewModel 
.... 
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 
{ 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary("", new { @class = "text-danger" }) 
    <input type="hidden" id="editRecordURL" value="@Model.ExtraVM.EditRecordUrl" /> 
    @Html.LabelFor(m => m.AccessVM.AccessMode, new { @class = "col-xs-5" }) 
    @Html.HiddenFor(m => m.AccessVM.Id) 
    @Html.DropDownListFor(m => m.AccessVM.AccessMode, new SelectList(Model.AccessModes, "Mode", "Description"), null, new { @class = "input-sm col-xs-7" }) 
    @Html.LabelFor(m => m.AccessVM.LoginFailLimit, new { @class = "col-xs-9" }) 
    @Html.DropDownListFor(m => m.AccessVM.LoginFailLimit, new SelectList(Model.LoginLimits, "LoginFailLimit", "Value"), null, new { @class = "input-sm col-xs-3" }) 
    @Html.LabelFor(m => m.AccessVM.PwdWCap, new { @class = "col-xs-11" }) 
    @Html.CheckBoxFor(m => m.AccessVM.PwdWCap, new { @class = "input-xs col-xs-1" }) 
    .... 
} 
+0

을 생성하는 @Html.Action() 또는 @Html.Partial()을 사용 .serializeArray()') 그리고'contentType : 'application/json을 제거한다; serialize(),') –

+0

생성하기 때문에 ("찾을 수 없습니다"오류가 발생합니다) 작동하지 않습니다. accessVM.Id = 1 & AccessVM.AccessMode = 1 & AccessVM.LoginFailLimit = 1 & AccessVM.PwdWCap = false & AccessVM.PwdWNum = false & AccessVM.PwdWSC = false & AccessVM과 같은 키와 값의 쿼리 문자열입니다.PwdMinLen = 3 ... 웹 API 엔드 포인트는 "policy"유형의 오브젝트 (JSON 오브젝트를 의미 함)로 전송 될 것으로 기대합니다. 하지만 어떻게 든이 문자열을 가져 와서 JSON 객체로 변환하면 멋질 것입니다. –

+0

'정책'모델은 무엇입니까? 'Id','AccessMode' 등의 속성을 포함하는'AccessVM'이라는 복잡한 속성이 포함되어 있다면, 그것은 잘 묶을 것입니다. 그리고보기 및 컨트롤러의 일부를 표시합니다 (POST 메서드의 모델은 뷰의 모델과 동일하지 않습니다.) –

답변

1

당신은 .serialize()을 (하지 .serializeArray() 늘 당신의 bool 속성과 DefaultModelBinder 제대로 작동하는)를 사용하고 기본 application/x-www-form-urlencoded; charset=UTF-8를 사용하고 데이터를 캐릭터 라인 화하지 않도록 contentType 옵션을 제거해야합니다. 뷰에서 모델이 PolicyViewModel하고 .serialize() 기능 PolicyViewModel을위한 이름/값 쌍을 직렬화합니다 귀하의 생성 폼 컨트롤은, 그 모델을 기반으로하지만 Yoru 스크립트는

$.ajax({ 
    type: "PUT", 
    url: editRecordURL, 
    data: $('form').serialize(), 
    success: function (msg) { 

해야한다. 즉, PutPolicy 메소드의 모델이 일치해야합니다. 방법은 메소드 매개 변수가 다음 뷰가 AccessItemViewModel 기반으로 할 필요가 변경 될 수없는 경우

public IHttpActionResult PutPolicy(int id, PolicyViewModel model) // not AccessItemViewModel 

할 필요가 또는 당신은 당신이`이름을 생성하도록 AccessVM 속성에 대한 부분 뷰를 사용할 필요가 "AccessVM"접두사가없는 속성 예를 들어

_AccessVM.cshtml는

@model AccessItemViewModel 
@Html.HiddenFor(m => m.Id) 
.... 

및 주요보기

, 그 HTML 그것은 $는 ("# 양식").`(`) (안 직렬화`의

관련 문제