控制器在DotNetNuke的模块没有过滤微风中查询数据 [英] Controller not filtering data in Breeze query in DotNetNuke Module

查看:246
本文介绍了控制器在DotNetNuke的模块没有过滤微风中查询数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想包括DotNetNuke的模块中的基本微风样品(它在独立的WebAPI项目正常工作)。为了简化事情,我删除客户端,将只是参考网址JSON调用我做了Chrome浏览器。

我可以看到我的元数据和物品,如的完整列表:
http://www.dnndev.me/DesktopModules/framework/api/breeze /敢/元
http://www.dnndev.me/DesktopModules/framework/api/breeze /敢/待办事项

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

我认为这是值得做的我已经宣布了MapHTTRoute的方式。问题是,DotNetNuke的模块没有Global.ascx。我抄BreezeWebApiconfig.cs文件到我的App_Start文件夹,这样做火,当我调试,但是DotNetNuke的使用机制,为注册路线:

使用DotNetNuke.Web.Api;命名空间SmartThinker.Modules.Framework
{
    公共类RouteMapper:IServiceRouteMapper
    {
        公共无效的RegisterRoutes(IMapRoute mapRouteManager)
        {
            mapRouteManager.MapHttpRoute(框架,BreezeApi,清风/ {控制器} / {行动},新的[] {SmartThinker.Modules.Framework.Controllers});
        }
    }
}

我在 http://www.breezejs.com/documentation读了/ WEB-API控制器#note01 HTTP://www.breezejs。 COM /文档/ Web的API路由但似乎它的东西做DNN注册路由的方式。反正有做到这一点,而无需使用BreezeWebApiConfig.cs?

