2016-06-28 1 views
1

ASP.NET MVC 5 응용 프로그램에서 작업 중이며 프로젝트 소유자는 nullable이 아닌 형식의 유효성 검사로 인해 발생하는 "게시 부족"문제에 대해 우려하고 있습니다. (http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.htmlhttp://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api에 언급 된대로).nullable 유형 (Int32)에 대한 ASP.NET MVC 5 모델 유효성 검사

ASP.NET MVC 5에서이 문제를 재현하기위한 테스트 케이스를 만들었지 만 운이 좋지는 않습니다.

모델 :

public class ContactModel 
{ 
    [Required] 
    public Int32 data1 { get; set; } 

    public Int32 data2 { get; set; } 
} 

보기 :

<div class="form-group"> 
    @Html.LabelFor(model => model.data1) 
    <div> 
     @Html.EditorFor(model => model.data1) 
    </div> 
</div> 
<div> 
    @Html.LabelFor(model => model.data2) 
    <div> 
     @Html.EditorFor(model => model.data2) 
    </div> 
</div> 

컨트롤러 :

public ActionResult Index(Models.ContactModel contact) 
{ 
    if (ModelState.IsValid) 
    { 
     Response.Write("modelstate is valid<br>"); 

     return View(); 
    } 
    else 
    { 
     Response.Write("modelstate is invalid<br>"); 

     return View(); 
    } 
} 

그것은 보인다 data1data2이 게시물에 null의 경우, 모델에서 그 값 (contact)은 0이됩니다. 그러나 ModelState.IsValid는 0이됩니다. lso는 입니다. (대신이 두 개의 기사에 나와 있습니다).

내가 무엇을 가지고 :

enter image description here

두 번째 기사는 보여 주었다 무엇 :

enter image description here

내가 ASP.NET에서 어떻게 작동하는지 모델 검증의 변경에 관한 정보를 찾을 수 없습니다 MVC, 그래서 나는 내 테스트 케이스에 뭔가 잘못했다고 생각한다. 어떤 생각이나 제안도 환영합니다.

+2

'int' 속성은'(필수)'속성을 필요로하지 않습니다. (사용자 정의 에러 메시지를 원하지 않는다면)'int'는 결코'null'이 될 수 없습니다. 'DefaultModelBinder'는'int'에'null'을 할당 할 수없고'ModelState.IsValid = false'를 설정하기 때문에 오류를 추가합니다. 하지만 그 값은'int'의 기본값 인'0'입니다. –

+0

@StephenMuecke 그게 처음에 생각한 것입니다. 그러나 브래드 윌슨 (나의 질문에 첫 번째 링크) 게시물에 따르면 : _ 이것의 off-shoot는 nullable 값 유형에 대한 [Required]는 폼에 값이 포함되었음을 보증 할 수 없다는 것입니다. 값이 포함되어 있지 않으면 모델 바인딩이 생략되므로 모델 바인딩 오류가 발생하지 않습니다. 또한 [필수] 유효성 검사기를 실행하면 값 유형 기본값 (일반적으로 0)이 포함될 모델에서 값을 쿼리하고 "null이 아니며 모든 것이 모두 여기에 적합합니다!" – Jim

+0

틀렸고 모델 바인딩을 건너 뛰지 않았습니다. 값 유형이거나'[Required]'속성을 가진 참조 타입 인 경우에는 'ModelState.IsValid'가 항상 false가됩니다. –

답변

1

게시자가 모델의 각 속성에서 양식 값을 제공하고 있기 때문에 ModelState가 false 인 이유가 있습니다. 본질적으로 모델 바인딩 시스템은 @ Html.EditorFor 도우미 을 명시 적으로으로 작성하여 data1 및 data2 필드의 유효성을 검사합니다 (보기에 두 속성 모두에 대해 작성되었으므로 과소 평가는 실제로 수행되지 않습니다).

기사에서 under-posting concern을 성공적으로 복제했습니다. 보기에서 EditorFor 헬퍼 중 하나를 제거하기 만하면 실제로 밑 부분 처리됩니다. 두 헬퍼가 모두 참석할 때 진행되는 과소 평가가 없습니다.

보기 :

<div class="form-group"> 
    @Html.LabelFor(model => model.data1) 
    <div> 
     @Html.EditorFor(model => model.data1) 
     @Html.ValidationMessageFor(model => model.data1) 
     @Html.ValidationMessageFor(model => model.data2) 
    </div> 
</div> 

가 @Html을 떠날 확인을 그래서보기 (두 속성은 무슨 일이 일어나고 있는지에보기에서 피드백을 얻을 수 있도록 나는 검증 도우미를 추가 참고) 이제 다음과 같습니다. Editor for data2 속성에 대한 헬퍼를 완전히 해제합니다. 이제 폼 필드에서 0을 채우십시오 (당연히 하나의 양식 필드 만 볼 수 있습니다). 그리고 작업에 게시하십시오.

하나의 양식 필드 만 게시되는 경우에도이 시나리오에서는 ModelState가 다시 true로 반환됩니다. 누군가가 underpost 않으면 좋은 결과!그래서 여기에 (약간 수정 된) 원본 모델 클래스가 있는데, 양식 필드가 양식에서 제외 된 경우에 과소 발급 문제가 발생합니다 (두 속성이 모두 값 유형이므로 필수 속성은이 상황에서 차이를 만들지 않습니다) :

//You could add the Required attribute or not, doesn't matter at this point. 
//The concern here is that the Modelstate will still come back as Valid 
//in the case of a form field being left off of your form (or someone underposts). 
//So to replicate underposting issues, make sure to comment or delete 
//at least one Html.EditorFor helper in the view. 

//[Required] Underposting will occur regardless if this is marked required or not, 
//so be careful if someone does underpost your form. 
public Int32 data1 { get; set; } 

//[Required] 
public Int32 data2 { get; set; } 

이제 underposting 문제를 해결하려면 솔루션 : 필요에 따라 단순히 두 속성을 표시를하고, 제공 그래서 같은 기사에서 언급 한 바와 같이 그들이 널 (NULL)합니다 이제

[Required] 
public Int32? data1 { get; set; } 

[Required] 
public Int32? data2 { get; set; } 

때 보기가 누락 된 @ Html.EditorFor 도우미 또는 누락 된 양식 필드 인 ModelState V 알리 테이션은 거짓으로 돌아오고, 당신은 과소 발간되는 문제로부터 보호받습니다.

+0

감사합니다. 이것은 매우 유망한 것으로 들립니다. 나는 오늘 나중에 이것을 복제하려고 노력할 것이고, 그것이 작동한다면 답을 표시 할 것이다. – Jim

+0

굉장한 짐. 내가 디버거를 통해 그것을 실행하고 동작을 확인, 그래서 모든 일을해야합니다. 그것에 대해 질문이 있으면 알려주세요. 그건 그렇고, 네 질문에 다가와서 기뻐. 그 Required 속성은 오도 될 수 있으며 조심하지 않으면 갑자기 속성을 기본값으로 설정할 수 있습니다. 고마워, 팀 – firecape