我之前有一个Web API控制器,如下所示:
public IQueryable<ApiDesignOverview> GetList(
string brandIds = "",
string categoryIds = "",
string query = "",
string categoryOp = "or")
我听说OData NuGet包现在支持$ inlinecount OData参数,所以我尝试使用http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options的指令添加它 - 我不想使用OData批发,因为这需要一个大量的应用程序重新构建,所以我选择PageResult<T>
选项。
所以现在我的控制器看起来像这样:
public PageResult<ApiDesignOverview> GetList(
ODataQueryOptions<ApiDesignOverview> options,
string brandIds = "",
string categoryIds = "",
string query = "",
string categoryOp = "or")
我现在的问题是:
ODataQueryContext
来构建一个,这需要Microsoft.Data.Edm.IEdmModel
,这需要......什么?我找不到任何相关的文档。真的,如果我可以像以前一样从控制器签名中删除ODataQueryOptions会更好。这可能吗?
答案 0 :(得分:11)
如果你没有(或者不能像我的情况那样)想要改变使用ODataQueryOptions和PageResult,那么你可以在这里为单元测试创建一个ODataQueryOptions实例:
//arrange
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/MyProject/api/Customers?$filter=CustomerID eq 1");
var controller = new CustomersController
{
Request = request
};
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Customer>("Customers");
var opts = new ODataQueryOptions<Customer>(new ODataQueryContext(modelBuilder.GetEdmModel(),typeof(Customer)), request);
//act
var result = controller.Get(opts);
//assert
Assert.AreEqual(1, result.Items.First().CustomerID);
答案 1 :(得分:8)
如果您更喜欢返回IQueryable并希望支持$ inlinecount,那么仍然可以通过对QueryableAttribute进行表达来实现。
public class InlineCountQueryableAttribute : QueryableAttribute
{
private static MethodInfo _createPageResult =
typeof(InlineCountQueryableAttribute)
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
.Single(m => m.Name == "CreatePageResult");
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
HttpRequestMessage request = actionExecutedContext.Request;
HttpResponseMessage response = actionExecutedContext.Response;
IQueryable result;
if (response.IsSuccessStatusCode
&& response.TryGetContentValue<IQueryable>(out result))
{
long? inlineCount = request.GetInlineCount();
if (inlineCount != null)
{
actionExecutedContext.Response = _createPageResult.MakeGenericMethod(result.ElementType).Invoke(
null, new object[] { request, request.GetInlineCount(), request.GetNextPageLink(), result }) as HttpResponseMessage;
}
}
}
internal static HttpResponseMessage CreatePageResult<T>(HttpRequestMessage request, long? count, Uri nextpageLink, IEnumerable<T> results)
{
return request.CreateResponse(HttpStatusCode.OK, new PageResult<T>(results, nextpageLink, count));
}
}
注意,我正在使用反射来创建PageResult。您可以改为返回您喜欢的对象,该对象可以由您使用的格式化程序格式化。如果您使用的是Json格式化程序,那么带有结果和计数的匿名对象也会起作用。
答案 2 :(得分:0)
在最新的ODataController
中,有一个AllowedQueryOptions
解决了这个问题。
public class MyOdataController : ODataController
{
[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Product> Get()
{
return Products.AsQueryable();
}
}