我的控制器code有BreezeController属性。 (当我做样本客户机连接到它我得到的项目列表 - ?它只是不过滤,所以我认为这是值得的OData的行动过滤器如何调试问题出在哪里。

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

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

和GetUsers方法试图通过用户名进行过滤(不工作,这是问题)
http://www.ftter.com/desktopmodules/框架/ API /敢/ getusers?=用户ID%20eq%204
http://www.ftter.com/desktopmodules/framework/api/dare/GetUsersWithoutCors?=UserID%20eq%204 (此方法返回的IQueryable)

下面是控制器:

[BreezeController]
公共类DareController:DnnApiController
{
    私人只读EFContextProvider< FrameworkContext> contextProvider =新EFContextProvider< FrameworkContext>();    [使用AllowAnonymous]
    [HTTPGET]
    公众的Htt presponseMessage元数据()
    {
        VAR响应= Request.CreateResponse(的HTTPStatus code.OK,contextProvider.Metadata());
        返回GetResponseWithCorsHeader(响应);
    }    [使用AllowAnonymous]
    [HTTPGET]
    公众的Htt presponseMessage GetUsers()
    {
        VAR userInfoController =新UserInfoController();        VAR响应= Request.CreateResponse(的HTTPStatus code.OK,userInfoController.GetUsers());
        返回GetResponseWithCorsHeader(响应);
    }    [使用AllowAnonymous]
    [HTTPGET]
    公开IQueryable的<使用者> GetUsersWithoutCors()
    {
        返回contextProvider.Context.Users;
    }
}


解决方案

路由是不是一个真正的微风问题。你的服务器路由如何要求你的控制器是由你。我们做外的开箱什么是无数当中很多只是一种方式。

您有 [BreezeController] 属性控制器上是吗?你可以把样品端点,在那里我们可以打它。可能会从一些线索。同时发布控制器。一个小小的例子应该做的事...返回的元数据和一个方法返回的IQueryable。

更新2013年6月25日

我认为你在路上发现一个bug我们的 [BreezeController] 发现方法返回的IQueryable< T>

[BreezeController] 属性会扫描你的Web API控制器的方法和(有效)适用的 [BreezeQueryable] 属性回归方法的IQueryable< T>


  

[BreezeQueryable] 是网络API的 [可查询] ,增加了$选择,$支持扩展扩大和嵌套$排序依据......所有从目前缺少 [可查询]


我现在看你的 GetUsers()方法的返回值的Htt presponseMessage ,而不是 IQueryable的<使用者> 。让我们假设你的方法返回在 userInfoController.GetUsers()方法的IQueryable<使用者> 。否则,OData的查询参数将不适用,我们必须借此在不同的方向。顺动...

我检查的Breeze.WebApi.dll的v.1.3.6,并没有检测到的Htt presponseMessage 包裹了 IQueryable的< T> 。因此,它不适用于客户端的OData的查询标准(或就此而言的任何其他的OData改性剂)。这个缺点(在我看来)是一个错误。下面列出的是等同的实现:

[HTTPGET]
公众的IQueryable<&内的TodoItem GT;待办事项(){
    返回_repository.Todos;
}[HTTPGET]
公众的Htt presponseMessage TodosWrapped()
{
    返回Request.CreateResponse(的HTTPStatus code.OK,_repository.Todos);
}

第二,包装法不尊重的OData查询参数。

幸运的是,有一个解决办法,直到我们得到这个固定。只需添加 [BreezeQueryable] 属性明确......在:

[HTTPGET]
[BreezeQueryable]
公众的Htt presponseMessage TodosWrapped()
{
    返回Request.CreateResponse(的HTTPStatus code.OK,_repository.Todos);
}

我证实了这种方法的确实的工作。

感谢找到这个。

使用OData的查询语法

一个同事还注意到,您的查询网址不使用OData的查询语法。您写道:


... /待办事项?= DareId%20eq%204

当它应该是


... /待办事项/?$ =过滤%DareId%20eq 204

请确保您使用?$ =过滤器

I am trying to include the basic Breeze sample in a DotNetNuke module (it works fine in a standalone WebAPI project). To simplify things I remove the client and will just refer to the URL JSON calls I make in the Chrome browser.

I can see my metadata and a full list of items, eg: http://www.dnndev.me/DesktopModules/framework/api/breeze/dare/metadata http://www.dnndev.me/DesktopModules/framework/api/breeze/dare/todos

however, when I try to filter the list from the URL, it always returns the full list, e.g. http://www.dnndev.me/DesktopModules/framework/api/breeze/dare/todos?=DareId%20eq%204

I think it is something to do with the way I have declared the MapHTTRoute. The problem is that DotNetNuke modules do not have a Global.ascx. I have copied the BreezeWebApiconfig.cs file into my App_Start folder and this does fire when I debug, however DotNetNuke uses mechanism for registering routes:

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

I have read up on http://www.breezejs.com/documentation/web-api-controller#note01 and http://www.breezejs.com/documentation/web-api-routing but it seems that it's something to do with the way DNN registers the routes. Is there anyway to do this without using BreezeWebApiConfig.cs?

My controller code has the BreezeController attribute. (When I do connect the sample client to it I do get a list of items - it just does not filter, so I think it is something to with the OData Action filters. How can I debug where the problem is?

Update 1) Here is the metadata: http://www.ftter.com/desktopmodules/framework/api/dare/metadata

The GetUsers method: http://www.ftter.com/desktopmodules/framework/api/dare/getusers

and the GetUsers method trying to filter by UserID (which doesn't work, which is the issue) http://www.ftter.com/desktopmodules/framework/api/dare/getusers?=UserID%20eq%204 http://www.ftter.com/desktopmodules/framework/api/dare/GetUsersWithoutCors?=UserID%20eq%204 (this returns IQueryable)

Here is the controller:

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

解决方案

The routing is not really a Breeze issue. How your server routes requests to your controller is up to you. What we do out-of-the-box is just one way among innumerable many.

You have the [BreezeController] attribute on your controller yes? Can you put a sample endpoint up where we could hit it. Might get some clues from that. Also post the controller. A tiny example should do ... something returning metadata and one method returning IQueryable.

Update 25 Jun 2013

I think you've discovered a bug in the way our [BreezeController] discovers methods returning IQueryable<T>.

The [BreezeController] attribute scans your Web API controller methods and (in effect) applies the [BreezeQueryable] attribute to methods returning IQueryable<T>.

[BreezeQueryable] is an extension of the Web API's [Queryable] that adds support for $select, $expand, and nested $orderby ... all missing from the current [Queryable].

I see now that your GetUsers() method returns HttpResponseMessage rather than IQueryable<User>. Let's assume that the userInfoController.GetUsers() method inside your method returns IQueryable<User>. Otherwise, the OData query parameters will not apply and we'll have to take this in a different direction. Moving along ...

I checked with v.1.3.6 of the Breeze.WebApi.dll and it does not detect that the HttpResponseMessage is wrapping IQueryable<T>. Therefore, it does not apply the client's OData query criteria (or any other OData modifiers for that matter). This shortcoming (in my opinion) is a bug. The following should be equivalent implementations:

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

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

The second, "wrapped" method does not respect the OData query parameters.

Fortunately, there is a workaround until we get this fixed. Just add the [BreezeQueryable] attribute explicitly ... as in:

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

I confirmed that this approach does work.

Thanks for finding this.

Use OData query syntax

A colleague also noticed that your query URL does not use the OData query syntax. You wrote:

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

when it should be

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

Make sure you use ?$filter=

这篇关于控制器在DotNetNuke的模块没有过滤微风中查询数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