具有2个参数的函数的OData路由

具有2个参数的函数的OData路由,odata,asp.net-web-api2,Odata,Asp.net Web Api2,我正在创建OData控制器,希望它支持带有2个参数的功能。 这是我目前的代码 奥达塔·科菲格: ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.Namespace = "hop"; builder.EntitySet<ScheduleDTO>("Schedules"); var function = builder.Function("GetByEntityAndJurisdiction"

我正在创建OData控制器,希望它支持带有2个参数的功能。 这是我目前的代码

奥达塔·科菲格:

ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "hop";

builder.EntitySet<ScheduleDTO>("Schedules");
var function = builder.Function("GetByEntityAndJurisdiction");

function.Parameter<Guid>("EntityId");
function.Parameter<Guid>("JurisdictionId");
function.ReturnsCollectionFromEntitySet<ScheduleDTO>("Schedules");
ODataModelBuilder=new ODataConventionModelBuilder();
builder.Namespace=“hop”;
建造商实体集(“附表”);
var function=builder.function(“GetByEntityandJudiction”);
function.Parameter(“EntityId”);
函数参数(“辖区ID”);
function.ReturnsCollectionFromEntitySet(“附表”);
控制器:

            [ODataRoutePrefix("Schedules")]
            public class ScheduleODataController : BaseODataManager, IScheduleODataManager
            {
                [ODataRoute]
                public async Task<IHttpActionResult> GetAsync(ODataQueryOptions<ScheduleDTO> options)
                {
                    .....
                    return Ok(schedules.Select(x => Mapper.Map<ScheduleDTO>(x)));
                }

                [HttpGet]
                [ODataRoute("GetByEntityAndJurisdiction(EntityId={entityId}, JurisdictionId={jurisdictionId})")]
                public async Task<IHttpActionResult> GetByEntityAndJurisdiction(ODataQueryOptions<ScheduleDTO> options, [FromODataUri] Guid entityId, [FromODataUri] Guid jurisdictionId)
                {
                   .....    
                   return Ok(schedules.Select(x => Mapper.Map<ScheduleDTO>(x)));
                }
            }
[ODataRoutePrefix(“计划”)]
公共类ScheduleODataController:BaseODataManager、IsScheduleODataManager
{
[ODataRoute]
公共异步任务GetAsync(ODataQueryOptions选项)
{
.....
返回Ok(schedules.Select(x=>Mapper.Map(x));
}
[HttpGet]
[ODataRoute(“GetByEntityAndJudiction(EntityId={EntityId},JudictionId={JudictionId})”)]
公共异步任务GetByEntityAndJudiction(ODataQueryOptions选项,[FromODataUri]Guid entityId,[FromODataUri]Guid JudictionId)
{
.....    
返回Ok(schedules.Select(x=>Mapper.Map(x));
}
}
启动我的应用程序时,我出现以下错误:

System.Web.OData.dll中发生类型为“System.InvalidOperationException”的第一次意外异常

其他信息:控制器“ScheduleOData”中的操作“GetByEntityAndJudiction”上的路径模板“Schedules/GetByEntityAndJudiction(EntityId={EntityId},JudictionId={JudictionId})”不是有效的OData路径模板。请求URI无效。由于段“Schedules”引用一个集合,因此它必须是请求URI中的最后一个段,或者后面必须有一个可以绑定到它的函数或操作,否则所有中间段都必须引用单个资源

如何解决这个问题?提前谢谢

弗拉基米尔

在控制器中,可以在控制器上添加前缀属性
[ODataRoutePrefix(“Schedules”)]
。这样做将在同一控制器中所有[ODataRoute]的开头添加前缀字符串。所以,下面的行动

public async Task<IHttpActionResult> GetByEntityAndJurisdiction(ODataQueryOptions<ScheduleDTO> options, [FromODataUri] Guid entityId, [FromODataUri] Guid jurisdictionId)
{...}
显然,此Uri无效,因为:

  • 计划的集合
    没有名为
    getByEntityandJudiction的绑定函数
  • 即使
    getByEntityandJudiction
    是绑定函数,也应该通过其命名空间限定函数名调用绑定函数
  • 可能会感到困惑的是,您已经按照以下代码构建了函数:

    var function = builder.Function("GetByEntityAndJurisdiction");
    
    但是,它意味着构建一个未绑定的函数。通过函数导入调用未绑定函数,方法是向标识函数导入的URL发出GET请求,并使用内联参数语法传递参数值函数导入的规范URL是服务根目录,后跟函数导入的名称

    因此,您可以按如下方式更改代码以使其正常工作:

  • 如果要保持模型模式不变,即将
    getByEntityandJudiction
    构建为未绑定函数,请从控制器中删除ODataRoutePrefix(“Schedules”)]。或创建新控制器(任何控制器),将操作移动到新控制器中,但不添加前缀属性

  • 如果要更改架构并保持控制器不变,则将
    getByEntityandJudiction
    作为绑定函数

  • 请按以下方式办理:

    var entity = builder.EntitySet<ScheduleDTO>("Schedules").EntityType;
    var function = entity.Collection.Function("GetByEntityAndJurisdiction");
    
    var entity=builder.EntitySet(“明细表”).EntityType;
    var function=entity.Collection.function(“GetByEntityandJudiction”);
    

    有关函数的更多信息,请参阅或

    var entity = builder.EntitySet<ScheduleDTO>("Schedules").EntityType;
    var function = entity.Collection.Function("GetByEntityAndJurisdiction");