【问题标题】:Multiple IQueryable in one controller?一个控制器中有多个 IQueryable?
【发布时间】:2012-05-16 18:25:44
【问题描述】:

我的整个数据库都有一个控制器,代码如下:

public class YogaController : DbDataController<Yoga.Models.YOGAEntities>
{
    public YogaController()
    {
    }

    public IQueryable<Yoga.Models.Action> GetActions(int BugId)
//GetActions retrieves "actions" table from the db, not Actions in MVC term 
    {
        return DbContext.Actions.Where(x => x.FK_BugsID == BugId);
    }
    public IQueryable<Yoga.Models.Label> GetRequiredLabels()
    {
        return DbContext.Labels.Where(x => x.IsRequired == true);
    }
    public IQueryable<Yoga.Models.Role> GetRoles()
    {
        return DbContext.Roles;
    }
    public IQueryable<Role> GetRoles2() //TODO: finish this
    {
        return DbContext.Roles.Where(x => x.RoleID == 1);
    }
    public IQueryable<Tag> GetTags(int actionid)
    {
        return DbContext.Tags.Where(x => x.J_Tags.Any(y => y.FK_ActionID == actionid));
    }
}

如您所见,我在一个控制器中有多个 IQueryable,每个都查询不同的表。这是被禁止的东西吗?因为当我转到localhost/api/Yoga/GetActionslocalhost/api/Yoga/GetRequiredLabels 时,我收到错误消息:

Multiple actions were found that match the request: 
 System.Linq.IQueryable`1[Yoga.Models.Label] GetRequiredLabels() on type Yoga.Controllers.YogaController
 System.Linq.IQueryable`1[Yoga.Models.Role] GetRoles() on type Yoga.Controllers.YogaController
 System.Linq.IQueryable`1[Yoga.Models.Role] GetRoles2() on type Yoga.Controllers.YogaController

当我禁用除一个 IQueryable 之外的所有 IQueryable 时,结果很好。

我搜索过类似问题并检查了我的路由设置,控制器路径和名称没有冲突。

我的路线(默认生成):

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        //routes.MapRoute(
        //    name: "Default",
        //    url: "{controller}/{action}/{id}",
        //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

有什么想法吗?

【问题讨论】:

  • 为什么要返回 IQueryable 作为操作方法的返回类型?
  • 这是我看到的使用 MVC4 的教程:goo.gl/mqzDD 前端使用 upshot.js 并直接处理 IQueryable。我不太确定确切的机制
  • 返回 IQueryable 允许您在该操作的查询字符串中使用 OData 过滤器和选项
  • 谢谢。没想到!
  • 如果你是新手,我会说坚持传统的方式返回 ActionResult 并使用包含你需要的数据的模型,这样你就不必捏造使用路线等来获得这种自定义行为:)

标签: asp.net asp.net-mvc asp.net-mvc-4 asp.net-web-api


【解决方案1】:

MVC4 可能会将您的 HTTP 动词 (Get) 与名称以“Get”开头且没有参数的所有方法进行匹配。尝试强制操作名称:

[ActionName("GetRequiredLabels")]
public IQueryable<Yoga.Models.Label> GetRequiredLabels()
...
[ActionName("GetActions")]
public IQueryable<Yoga.Models.Action> GetActions(int BugId)
... // etc

编辑:

根据您粘贴的路线和控制器,我认为您的路线应该是:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

即它应该有{action} 在那里。如果您只有一个“获取”方法,则默认的 MVC4 路由将起作用。由于您有多个,因此您必须强制它根据路线选择动作。

【讨论】:

  • 刚试了一下,还是一样的错误。我尝试包含参数localhost/api/Yoga/GetActions?BugId=1,但它根本找不到动作:No action was found on the controller 'Yoga' that matches the request.
  • 这绝对不是因为您有多个返回 IQueryable 的操作,因为我有执行相同操作的控制器。你能发布你的路线吗?
  • 太棒了!谢谢你,先生,它就像一个魅力:) MVC4 默认情况下没有在控制器中包含多个动作的路由,这让我有点惊讶。
  • 很高兴听到! MVC4 默认路由仅处理控制器的基本 CRUD 操作。假设您有一个ProductContoller,您可以使用四个 HTTP 动词中的任何一个点击localhost/api/product,然后这些动词将路由到与这些动词匹配的方法。不过你是对的,默认情况下它不允许更微妙的路线
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 2015-06-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
相关资源
最近更新 更多