ASP.NET MVC- 모형이 사용자 정의 뷰 모델로 래핑되지 않는 한 NULL 모델을 반환합니다.

StackOverflow https://stackoverflow.com/questions/1821302

문제

내 응용 프로그램에는 모델 항목 중 하나에 대해 동일한 편집기 템플릿을 표시하는 한 쌍의 뷰가 있습니다. 두 뷰 ( "add"및 "edit") 중에서 "편집"은 잘 작동하지만 컨트롤러 동작이 게시물을 처리 할 때 모델에 대해 "add"가 모델에 대해 NULL을 반환합니다.

"추가"를 제공하면 사용자 정의 뷰 모드보기 및 호출이 있음을 알았습니다. Html.EditorFor(p => p.PageContent) 전체 모델 객체에서 편집기 ()을 단순히 호출하는 대신 Html.EditorFor(p => p), 양식은 올바른 비 널 모델을 반환하지만 내 클라이언트 측 스크립팅 및 제어 ID와 관련된 다른 문제를 생성합니다 (이제 모든 필드는 "pagecontent_"로 접두사가 표시됨). 응용 프로그램 전체에서 동일한 편집기 템플릿 기술을 사용하고 있으며 다른 곳에서는 뷰 모델 에이 이상한 의존성을 보여주지 않습니다.

다른 사람이 비슷한 문제를 경험 한 적이 있습니까?

보기 편집

<%@ Page Title="" Language="C#" MasterPageFile="~/Areas/Admin/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<PageContent>" %>

<% using (Html.BeginForm())
   { %>
<%=Html.Hidden("PageID", Model.Page.ID) %>
<%=Html.EditorFor(p => p)%>
<input type="submit" name="btnSave" value="Save" />
<input type="submit" name="btnCancel" value="Cancel" class="cancel" />
<% }

액션 (작업)

[HttpPost, ValidateInput(false)]
public ActionResult EditContent(int id, FormCollection formCollection) {}

보기를 추가하십시오

<%@ Page Title="" Language="C#" MasterPageFile="~/Areas/Admin/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<PageContent>" %>

<% using (Html.BeginForm())
   { %>
<%=Html.Hidden("PageID", ViewData["PageID"]) %>
<%=Html.EditorFor(p => p)%>
<input type="submit" name="btnSave" value="Save" />
<input type="submit" name="btnCancel" value="Cancel" class="cancel" />
<% } %>

행동 (실패)

// content is ALWAYS null
[HttpPost, ValidateInput(false)]
public ActionResult AddContent(PageContent content, FormCollection formCollection) {}

당신이 울기 전에 "Duplicat"

이 질문은 관련이 있습니다 이 하나, 그러나이 질문은 더 일반적인 질문보다는 내가 겪고있는 특정 문제를 목표로 삼기위한 것입니다.

도움이 되었습니까?

해결책

나는 문제를 추적했고 다소 흥미로운 문제입니다.

DefaultModelBinder가 모델 항목을 해결하려고 시도 할 때 가장 먼저 수행하는 작업 중 하나는 데이터에 접두사가있는 필드가 있는지 확인하는 것입니다. 모델 객체의 이름으로 시작하는 모든 양식 항목을 확인하여이를 수행합니다 (이것은 보입니다. 매우 임의적입니다, 당신이 나에게 물어 보면). "접두사"필드가 발견되면 다른 바인딩 로직이 호출됩니다.

ASP.NET MVC 2 미리보기 2 bindmodel () 소스

public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
    if (bindingContext == null) {
        throw new ArgumentNullException("bindingContext");
    }
    bool performedFallback = false;
    if (!String.IsNullOrEmpty(bindingContext.ModelName) && !DictionaryHelpers.DoesAnyKeyHavePrefix(bindingContext.ValueProvider, bindingContext.ModelName)) {
        // We couldn't find any entry that began with the prefix. If this is the top-level element, fall back
        // to the empty prefix.
        if (bindingContext.FallbackToEmptyPrefix) {
             /* omitted for brevity */
            };
            performedFallback = true;
        }
        else {
            return null;
        }
    }

    // Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))
    // or by seeing if a value in the request exactly matches the name of the model we're binding.
    // Complex type = everything else.
    if (!performedFallback) {
       /* omitted for brevity */
    }
    if (!bindingContext.ModelMetadata.IsComplexType) {
        return null;
    }
    return BindComplexModel(controllerContext, bindingContext);
}

추가 작업을 처리하도록 정의한 컨트롤러 동작은 "Content"라는 PageContent 항목을 정의하고 내 도메인에는 "Content"라는 속성이있어 "Content"의 모델 이름과 "일치"하여 DefaultModelBinder가 내가 가지고 있다고 가정합니다. 실제로 PageContent의 회원 일 때 접두사 값. 서명을 변경하여

에서:

[HttpPost, ValidateInput(false)]
public ActionResult AddContent(PageContent content, FormCollection formCollection) {}

에게:

[HttpPost, ValidateInput(false)]
public ActionResult AddContent(PageContent pageContent, FormCollection formCollection) {}

DefaultModelBinder는 다시 한 번 내 PageContent 모델 항목에 올바르게 바인딩 할 수있었습니다. 편집보기가 왜이 동작을 표시하지 않았는지 잘 모르겠지만 문제의 출처를 추적했습니다.

이 문제는 "버그"상태에 매우 가깝습니다. "content"가 "pagecontent_"로 접두어가 접두어가 나오기 때문에 내 뷰는 처음에 ViewModel과 함께 작동했지만 이와 같은 핵심 프레임 워크 기능/버그는 IMHO가되지 않아야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top