2010-02-06 1 views
18

편집 : (있는 경우) 내가 MVC3 솔루션을 추구하고 있습니다 때문에 추가 현상금이 아닌 다른 :왜 ASP.NET MVC는 데이터 바인딩 중에 읽기 전용 속성에 관심이 있습니까?

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = 거짓;


나는 나의 '주소'모델 'CityStateZip'에 읽기 전용 속성이 있습니다.

그것은 도시, 주, 미국 주소의 우편 번호를 얻기 위해 단지 편리한 방법입니다. 국가가 미국이 아니면 예외가 발생합니다 (호출자가 먼저 확인해야 함). 바인드됩니다 있도록

public string CityStateZip 
    { 
     get 
     { 
      if (IsUSA == false) 
      { 
       throw new ApplicationException("CityStateZip not valid for international addresses!"); 
      } 

      return (City + ", " + StateCd + " " + ZipOrPostal).Trim().Trim(new char[] {','}); 
     } 
    } 

이 내 모델의 일부입니다. ASP.NET MVC2 RC2 이전에는이 ​​필드가 데이터 바인딩 중에 문제를 일으키지 않았습니다. 나는 그것에 대해 정말로 생각조차하지 못했습니다. 결국 그것은 오직 읽기 전용입니다.

지금 2010 년 1 월 RC2 출시와 함께 나에게 데이터 바인딩 중에 오류 제공하지만 - 기본 모델 바인더를 변경할 수 없기를 (이 읽기 전용 되더라도)이 값을 검사 할 것으로 보인다.

그것은이 오류를 발생시키는 'base.OnModelUpdated'라인은 트리거 될 것입니다.

public class AddressModelBinder : DefaultModelBinder 
{ 
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     base.OnModelUpdated(controllerContext, bindingContext); 

마지막 분은 분명히 행동의 변화를 일으킨 ModelBinder를로 변경 -하지만 난 아직 그것의 repurcussions이 무엇인지 확실히 모르겠어요 - 또는 여부 이것은 버그가? 나는 이것을 MVC 팀에 전달하지만, 그 사이에 누군가가 어떤 제안을 가지고 있다면이 속성이 바인딩되지 못하도록 막을 수 있는지 궁금 할 것입니다.

이 문서

은 변화를 읽을 가치가있다 -하지만 (나는 그것에을 기대하지 않는 것이) 모두에서 읽기 전용 특성을 언급하지 않습니다. 이 문제 (이 경우)가이 상황보다 더 광범위 할 수 있습니다 - 나는 어떤 반향에 대해서도 확신 할 수 없습니다 - 만약 있다면!

단순히 어떤 모델에 다음 행을 추가하고 해당 조치 방법에 게시물을하여 얻을 : 여기 @haacked의 요청에 따라

Input Validation vs. Model Validation in ASP.NET MVC


는 스택 트레이스입니다. 이 예에서는 가능한 가장 단순한 모델에 추가했습니다.

public string Foo { get { throw new Exception("bar"); } } 

[TargetInvocationException : 오브젝트 Rolling_Razor_MVC.Models.ContactUsModel '에 대한 속성 접근'갑 '이 다음과 같은 예외가 발생했습니다'바 '] System.ComponentModel.ReflectPropertyDescriptor.GetValue (객체 성분) + 390 System.Web.Mvc. < > c__DisplayClassb. <GetPropertyValueAccessor> b__a() +18 System.Web.Mvc.ModelMetadata.get_Model() +22 System.Web.Mvc.ModelMetadata.get_RealModelType() +29 System.Web.Mvc. <GetValidatorsImpl> d__0.MoveNext() +38 을 System.Linq. <SelectManyIterator> d__14`2.MoveNext() 273 System.Web.Mvc. < > d__5를 확인하십시오.MoveNext는() 644 System.Web.Mvc.DefaultModelBinder.OnModelUpdated (ControllerContext controllerContext, ModelBindingContext BindingContext를) +92 System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel (ControllerContext controllerContext, ModelBindingContext BindingContext를, 개체 모델) +60 System.Web .Mvc.DefaultModelBinder.BindComplexModel (ControllerContext controllerContext, ModelBindingContext의 BindingContext) 1048 System.Web.Mvc.DefaultModelBinder.BindModel (ControllerContext controllerContext, ModelBindingContext의 BindingContext) 280 System.Web.Mvc.Controller.TryUpdateModel (tModel을 모델 문자열 접두어 , String [] includeProperties, String [] excludeProperties, IValueProvider valueProvider) +449 System.Web.Mvc.Controller.TryUpdateModel (TModel 모델) +73

+0

입니다 Global.asax.cs 다음 추가해야합니다 문제

protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType, string propertyName) { var metadata = base.CreateMetadataPrototype(attributes, containerType, modelType, propertyName); if (metadata.IsReadOnly) { metadata.IsRequired = false; } return metadata; } protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor) { var metadata = base.CreateMetadataFromPrototype(prototype, modelAccessor); if (prototype.IsReadOnly) { metadata.IsRequired = false; } return metadata; } 

