2013-03-28 7 views
1

컨트롤러의 동작 메서드에 사용자 지정 필터를 전달하고 싶습니다. 그런 식으로 정의하려고합니다. 내가 작업을 실행할 때컨트롤러 작업에 대리인을 전달할 수 있습니까?

public ActionResult GetResult(Func<Fault,bool> filter) 
{ 
    List<Fault> faultList; 
    using (var _context = new myDB()) 
    { 
     faultList = 
      from f in _context.Faults 
      where filter(f) 
      select f; 
    } 
    return Json(faultList); 
} 

는하지만 오류이 개체에 대해 정의

어떤 매개 변수가없는 생성자를 얻을 수 없습니다.

System.RuntimeTypeHandle.CreateInstance에서 (RuntimeType이 유형 부울 publicOnly 부울 NOCHECK 부울 & canBeCached, RuntimeMethodHandleInternal & ctor에 부울 & bNeedSecurityCheck) System.RuntimeType.CreateInstanceSlow (부울 publicOnly 부울 skipCheckThis 부울 fillCache, StackCrawlMark &에서 System.Activator.CreateInstance (Type 형식, 부울 nonPublic)의 System.RuntimeType.CreateInstanceDefaultCtor (부울 publicOnly, 부울 skipCheckThis, 부울 fillCache, StackCrawlMark & stackMark)에서 System.Web. System.Web.Mvc에서 Mvc.DefaultModelBinder.CreateModel (ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)입니다. System.Web.Mvc.DefaultModelBinder.BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)에서 System.Web.Mvc.ControllerActionInvoker.GetParameterValue (ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) System.Web.Mvc의 DefaultModelBinder.BindComplexModel (ControllerContext controllerContext, ModelBindingContext bindingContext) .ControllerActionInvoker.GetParameterValues ​​(ControllerContext controllerContext, ActionDescriptor actionDescriptor) System.Web.Mvc.ControllerActionInvoker.InvokeAction (ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext)에서 System.Web.Mvc.MvcHandler의 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext)를 호출합니다. <> c_ DisplayClass6. <> c _DisplayClassb.b_ 5() at System.Web.Mvc.Async.AsyncResultWrapper. <> c _DisplayClass1.b_ 0() at System.Web.Mvc.Async.AsyncResultWrapper. <> c _DisplayClass8 1.b__7(IAsyncResult _) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult System.Web.Mvc.MvcHandler에서 1.End()입니다. <> c_ DisplayClasse.b _d() at System.Web.Mvc.SecurityUtil.b__0 (동작 f), System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust (동작 동작), System.Web.Mvc.Handler.EndProcessRequest (동작 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()에서 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.IHttpAsyncHandler.EndProcessRequest (IAsyncResult 결과)에서 System.Web.Mvc.HttpApplication. ExecuteStep (IExecutionStep 단계, 부울 & 동기화 완료)

이와 비슷한 작업을 수행 할 수 있습니까?

대리인을 전달하지 않으면 다른 방법을 제안 할 수 있습니까?

+1

당신은이 작업에 어떤 데이터를 보내려면 어떻게합니까? 어떻게'Func 필터'가 그 데이터를 만들어 낼 것으로 기대합니까? – nemesv

+0

나는 @ Html.Action ("GetResults", 새로운 {filter = (f => f.TypeID == 1)}) 또는 이와 비슷한 것을 생각하고 있었다. ... – Mortalus

답변

2

나는 당신의 질문을 이해 했으므로 나는 불가능하다고 말하고 싶습니다.

ASP NET MVC 컨트롤러의 작업 방법은 HTTP 요청 (URL 라우팅) 매핑에 대한 진입 점의 일종으로, 수신 된 http 요청 후 Action 메서드가 실행되는 곳입니다. 따라서 메소드의 입력 매개 변수는 사실 http 요청에서 강력한 형식의 객체로 Post 또는 Get 매개 변수를 비 직렬화 (또는 매핑) 한 결과입니다. MVC 프레임 워크는 객체를 생성 할 때 매개 변수없는 생성자를 찾습니다. 참조 유형 인 데이터 컨테이너와 관련됩니다.

또 다른 것은 HTTP 요청을 통해 기능 (논리)을 보내고 NET 대리인에 매핑하는 것입니다. NET은 인터프리터가 아닌 프레임 워크를 컴파일하기 때문에 NET 코드를 텍스트 (예 : C# 코드)로 보내고 위임에 매핑하는 방법이 없습니다. 예를 들어 Action 메소드에서 자바 스크립트 코드를 반환 할 수 있습니다.

런타임에서도 NET 코드를 컴파일 할 수 있다면 (일부 방법이 있음) NET 코드를 Action 메서드에 삽입하면 보안 문제가 발생할 수 있습니다.

0

액션에 위임자를 전달할 수 있는지 여부는 잘 모르겠지만 대체 방법에 대한 제안 사항이 있습니다. 작업에 매개 변수를 전달하고 해당 값을 기반으로 적절한 함수를 filter 대리자에 할당 할 수 있습니다.

public enum Cases { Case1, Case2, Case3 }; 

class Program 
{ 
    private static bool Test1(int test) { return test == 1; } 

    private static bool Test2(int test) { return test == 2; } 

    private static bool Test3(int test) { return test == 3; } 

    public static void Main() 
    { 
     RunTest(Cases.Case1); 
     RunTest(Cases.Case2); 
     RunTest(Cases.Case3); 

     Console.ReadLine(); 
    } 


    private static void RunTest(Cases testCase) 
    { 
     var list = new List<int> {1, 2, 3}; 
     Func<int, bool> del; 

     switch (testCase) 
     { 
      case Cases.Case1: 
       del = Test1; 
       break; 
      case Cases.Case2: 
       del = Test2; 
       break; 
      case Cases.Case3: 
       del = Test3; 
       break; 
      default: 
       throw new InvalidDataException(); 
     } 

     list.ForEach(i => Console.WriteLine(del(i) ? i.ToString() : "--") ); 
    } 
} 
+0

이것은 패스해야만한다. 내 컨트롤러에 대한 필터링 전략, 또한 귀하의 대답은 오류 메시지를 설명하지 않습니다. – Mortalus

0

대리자를 전달하는 데 확실히 가능하다 :

여기에 내 생각을 설명하기 위해 샘플 콘솔 응용 프로그램입니다. 은 내가 위의 코드가 당신에게 예를 제공하고 방향을 따라 진행할 수 있다고 생각

public class MyCommand<T>{ 

Action myAction; 
Func<T, bool> canExecute; 

public MyCommand(Action<T> actionToBeExecuted, Func<T, bool> canExecute) 
{ 
this.myAction = actionToBeExecuted; 
this.canExecute = canExecute; 
} 

public void ExecuteMyCommand<T>(T param) 
{ 
if(this.canExecute(param)) 
    this.myAction(param); 
} 
} 

아래 같은 명령 클래스가 있다고 할 수 있습니다.

+0

미안하지만,이 복용량은 내가 MVC에 가지고있는 투쟁에 도움이 안된다. MVC가 나에게 오류를주는 이유를 이해하지 못하는 델리게이트를 전달하는 것이 가능하다는 것을 알고있다. – Mortalus

0

시도한 작업이 엄격하게 가능하지는 않지만 유사한 작업을 수행하는 방법이 있습니다.

HTTP 요청에서 Func을 전달하지 않고 Func을 테스트 및 기타 목적으로 코드의 이음새로 사용합니다. 나는 같은 문제에 부딪 쳤지 만 다른 매개 변수로 메소드를 오버로드함으로써 해결했습니다.

여기에 내가 가진 무엇 : @Bronek는 그의 대답에 명시된 바와 같이

public class SomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult SomeAction(string q, Func<string, SomeResultType> fn = null) 
    { 
     fn = fn ?? SomeDefaultFn; 
     ... 

     return View(...); 
    } 
} 

이는 이유로 작동하지 않았다. 그러나, 어쨌든 기본값을 제공하기 때문에 메소드 서명에 과부하가 걸리는 단순한 문제였습니다. 내가 좋아하는 뭔가를 다른 곳에서

public class SomeController : Controller 
{ 
    [HttpGet] 
    public Action SomeAction(string q) 
    { 
     // mvc will execute this action and pass 
     // my default off to the next method 
     return SomeAction(q, SomeDefaultFn); 
    } 

    public ActionResult SomeAction(string q, Func<string, SomeResultType> fn) 
    { 
     ... 
     return View(...); 
    } 
} 

다음

public class SomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult SomeAction(string q, string filterType) 
    { 
     return SomeAction(q, FilterFactory.Build(filterType)); 
    } 

    ... 
} 
관련 문제