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 类型,Boolean publicOnly,Boolean noCheck,Boolean& canBeCached,RuntimeMethodHandleInternal& ctor,Boolean& bNeedSecurityCheck)在 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark 和 stackMark)在 System.RuntimeType.CreateInstanceDefaultCtor (Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark & stackMark) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext,类型 modelType) 在 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext,ModelBindingContext bindingContext) 在 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext , ActionDescriptor actionDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller.ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在系统。 Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler.<>c_BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 在 System.Web.Mvc.ControllerActionInvoker .InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller.ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在 System.Web.Mvc.ControllerBase.System.Web.Mvc。 IController.Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler.<>c_BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 在 System.Web.Mvc.ControllerActionInvoker .InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller.ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在 System.Web.Mvc.ControllerBase.System.Web.Mvc。 IController.Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler.<>c_GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller .ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler。< >c_GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 在 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller .ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler。< >c_InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller.ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController .Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler.<>c_InvokeAction(ControllerContext controllerContext, String actionName) 在 System.Web.Mvc.Controller.ExecuteCore() 在 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 在 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController .Execute(RequestContext requestContext) 在 System.Web.Mvc.MvcHandler.<>c_DisplayClass6.<>c _DisplayClassb.b_ 5() 在 System.Web.Mvc.Async.AsyncResultWrapper.<>c _DisplayClass1.b_ 0() 在 System.Web.Mvc.Async.AsyncResultWrapper.<>c _DisplayClass8 1.b__7(IAsyncResult _) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.End( ) 在 System.Web.Mvc.MvcHandler.<>c_DisplayClasse.b _d () 在 System.Web.Mvc.SecurityUtil.b__0(Action f) 在 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) 在 System。 Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) 在 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult 结果) 在 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute( ) 在 System.Web.HttpApplication.ExecuteStep(IExecutionStep 步骤,Boolean& completedSynchronously)

是否有可能做这样的事情?

如果不是通过代表,你能建议另一种方式吗?

4

4 回答 4

2

据我了解您的问题,我会说这是不可能的。

Controller 中的 ASP NET MVC Action 方法是一种针对映射 http 请求(url 路由)的入口点,其中 Action 方法在收到 http 请求后被触发。因此,该方法的输入参数实际上是将 http 请求中的 Post 或 Get 参数反序列化(或映射)到强类型对象的结果。当 MVC 框架创建对象时,它会寻找无参数构造函数。它涉及引用类型的数据容器。

另一件事是通过 http 请求发送功能(逻辑)并将其映射到 NET 委托。由于 NET 是编译框架而不是解释器,因此无法将 NET 代码作为文本发送(例如 C# 代码)并将其映射到委托(例如,我们可以从 Action 方法返回 javascript 代码)。

最后一件事,即使可以在运行时编译 NET 代码(有一些方法),将 NET 代码注入 Action 方法的可能性也会导致安全问题。

于 2013-05-13T00:23:12.567 回答
0

我不知道是否可以将委托传递给 Action,但我有一个替代方案的建议。您可以将参数传递给操作,并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() : "--")  );
    }
}
于 2013-03-28T06:13:41.717 回答
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);
}
}

我相信上面的代码给了你一个例子,你可以沿着这个方向前进。

于 2013-03-28T10:05:28.180 回答
0

虽然您尝试做的事情并非绝对可行,但有一些方法可以做类似的事情。

我不是在 HTTP 请求中从用户那里传递 Func,而是在我的代码中使用 Func 作为接缝来进行测试和其他目的。我遇到了同样的问题,但通过重载具有不同参数的方法来解决它。

这是我所拥有的:

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

        return View(...);
    }
}

正如@Bronek 在他的回答中所说的那样,这不起作用。但是,因为无论如何我都想提供一个默认值,所以重载我的方法签名只是一件简单的事情。

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

    ...
}
于 2017-02-21T14:31:01.730 回答