ASP.NET MVC가 데이터베이닝 중에 내 읽기 전용 속성에 관심이있는 이유는 무엇입니까?

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

문제

편집 :이 외에 MVC3 솔루션 (존재하는 경우)을 찾고 있기 때문에 바운티 추가 :

DataAnnotationsModelValidatorProvider.AdDimplicitRequiredTributeForValuetypes = false;


내 '주소'모델에 읽기 전용 속성이 있습니다. '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의 마지막 순간 변경은 동작의 이러한 변화를 일으킨 것 같습니다. 그러나 아직 반사가 무엇인지 또는 이것이 버그인지 여부는 확실하지 않습니다. 나는 이것을 MVC 팀에 전달하지만 다른 사람 이이 속성을 구속하는 것을 방지 할 수있는 방법에 대한 제안이 있다면 궁금합니다.

이 기사는 변경 사항에 대해 읽을 가치가 있지만 Readonly 속성을 전혀 언급하지는 않습니다 (내가 기대하지는 않습니다). 문제 (하나가있는 경우)는이 상황보다 더 넓을 수 있습니다 - 나는 어떤 기복에 대해 확신하지 못합니다.

ASP.NET MVC의 입력 유효성 검사 대 모델 유효성 검사


@haacked가 요청한대로 여기에 StackTrace가 있습니다.

나는 단순히 모든 모델에 다음 줄을 추가하고 해당 조치 방법에 게시하여 게시하여 이것을 얻습니다. 이 경우 가장 간단한 가능한 모델에 추가했습니다.

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

TargetInVocationException : 객체의 Property Accessor 'foo' 'rolling_Razor_MVC.Models.ContactusModel' 'Bar'예외를 던졌습니다 : 'Bar'System.componentModel.ReflectPropertyDescriptor.getValue (객체 구성 요소) +390 System.Web.mvc. <> C_DISPlayClassB.u003CGetPropertyValueAccessor> B__A () +18 System.Web.mvc.modelmetadata.get_model () +22 System.Web.mvc.modelmetadata.get_realmodeltype () +29 System.web.mvc.u003CGetValidatorsImpl> d__0.movenext () +38 System.linq.u003CSelectManyIterator> D__14`2.movenext () +273 System.Web.mvc.u003CValidate> d__5.MoveNext() +644 System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +92 System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +60 System.Web. mvc.defaultmodelbinder.bindcomplexModel (ControlLerConText ControlLerContext, ModelBindingContext BindingContext) +1048 System.web.mvc.defaultModelBinder.bindModel (ControlLerConText ControlLeCtix, StriengContext (ModelBindingContext) +280 시스템 .web.C.C.C.C.C.C.C.C.C.C.C.C.C.C.C.C.C.C.ContOconTextInt.BindModel. ] IncludeProperties, String [] ExcludeProperties, IvalueProvider ValueProvider) +449 System.Web.mvc.controller.TryUpDateModel (Tmodel Model) +73

도움이 되었습니까?

해결책

나는 비슷한 문제를 겪고 있다고 생각합니다. 세부 사항을 게시했습니다.

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


편집하다: MVC 팀의 응답 (위에서 URL 위) :

우리는 이것을 조사하고 검증 시스템이 예상대로 작동한다고 결론을 내 렸습니다. 모델 검증에는 모든 속성에 대한 유효성 검사를 실행하려는 시도가 포함되므로, 불가능한 값 유형 속성은 암시 적 [필수] 속성을 가지 므로이 속성을 검증하고 프로세스에서 getter를 호출합니다. 우리는 이것이 제품의 V1에서 파괴 된 변화이라는 것을 이해하지만 새로운 모델 검증 시스템을 올바르게 작동시켜야합니다.

이 문제를 해결할 수있는 몇 가지 옵션이 있습니다. 이 중 하나는 다음과 같습니다.

  • 날짜 속성을 속성 대신 방법으로 변경하십시오. 이렇게하면 MVC 프레임 워크에 의해 무시됩니다.
  • 속성 유형을 dateTime으로 변경 하시겠습니까? DateTime 대신. 이것은이 속성에서 암시 적 [필수]을 제거합니다.
  • 정적 DataannotationsModelValidatorProvider.AdDimplicitRequiredTributeForValuetypes 플래그를 지 웁니다. 이는 모든 무효화가없는 값 유형 속성에서 암시 적 [필수]을 제거합니다. 우리는 제품의 v3에 우리에게 신호를 보내는 속성을 추가하는 것을 고려하고 있습니다.

보고서에 다시 한번 감사드립니다!

다른 팁

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

가장 좋은 방법은 Global.asax (Sevencentral의 답변에서)에서 이것에 대한 것입니다.

 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

이것은 그들 모두에게 비활성화됩니다

이것은 전 세계를 나에게 버그처럼 본다. 모델 바인더가 내 읽기 전용 속성을 확인 해야하는 이유를 완전히 이해할 수 없습니다 (기술이있을 수 있지만 확실히 이해하지 못하고 시간을 보내려고하지 않습니다).

문제를 해결하기 위해 다음 모델 메타 데이터 제공자를 내 솔루션에 추가했습니다.

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;
}

또한 Global.asax.cs에 다음을 추가해야합니다.

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

    ...
}

물론 나는 전환 할 수 있다고 생각합니다 CityStateZip 에게 GetCityStateZip() 그러나 나는 Silverlight와 같은 것에 쉽게 묶을 수 없습니다. 이것은이 문제를 겪는 다른 사람에게 임시 수정에 효과가있을 수 있습니다.

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

내 문제에 대한 자세한 내용은 방문 할 수 있습니다. ASP.NET MVC 2.0 제품을 서버에 게시 할 때 사용되지 않은 모델 속성이 호출됩니까?

이것은 우리가 속성을 예기치 않게 (의존하는 속성이 설정/초기화되기 전에)라고 가정하여 속성을 프로그래밍해야한다는 것을 의미합니까? 진행 방법을 알고 싶습니다.

한편, 나는 단지 문제를 제거하는 간단한 'if'점검이 있습니다.

비슷한 문제가 있었는데, 검증 될 것으로 예상하지 않은 필드는 양식이 컨트롤러에 다시 게시 될 때 오류를 받고있었습니다. 인터넷 검색을 마친 후, 나는 만났다 http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/ 이름의 충돌이 문제를 일으킬 수 있다고 지적한 곳.

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

MVC 5.2.3에는 동일한 문제가 여전히 존재하며 문제를 일으키는 유효성 검사 코드조차도 아닙니다. 그만큼 DefaultModelBinder 읽기 전용 속성이고 요청 데이터가 해당 속성과 일치하는 컨트롤러로 전달되지 않더라도 유효성 검사 코드 외부의 getters를 호출합니다.

보다 자세한 설명과 내 전체 솔루션을 참조하십시오. https://stackoverflow.com/a/54431404/10987278.

해당 솔루션이 MVC 3과 함께 작동하도록 리팩토링 될 수 있는지 확신 할 수 없지만,이 질문에 걸쳐 우연히 발견 된 MVC의 이후 버전에서 다른 사람들이 여전히 같은 문제로 고통받는 다른 사람들에게 도움이 될 수 있기를 바랍니다.

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