控制器不在DotNetNuke模块的Breeze查询中过滤数据

时间:2013-06-11 13:28:19

标签: asp.net-web-api dotnetnuke breeze

我试图在DotNetNuke模块中包含基本的Breeze示例(它在独立的WebAPI项目中工作正常)。为了简化操作,我删除了客户端,并且只是引用了我在Chrome浏览器中进行的JSON调用。

我可以看到我的元数据和完整的项目列表,例如: http://www.dnndev.me/DesktopModules/framework/api/breeze/dare/metadata http://www.dnndev.me/DesktopModules/framework/api/breeze/dare/todos

然而,当我尝试从URL过滤列表时,它总是返回完整列表,例如 http://www.dnndev.me/DesktopModules/framework/api/breeze/dare/todos?=DareId%20eq%204

我认为这与我宣布MapHTTRoute的方式有关。问题是DotNetNuke模块没有Global.ascx。我已将BreezeWebApiconfig.cs文件复制到我的App_Start文件夹中,这在我调试时会触发,但DotNetNuke使用机制来注册路由:

using DotNetNuke.Web.Api;

namespace SmartThinker.Modules.Framework
{
    public class RouteMapper : IServiceRouteMapper
    {
        public void RegisterRoutes(IMapRoute mapRouteManager)
        {
            mapRouteManager.MapHttpRoute("framework", "BreezeApi", "breeze/{controller}/{action}", new[] { "SmartThinker.Modules.Framework.Controllers" });
        }
    }
}

我已经阅读了http://www.breezejs.com/documentation/web-api-controller#note01http://www.breezejs.com/documentation/web-api-routing,但似乎这与DNN注册路由的方式有关。无论如何不使用BreezeWebApiConfig.cs吗?

我的控制器代码具有BreezeController属性。 (当我将示例客户端连接到它时,我确实得到了一个项目列表 - 它只是没有过滤,所以我认为它与OData Action过滤器有关。我如何调试问题所在?

更新1) 这是元数据: http://www.ftter.com/desktopmodules/framework/api/dare/metadata

GetUsers方法: http://www.ftter.com/desktopmodules/framework/api/dare/getusers

和GetUsers方法尝试按UserID过滤(这不起作用,这是问题) http://www.ftter.com/desktopmodules/framework/api/dare/getusers?=UserID%20eq%204 http://www.ftter.com/desktopmodules/framework/api/dare/GetUsersWithoutCors?=UserID%20eq%204(这会返回IQueryable)

这是控制器:

[BreezeController]
public class DareController : DnnApiController
{
    private readonly EFContextProvider<FrameworkContext> contextProvider = new EFContextProvider<FrameworkContext>();

    [AllowAnonymous]
    [HttpGet]
    public HttpResponseMessage Metadata()
    {
        var response = Request.CreateResponse(HttpStatusCode.OK, contextProvider.Metadata());
        return GetResponseWithCorsHeader(response);
    }

    [AllowAnonymous]
    [HttpGet]
    public HttpResponseMessage GetUsers()
    {
        var userInfoController = new UserInfoController();

        var response = Request.CreateResponse(HttpStatusCode.OK, userInfoController.GetUsers());
        return GetResponseWithCorsHeader(response);
    }

    [AllowAnonymous]
    [HttpGet]
    public IQueryable<User> GetUsersWithoutCors()
    {
        return contextProvider.Context.Users;
    }
}

1 个答案:

答案 0 :(得分:3)

路由不是真正的Breeze问题。您的服务器如何将请求路由到您的控制器取决于您。我们开箱即用的只是无数人中的一种方式。

您的控制器上有[BreezeController]属性是吗?你能把一个样本端点放到我们可以触及它的地方。可能会从中获得一些线索。也发布控制器。一个小例子应该做...返回元数据的东西和一个返回IQueryable的方法。

2013年6月25日更新

我认为您发现了[BreezeController]发现方法返回IQueryable<T> 的方式存在错误。

[BreezeController]属性扫描您的Web API控制器方法,并且(实际上)将[BreezeQueryable]属性应用于返回IQueryable<T>的方法。

  

[BreezeQueryable]是Web API [Queryable]的扩展,它增加了对当前[Queryable]中$ select,$ expand和嵌套$ orderby ...的支持。

我现在看到您的GetUsers()方法返回HttpResponseMessage而不是IQueryable<User>。我们假设您方法中的userInfoController.GetUsers()方法返回IQueryable<User>。否则,OData查询参数将不适用,我们将不得不采用不同的方向。继续......

我查看了Breeze.WebApi.dll的v.1.3.6,它没有检测到HttpResponseMessage正在包裹IQueryable<T>。因此,它不应用客户端的OData查询条件(或任何其他OData修饰符)。这个缺点(在我看来)是一个错误。以下应该是等效的实现:

[HttpGet]
public IQueryable<TodoItem> Todos() {
    return _repository.Todos;
}

[HttpGet]
public HttpResponseMessage TodosWrapped()
{
    return Request.CreateResponse(HttpStatusCode.OK, _repository.Todos);
}

第二个“包装”方法不尊重OData查询参数。

幸运的是,在我们解决这个问题之前,有一个解决方法。只需显式添加[BreezeQueryable]属性,如下所示:

[HttpGet]
[BreezeQueryable]
public HttpResponseMessage TodosWrapped()
{
    return Request.CreateResponse(HttpStatusCode.OK, _repository.Todos);
}

我确认此方法确实有效。

感谢您找到这个。

使用OData查询语法

一位同事还注意到您的查询URL不使用OData查询语法。你写道:

... /todos?=DareId%20eq%204

什么时候应该

... /todos/?$filter=DareId%20eq%204

确保使用?$filter=