2016-06-30 3 views
2

조치 결과가 실행되기 전에 실행될 사용자 정의 ActionFilter를 작성하려고합니다. 이 속성은 TempData에 저장된 오류 정보를 가져 와서 강하게 유형이 지정된 주요 모델 내의 하위 모델 (ErrorModel)에 삽입합니다. 그러나 모든 모델에 오류 하위 모델이 포함 된 다른 작업 유형에 적용 할 수 있기를 원합니다. 이러한 이유로 특정 필터를 특정 ViewModel에 묶을 수는 없습니다.OnResultExecuting에서 서브 모델 내용을 설정하는 방법은 무엇입니까?

해당하는 경우 ErrorModel은 IEnumerable < ErrorViewModel>입니다.

이것은 처음으로 ActionFilters에서 작업 한 것이므로 어둠 속에서 촬영하는 것 같습니다. 리플렉션에 꽤 새로워졌습니다. 나는 비밀이 단순히 적절하게 항해하고 있다는 느낌을 가지고 있습니다.

예외 정보 : System.Reflection.TargetException : 개체가 대상 유형과 일치하지 않습니다를 코드로

나는 마지막 줄에 오류가 점점 오전, 아래 그림과 같이.

ActionFilter를 사용하여 다양한 모델에서 공유되는 하위 모델에 값을 삽입하려면 어떻게해야합니까? 아니면 더 좋은 방법이 있습니까? 당신은 본질적으로 무엇을 가지고

public class SetErrorModelAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     var model = filterContext.Controller.ViewData.Model.GetType(); 
     var errorModel = model.GetProperty("ErrorModel"); 
     errorModel.SetValue(errorModel, filterContext.Controller.TempData["Errors"] as IEnumerable<ErrorViewModel>); 
    } 
} 

답변

0

Type model = filterContext.Controller.ViewData.Model.GetType(); 
PropertyInfo errorModel = model.GetProperty("ErrorModel"); 
errorModel = tempData as IEnumerable<ErrorViewModel> 

예외 정보입니다 : System.Reflection.TargetException : 개체는 대상 유형을

일치하지 않습니다하지만 당신은 반사를 건너 뛸 수 있습니다. 뷰 모델에 공통 인터페이스를 사용하고 뷰 모델이 인터페이스를 구현하는지 확인할 수 있습니다.

public interface IErrorViewModel 
{ 
    IEnumerable<ErrorViewModel> Errors { get; set; } 
} 

public MyViewModel : IErrorViewModel 
{ 
    public string Name { get; set; } 
    public IEnumerable<ErrorViewModel> Errors { get; set; } 
} 


public class SetErrorModelAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     IErrorViewModel model = filterContext.Controller.ViewData.Model as IErrorViewModel; 
     model.Errors = filterContext.Controller.TempData["Errors"] as IEnumerable<ErrorViewModel>; 
    } 
} 

그리고 사용

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     TempData["Errors"] = new List<ErrorViewModel> 
     { 
      new ErrorViewModel { ErrorDescription = "Not enough cowbell" }, 
      new ErrorViewModel { ErrorDescription = "Too much cowbell" } 
     }; 

     return RedirectToAction("Error"); 
    } 

    [SetErrorModel] 
    public ActionResult Error() 
    { 
     return View("Index", new MyViewModel { Name = "Cowbell" }); 
    } 
} 
+0

내가 상관없이 입력하거나 다른 내용이 없습니다 ... filterContext.Controller.ViewData.Model 즐겁게 IErrorViewModel에서 파생 어떤 모델을 반환 이해 확인하십시오. 그런 다음 model.Errors를 사용하면 해당 하위 모델에 액세스 할 수 있으며 그 하위 모델에 할당 할 수 있습니까? – Abigail

+1

'filterContext.Controller.ViewData.Model'은'IErrorViewModel'에 던져 넣는'Object' 타입이고 뷰 모델이이 인터페이스를 구현한다고 가정하기 때문에 액션 필터에서 인터페이스의 속성을 사용할 수 있습니다. – Jasen

+0

감사합니다. 훨씬 더 깨끗하고 확실히 읽을 수 있습니다. 여전히 인터페이스의 유연성에 감사드립니다! – Abigail

관련 문제