피해 갈 내 솔루션에 다음과 같은 모델 메타 데이터 공급자를 추가 정확한 오류는보고 있습니까? 관련 컨트롤러 및보기 코드를 보는 것도 도움이됩니다. –

+0

더 자세한 정보가 필요하지만 예외가 발생하도록 해당 속성을 읽으려고하면 IsUsa가 false가됩니다. 그러나 게시되는 양식에 "CityStateZip"이라는 양식 필드가없는 한 모델 바인딩 중에 왜 책을 읽는지 확신 할 수 없습니다. – Haacked

+0

@brad 음, 정확한 오류는 'CityStateZip이 국제 주소로 유효하지 않습니다!'입니다. ;-) 전체 스택 추적으로 질문을 업데이트하고 있습니다. 복제하려면 기존 모델에 추가하고 해당 조치 메소드에 POST하십시오. public string Foo {get {throw new Exception ("bar"); }} –

답변

16

나는 비슷한 문제가 발생한다고 생각합니다. (URL 위에서) MVC 팀의 응답 :

http://forums.asp.net/t/1523362.aspx


편집 : 나는 세부 사항을 게시 한

우리는이 문제를 조사하고 검증 시스템이 작동되는지 결론을 내렸다 예상했다. 모델 유효성 검사는 모든 속성에 대해 유효성 검사를 실행하고 null이 아닌 값 유형 속성에 암시 적 [필수] 속성이 있으므로이 속성의 유효성을 검사하고 해당 프로세스에서 getter를 호출합니다. 우리는 이것이 제품 V1의 주요 변경 사항이지만 새로운 모델 검증 시스템을 올바르게 작동시키는 것이 필요하다는 것을 알고 있습니다.

이 문제를 해결할 수있는 몇 가지 옵션이 있습니다. 이들 중 하나는 작동해야합니다.

  • 날짜 속성을 속성 대신 메서드로 변경하십시오. 이 방법은 MVC 프레임 워크에서 무시됩니다.
  • 속성 유형을 DateTime으로 변경 하시겠습니까? DateTime 대신. 그러면이 속성에서 암시 적 [필수]이 제거됩니다.
  • 정적 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes 플래그를 지 웁니다. 그러면 응용 프로그램 전체에서 nullable이 아닌 모든 값 유형 등록 정보에서 내재적 인 [Required]가 제거됩니다. 우리는 V3 제품에 "바인딩하지 않고 유효성을 검사하지 않고 단지이 속성이 존재하지 않는 것처럼 보입니다"라는 메시지를 우리에게 보낼 속성을 추가하는 것을 고려 중입니다.

보고서를 다시 보내 주셔서 감사합니다.

+0

위 게시물에 대한 답변을 확인하십시오. – Rudy

+1

