0

매개 변수가없는 조치 방법이 있습니다.나중에 ASP.NET MVC의 모델 바인딩 : QueryString 값을 뷰 모델로 변환하는 방법은 무엇입니까?

QueryString 컬렉션에는 내 모든 값이 포함되어 있습니다. QueryString의 키가 내보기 모델 속성과 일치합니다.

var queryStringValueProvider = new QueryStringValueProvider(ControllerContext); 
var providerResult = queryStringValueProvider.GetValue(ValidationKeys.Id); // ?! 

var viewModelTypeName = queryString[ValidationKeys.ViewModelType]; 

var viewModelType = Type.GetType(viewModelTypeName); 
var viewModelInstance = providerResult.ConvertTo(viewModelType); // throws an InvalidOperationException 

QueryString 컬렉션을 뷰 모델로 변환하려면 어떻게해야합니까? ASP.NET MVC는 이미 뷰 모델을 작업 메서드 매개 변수로 전달할 때이 작업을 수행합니다. 그래서 내가 필요로하는 것은 이다. ASP.NET MVC 메카닉을 사용하여 모델 바인딩을 만든다.

+0

이 귀하의 질문에 대답 수 준 :

은 한 번보세요. http://stackoverflow.com/questions/627838/asp-net-mvc-getting-querystring-values ​​ – Ademar

+0

@Ademar 아니요. 매개 변수 이름/특성 이름은 런타임에만 알려집니다. RemoteAttribute 특성을 사용하여 사용자 입력 데이터의 유효성을 검사하려고합니다. 고유해야하는 속성에 대한 원격 유효성 검사를 처리하는 단일 작업 메서드가 필요합니다. – Rookian

답변

0

내 컨트롤러 액션

var viewModelTypeName = queryString[ValidationKeys.ViewModelType]; 
var viewModelType = Type.GetType(viewModelTypeName); 
var instance = Activator.CreateInstance(viewModelType); 
UpdateModelUsingQueryString(instance); 

UpdateModel

protected internal void UpdateModelUsingQueryString<TModel>(TModel model) where TModel : class 
{ 
    if (model == null) throw new ArgumentNullException("model"); 

    Predicate<string> propertyFilter = propertyName => new BindAttribute().IsPropertyAllowed(propertyName); 
    var binder = Binders.GetBinder(typeof(TModel)); 

    var bindingContext = new ModelBindingContext() 
    { 
     ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()), 
     ModelState = ModelState, 
     PropertyFilter = propertyFilter, 
     ValueProvider = new QueryStringValueProvider(ControllerContext) 
    }; 
    binder.BindModel(ControllerContext, bindingContext); 
} 

를 사용할 수있는 문제였다 UpdateModel 또는 012 그은 의도적으로이 작동하지 않습니다. 두 방법 모두 typeof(TModel)을 사용합니다. 하지만 model.GetType()을 사용해야합니다. Model Binding - Type in External Assembly

가 대린 디미트로프가 정답 :

0

사용자 지정 모델 바인딩을 수동으로 수행하려면 사용자 지정 모델 바인더를 만들고 (IModelBinder 구현) IoC 컨테이너에 등록하십시오.

또는 조치 방법 내부에서 this.UpdateModel으로 전화 할 수 있습니다. ValueProvider (RouteData, Request.Form 컬렉션 및 QueryString)의 값을 모델에 바인딩해야합니다.

+0

IoC는 내 질문과 어떤 관련이 있습니까? – Rookian

+0

MVC는 IoC 컨테이너를 사용하여 모델 바인더를 해결합니다. 자신 만의 모델 바인더를 만들면 IoC 컨테이너에 등록해야합니다. –

+0

왜 내 모델 바인더를 써야합니까? – Rookian

0

당신이 원하는 것은 직렬화입니다. 이 작업을 간단히 수행하기 위해 QueryStringValueProvider를 인수로 사용하는 생성자 오버로드를 넣을 수 있으며 해당 생성자는 공급자를 기반으로 모든 모델의 속성을 초기화해야합니다. 문자열에 집착하면 모든 모델에서 상속받을 수있는 모델 기본 클래스에 이러한 생성자를 매우 쉽게 넣을 수 있습니다.

이것은 또한 확장 메서드에 내장되어 건설 중에 "주문형"이라고 부를 수 있습니다.

0

당신은 TryUpdateModel

public ContentResult TestAction() 
{ 
    var model = new MyModel(); 

    if(TryUpdateModel(model, new QueryStringValueProvider(ControllerContext))) 
    { 
     return Content("success"); 
    } 

    return Content("failed"); 
} 
+0

본인이 직접 시도 했습니까? – Rookian

+0

@Rookian 당신은 질문에 대답했습니다. 시도 할 때까지 당신에게 달려 있습니다. – VJAI

+0

그럼 TryUpdateModel 모델이 잘 작동한다는 것을 안다면. 그러나 모델은 모르지만 그 모델은 그 모델입니다. – Rookian