如何将多个参数传递给ODATA 4动作(Web API 2.2项目的一部分)



我正在尝试使用ODATA-4(内部Web API 2.2项目)创建一个ODATA API端点,在此我需要在ODATA Controller中进行我的GET ACTION之一,以接受多个字符串参数(除了创建ODATA控制器的实体中的属性外,它们是自定义搜索属性)。

但是,到目前为止,我已经进行了所有试验,在访问浏览器中的特定操作时,我总是会遇到一个或另一个错误。到目前为止修复我的错误。

代码如下:

package.config:

<?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>

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

ODATA控制器:

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

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

错误详细信息

现在,通过下面的URL访问浏览器时,我会遇到错误:

url:http://localhost/virtualDirectoryNameIiniis/odata/sampledata/samemfunction(catguidortext ='752',type ='230',isautocsearch ='false'')

错误:

路径模板 'sampledata/samplefunction(catguidortext = {catguidortext},type = {type},isautocompSearch = {isautocompSearch})' 在控制器"采样"中的动作" getsampledata"上不是 有效的ODATA路径模板。请求URI无效。自从 细分"采样"是指收藏品,这必须是最后一个 请求URI中的段,或必须遵循功能或 可以绑定到它的动作,否则所有中间段 必须参考单个资源。

请在代码或我用来访问给定方法的URL中帮助我使用您可能拥有的任何输入。谢谢。

我遵循的一些参考可以解决此问题或确保我遵循正确的方向/语法:

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

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

    li>

编辑webapiconfig.cs添加一个显式命名空间

        builder.Namespace = "MyNamespace";
  • 如果您不明确说明,则默认名称空间为"默认":)

编辑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");
  • 使用" .entityType()"您针对实体文档的控制器,您已命名为" 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>();
    }
}
  • 您可以评论[odatarouteprefix(" sampledata")]:命名约定的路由为 entitySetname 控制器,然后使用" builil.entitysetsetsements
  • 返回类型不能是一种可观的;如果您使用ihttpactionResult,您将永远不会遇到问题。
  • 如果您使用命名公约,您可以评论Odataroute

更改添加ODATA名称空间的URL

http://localhost/virtualdircorectorynameiniis/odata/sampledata/sampledata/mynamespace.samplefunction(catguidortext ='752',type ='230'


在您的代码中,您声明了一个未结合的函数,但是您像绑定功能一样呼叫

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

我正在尝试实现类似的东西,但我直接使用odataqueryOptions,因此我的控制器就是这样:

[HttpGet]
public ODataList<DTO> Get(ODataQueryOptions<POCO> options) {
    using (var db = new Entities()) {
        var param = Request.RequestUri.ParseQueryString().Get("CompanyCode");
        return _oData.Query<POCO, DTO>(options, db.POCO.AsQueryable());
    }
}

如果我尝试在签名中添加其他参数,我会遇到错误,因此试图找到一种与所有ODATA参数一起传递公司码的方法,并且仍然具有所有分页/过滤/分类工作。

这对我来说像魅力一样工作 - 我只是在请求中添加额外的参数,例如:

api/dto?compandcode = blah&amp; $ skip = 50&amp; $ top = 50

.net Odata的东西似乎忽略了我的额外参数,并且没有问题 - 我只是手动解析了参数,而不是将其放在函数签名中。对我来说足够好!

我能够通过: -

解决此问题
  1. 将以下代码添加到startup.cs

    public void ConfigureServices(IServiceCollection services)
     {
        // your code
       services.AddMvc();
       services.AddOData();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
      // your code
      app.UseRouting();
       app.UseEndpoints(endpoints =>
        {
    endpoints.Select().Filter().OrderBy().Expand().Count().MaxTop(50);
            endpoints.MapODataRoute("api", "api", GetEdmModel());
        });
    }
    private IEdmModel GetEdmModel()
    {
        var edmBuilder = new ODataConventionModelBuilder();
        edmBuilder.EntitySet<Student>("Students");  
        var pullRequestsByProjectByContributor = edmBuilder.EntityType<Student>().Collection
    .Function("GetStudents")
    .ReturnsCollectionFromEntitySet<Student>("Students");
        pullRequestsByProjectByContributor.Parameter<int>("id").Required();
        pullRequestsByProjectByContributor.Parameter<int>("classId").Required();
    
        return edmBuilder.GetEdmModel();
    }
    
  2. 在控制器中

    [ODataRouting]
    [ODataRoutePrefix("students")] 
    public class StudentsController : ODataController
    {
    //http://localhost:5112/api/students/GetStudents(id=3,classId=6)?$orderby=id%20desc&$skip=1&$top=2 
    [HttpGet]
    [EnableQuery]        
    [ODataRoute("GetStudents(id={id},classId={classId})")]
    public async Task<IActionResult> GetStudents(int id, int classId, ODataQueryOptions<Student> options)
    {
    }
    }
    

最新更新