[c#] @ Html.HiddenFor는 ASP.NET MVC의 목록에서 작동하지 않습니다.

List를 속성으로 포함하는 모델을 사용하고 있습니다. 이 목록을 SQL Server에서 가져온 항목으로 채우고 있습니다. 목록이 뷰에서 숨겨지고 POST 작업에 전달되기를 원합니다. 나중에 jQuery를 사용하여이 목록에 더 많은 항목을 추가하여 나중에 확장에 적합하지 않은 배열을 만들고 싶을 수 있습니다. 일반적으로 당신은

@Html.HiddenFor(model => model.MyList)

이 기능을 수행하기 위해 어떤 이유로 POST의 목록은 항상 null입니다.

매우 간단한 질문입니다. MVC가 왜 이렇게 작동하는지 아는 사람이 있습니까?



답변

나는 방금이 문제를 발견하고 다음을 수행하여 간단히 해결했습니다.

@for(int i = 0; i < Model.ToGroups.Length; i++)
{
    @Html.HiddenFor(model => Model.ToGroups[i])
}

foreach 대신 for를 사용하면 모델 바인딩이 올바르게 작동하고 목록에서 숨겨진 값을 모두 선택합니다. 이 문제를 해결하는 가장 간단한 방법 인 것 같습니다.


답변

HiddenFor는 DisplayFor 또는 EditorFor와 다릅니다. 컬렉션에서는 작동하지 않으며 단일 값만 사용할 수 있습니다.

MVC Futures 프로젝트에서 사용할 수있는 Serialize HTML 도우미를 사용하여 개체를 Hidden 필드에 직렬화하거나 코드를 직접 작성해야합니다. 더 나은 솔루션은 단순히 일종의 ID를 직렬화하고 포스트 백시 데이터베이스에서 데이터를 다시 가져 오는 것입니다.


답변

그것은 약간의 해킹이지만 목록에 대해 작동 @Html.EditorFor하거나 @Html.DisplayFor게시 요청에 전송되었는지 확인하고 싶지만 표시되지 않도록하려면 스타일을 지정하여 display: none;대신 숨길 수 있습니다. 예 :

<div style="display: none;">@Html.EditorFor(model => model.MyList)</div>


답변

Newtonsoft를 사용하여 객체를 json 문자열로 역 직렬화 한 다음 숨겨진 필드에 삽입하는 것은 어떻습니까? 예를 들어 ( Model.DataResponse.Entity.Commission 은 JSON에서 볼 수있는 간단한 “CommissionRange” 객체 목록 입니다 )

@using (Ajax.BeginForm("Settings", "AffiliateProgram", Model.DataResponse, new AjaxOptions { UpdateTargetId = "result" }))
   {
      string commissionJson = JsonConvert.SerializeObject(Model.DataResponse.Entity.Commission);
      @Html.HiddenFor(data => data.DataResponse.Entity.Guid)
      @Html.Hidden("DataResponse_Entity_Commission", commissionJson)
      [Rest of my form]
   }

다음과 같이 렌더링합니다.

<input id="DataResponse_Entity_Commission" name="DataResponse_Entity_Commission" type="hidden" value="[{"RangeStart":0,"RangeEnd":0,"CommissionPercent":2.00000},{"RangeStart":1,"RangeEnd":2,"CommissionPercent":3.00000},{"RangeStart":2,"RangeEnd":0,"CommissionPercent":2.00000},{"RangeStart":3,"RangeEnd":2,"CommissionPercent":1.00000},{"RangeStart":15,"RangeEnd":10,"CommissionPercent":5.00000}]">

제 경우에는 다시 게시하기 전에 숨겨진 필드에서 json을 편집하기 위해 JS 작업을 수행합니다.

내 컨트롤러에서 Newtonsoft를 다시 사용하여 역 직렬화합니다.

string jsonCommissionRange = Request.Form["DataResponse_Entity_Commission"];
List<CommissionRange> commissionRange = JsonConvert.DeserializeObject<List<CommissionRange>>(jsonCommissionRange);


답변

Html.HiddenFor하나의 값만을 위해 설계되었습니다. 숨겨진 필드를 만들기 전에 어떤 방식 으로든 목록을 직렬화해야합니다.

예를 들어 목록이 문자열 유형 인 경우 목록을 쉼표로 구분 된 목록으로 결합한 다음 컨트롤러에 다시 게시 한 후 목록을 분할 할 수 있습니다.


답변

나는 숨겨져있는 (모델 값이 컨트롤러로 돌아 가지 않는 이유를 알아 내려고 몇 시간 후에) EditorFor를 따라야한다는 것을 방금 알아 냈습니다.

내가 다른 일을 잘못하지 않는 한 이것이 내가 찾은 것입니다. 다시는 실수하지 않겠습니다.

다른 클래스의 목록을 포함하는 모델의 컨텍스트에서.

이것은 작동하지 않습니다.

        @{
            for (int i = 0; i < Model.Categories.Count; i++)
            {
                <tr>
                    <td>
                        @Html.HiddenFor(modelItem => Model.Categories[i].Id)
                        @Html.HiddenFor(modelItem => Model.Categories[i].ProductCategoryId)
                        @Html.HiddenFor(modelItem => Model.Categories[i].CategoryName)
                        @Html.DisplayFor(modelItem => Model.Categories[i].CategoryName)
                    </td>
                    <td>
                        @Html.HiddenFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                        @Html.EditorFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                        @Html.ValidationMessageFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                    </td>
                    <td style="text-align: center">
                        @Html.HiddenFor(modelItem => Model.Categories[i].IsSelected)
                        @Html.EditorFor(modelItem => Model.Categories[i].IsSelected)
                    </td>
                </tr>
            }
        }

이것이 어디에서 …

            for (int i = 0; i < Model.Categories.Count; i++)
            {
                <tr>
                    <td>
                        @Html.HiddenFor(modelItem => Model.Categories[i].Id)
                        @Html.HiddenFor(modelItem => Model.Categories[i].ProductCategoryId)
                        @Html.HiddenFor(modelItem => Model.Categories[i].CategoryName)
                        @Html.DisplayFor(modelItem => Model.Categories[i].CategoryName)
                    </td>
                    <td>
                        @Html.EditorFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                        @Html.HiddenFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                        @Html.ValidationMessageFor(modelItem => Model.Categories[i].DailyPurchaseLimit)
                    </td>
                    <td style="text-align: center">
                        @Html.EditorFor(modelItem => Model.Categories[i].IsSelected)
                        @Html.HiddenFor(modelItem => Model.Categories[i].IsSelected)
                    </td>
                </tr>
            }


답변

에 대한 소스 코드를 파헤 치기 시작했고 HiddenFor, 여러분이보고있는 장애물은 복잡한 객체 MyList가 암시 적으로 type으로 변환 할 수 없다는 string것이므로 프레임 워크가 Model값을 처리 null하고 value속성을 비워 둡니다.