1

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

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

但是,当我尝试从 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 操作过滤器有关。我如何调试问题出在哪里?

更新 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;
    }
}
4

1 回答 1

3

路由并不是真正的微风问题。您的服务器如何将请求路由到您的控制器取决于您。我们开箱即用的方法只是众多方法中的一种。

你的控制器上有这个[BreezeController]属性是吗?你能把一个示例端点放在我们可以点击它的地方吗?或许能从中得到一些线索。还要发布控制器。一个小例子应该做......一些返回元数据和一个返回 IQueryable 的方法。

2013 年 6 月 25 日更新

我想你在我们的方式中发现了一个错误[BreezeController]发现方法返回IQueryable<T>的方式中发现了一个错误。

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

[BreezeQueryable]是 Web API 的扩展[Queryable],增加了对 $select、$expand 和嵌套 $orderby ... 的支持,所有这些都从当前[Queryable].

我现在看到您的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=

于 2013-06-12T19:21:22.350 回答