이 두 가지 사항은 내 재산이 읽기 전용 이었기 때문에 '획득'할 필요가 없다는 사실입니다. 그래서이 솔루션은 약간 내 디자인을 망쳐 놨지만, 여전히 해결 방법은 작동합니다.두 번째로 이것은 어쨌든 예외로 인해 폭발하는 것입니다. 확실히 좋지 않은 thats. 모델이 실패하더라도 모델은 실패하지만 불어 난 것은 좋지 않습니다. –

+0

나는 똑같은 문제를 겪고 있습니다. 원하는 경우 내 답장 게시물을 읽어보십시오. 나는 v2에 너무 많은 미해결/누락 요소가 있기 때문에 mvc v3을 기다리고 있습니다.이 기능과 웹 페이지의 다른 물리적 영역을 업데이트하는 여러보기를 반환하는 기능, 더 나은 사용자 지정 서버 측 유효성 검사 지원 등등 ... 현재이 문제를 해결할 수 있지만 '해킹'만 사용하면 mvc를 사용하여 느껴야하는 코딩의 우아함을 느끼지 못합니다. (- v3을 기다릴 수 없습니다.) –

0

물론 CityStateZipGetCityStateZip()으로 변환 할 수는 있지만 실버 라이트와 같은 것으로 쉽게 바인딩 할 수는 없습니다. 이 문제가 발생한 다른 모든 사람들을위한 임시 수정 프로그램이 작동 할 수 있습니다.

0

나는 똑같은 문제가 있습니다!

내 문제에 대한 자세한 내용은, 당신은 방문 할 수 ASP.NET MVC 2.0 Unused Model Property being called when posting a product to the server?

가에 따라 속성/설정 초기화 우리는 그들이 예기치 않게 호출 될 것이다라는 가정에 우리의 속성을 프로그래밍하기 위해 필요한이 평균 (전에 않습니다 등) ... 만약 그렇다면, 이것은 프로그래밍 실습의 변화를 나타내며 진행 방법을 알고 싶습니다.

그 사이에 문제를 해결하는 간단한 'if'확인 만 있습니다.

+1

일반적으로 속성은 그럴 것입니다. - 바보 같은 속성. 당신이 거기에 너무 많은 비즈니스 로직을 가지고 있다면 당신은 변화를해야 할 것입니다,하지만 어쨌든해야합니다. 그들이 부끄러움을 그들은 어떤 종류의 '재산을 확인'속성을 추가하지만 아마 올 것이다 MVC3에 대한 –

2

여전히 MVC3에서 동일한 문제가 있습니다.

나는 (SevenCentral의 대답에서) 가장 좋은 방법은 Global.asax에에에 그냥이에 생각 :

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; 

이 그들

0

나는 비슷한 문제가되었다하는 모두를 위해 사용할 수 없게됩니다 필드에 양식이 컨트롤러에 다시 게시 될 때 유효성이 확인되지 않았던 오류가 발생했습니다. 인터넷 검색 후, 나는 이름 충돌이 문제를 일으킬 수 있다고 지적한 http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/을 발견했다.

내 포스트 백 변수 클래스에 충돌하는 속성 이름이 있다고 생각하지는 않지만 오류를 수신 한 속성의 이름을 바꾸면 내 문제가 해결됩니다.

1

세상의 모든 것을 저에게 알려줍니다. ModelBinder가 읽기 전용 속성을 검사해야하는 이유를 완전히 이해할 수 없습니다 (일부 기술적 인 부분이있을 수 있지만, 분명히 이해하지 못하고 시간을 보내려하지 않습니다).

나는 또한 무엇

protected void Application_Start() 
{ 
    ModelMetadataProviders.Current = new RESModelMetadataProvider(); 
    ModelBinders.Binders.Add(typeof(SmartDate), new SmartDateModelBinder()); 

    ... 
} 
+0

신난다, 이것은 받아 들여진 응답이어야한다 : 근원에 문제를 완전하게 해결하십시오 .MVC의 최신 버전은'GetMetadataForProperty' 다른 방법 이름이 있습니다. 당신이'보호 된 재정의 '를 입력하면 VS는 자동적으로 그루터기를 생성 할 수 있습니다. if 문을 추가하면됩니다. – David784