如何将多个参数传递给 Odata 4 操作(Web Api 2.2 项目的一部分)

Lea*_*nds 1 asp.net asp.net-mvc odata asp.net-web-api asp.net-web-api2

我正在尝试使用 odata-4(在 web api 2.2 项目中)创建一个 odata api 端点,我需要在 odata 控制器中使用我的 GET 操作之一来接受多个字符串参数(除了我的属性之外,它们是自定义搜索属性)为其创建 odata 控制器的实体)。

但是到目前为止,我所做的所有试验中,在浏览器中访问特定操作时,我总是遇到一个或其他错误。到目前为止,我还没有能够获得流/语法的有效组合,因此在此处共享查询以获取有关如何实现将多个参数传递给 odata-4 中的 odata 操作如何修复我遇到的错误的建议。

代码如下:

包.配置:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.Mvc" version="5.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.OData" version="5.3.1" targetFramework="net45" />
  <package id="Microsoft.AspNet.Razor" version="3.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.OData" version="5.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages" version="3.1.2" targetFramework="net45" />
  <package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net45" />
  <package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net45" />
  <package id="Microsoft.OData.Core" version="6.5.0" targetFramework="net45" />
  <package id="Microsoft.OData.Edm" version="6.5.0" targetFramework="net45" />
</packages>
Run Code Online (Sandbox Code Playgroud)

WebApiConfig:

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            ODataModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntitySet<DocumentsModel>("SampleData");

            var function = builder.Function("SampleFunction");
            function.Parameter<string>("catGUIDOrText");
            function.Parameter<string>("type");
            function.Parameter<string>("isAutoCompSearch");
            function.ReturnsCollectionFromEntitySet<DocumentsModel>("SampleData");

            config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
Run Code Online (Sandbox Code Playgroud)

数据控制器:

[ODataRoutePrefix("SampleData")]
    public class SampleDataController : ODataController
    {
        [EnableQuery]
        [HttpGet]
        [ODataRoute("SampleFunction(catGUIDOrText={catGUIDOrText},type={type},isAutoCompSearch={isAutoCompSearch})")]
        public IEnumerable<DocumentsModel> GetSampleData([FromODataUri] string catGUIDOrText, [FromODataUri] string type, [FromODataUri] string isAutoCompSearch)
        {
            return new List<DocumentsModel>().AsQueryable<DocumentsModel>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

注意: - DocumentsModel 是一个具有所有字符串属性的类。

错误详情

现在,通过以下 URL 在浏览器中访问此操作时,出现错误:

URL: http://localhost/VirtualDirectoryNameInIIS/odata/SampleData/SampleFunction(catGUIDorText= '752',type='230',isAutoCompSearch='false')

我得到的错误:

控制器“SampleData”中的“GetSampleData”操作上的路径模板“SampleData/SampleFunction(catGUIDOrText={catGUIDOrText},type={type},isAutoCompSearch={isAutoCompSearch})”不是有效的 OData 路径模板。请求 URI 无效。由于段“SampleData”指的是一个集合,这必须是请求 URI 中的最后一个段,或者它后面必须跟一个可以绑定到它的函数或操作,否则所有中间段都必须引用单个资源。

请帮助我解决您可能有的任何输入,无论是在代码中还是在我用来访问给定方法的 url 中。谢谢。

我遵循了一些参考资料来解决这个问题或确保我遵循正确的方向/语法:

  1. Web API 和 OData-传递多个参数

  2. https://damienbod.com/2014/06/13/web-api-and-odata-v4-queries-functions-and-attribute-routing-part-2/

Fra*_*zzi 6

编辑 WebApiConfig.cs 添加显式命名空间

        builder.Namespace = "MyNamespace";
Run Code Online (Sandbox Code Playgroud)
  • 如果你不明确它,默认命名空间是“默认”:)

编辑 WebApiConfig.cs 更改函数声明

        FunctionConfiguration function = builder.EntityType<DocumentsModel>().Collection.Function("SampleFunction");
        function.Parameter<string>("catGUIDOrText");
        function.Parameter<string>("type");
        function.Parameter<string>("isAutoCompSearch");
        function.ReturnsCollectionFromEntitySet<DocumentsModel>("SampleData");
Run Code Online (Sandbox Code Playgroud)
  • 使用“.EntityType()”,您定位实体 DocumentsModel 的控制器,您已将其命名为“SampleData”
  • 使用“.Collection”,您可以定位实体的集合;否则,如果省略,则针对单个实体

更改 Odata 控制器

//[ODataRoutePrefix("SampleData")]
public class SampleDataController : ODataController
{
    //[ODataRoute("SampleData/MyNamespace.SampleFunction(catGUIDOrText={catGUIDOrText},type={type},isAutoCompSearch={isAutoCompSearch})")]
    [EnableQuery]
    [HttpGet]
    public IHttpActionResult SampleFunction(string catGUIDOrText, string type, string isAutoCompSearch)
    {
        return new List<DocumentsModel>().AsQueryable<DocumentsModel>();
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 你可以评论[ODataRoutePrefix("SampleData")]:命名约定的路由是entitySetName Controller,你在WebApiConfig上用"builder.EntitySet("SampleData")"设置它
  • 返回类型不能是 IEnumerable;如果你使用 IHttpActionResult 你永远不会有问题。
  • 如果使用命名约定,则可以注释 ODataRoute

更改 url 添加 odata 命名空间

http://localhost/VirtualDirectoryNameInIIS/odata/SampleData/MyNamespace.SampleFunction(catGUIDorText='752',type='230',isAutoCompSearch='false')


在您的代码中,您已经声明了一个未绑定的函数,但是您像绑定函数一样调用

您可以在本教程中找到所需的信息

  • 我的回答对您有帮助还是没有解决您的问题?否则,如果您接受我的回答,我将不胜感激。 (3认同)