我试图在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#note01和http://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;
}
}
答案 0 :(得分:3)
路由不是真正的Breeze问题。您的服务器如何将请求路由到您的控制器取决于您。我们开箱即用的只是无数人中的一种方式。
您的控制器上有[BreezeController]
属性是吗?你能把一个样本端点放到我们可以触及它的地方。可能会从中获得一些线索。也发布控制器。一个小例子应该做...返回元数据的东西和一个返回IQueryable的方法。
我认为您发现了[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);
}
我确认此方法确实有效。
感谢您找到这个。
一位同事还注意到您的查询URL不使用OData查询语法。你写道:
... /todos?=DareId%20eq%204
什么时候应该
... /todos/?$filter=DareId%20eq%204
确保使用?$filter=