Asp.net mvc 两个操作的属性路由将导致一个;无效的OData路径模板";

Asp.net mvc 两个操作的属性路由将导致一个;无效的OData路径模板";,asp.net-mvc,odata,attributerouting,Asp.net Mvc,Odata,Attributerouting,所以我有两个函数返回一个客户,这两个函数由两个不同的参数反馈。一个是客户的ID,另一个是他的客户号码 我的控制器: using System.Linq; using System.Net; using System.Web.Http; using System.Web.OData; using System.Web.OData.Routing; using Models; using AutoMapper; using AutoMapper.QueryableExtensions; using

所以我有两个函数返回一个客户,这两个函数由两个不同的参数反馈。一个是客户的ID,另一个是他的客户号码

我的控制器:

using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Routing;
using Models;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using System.Web.OData.Extensions;
using Importing;
using Objects;
using Microsoft.OData;

namespace Controllers
{
    public class CustomersController : ODataController
    {
        // GET: CustomerByCNO(5)
        [HttpGet]
        [ODataRoute("CustomerByCNO({key})")]
        [EnableQuery]
        public SingleResult<CustomerDTO> GetCustomerByCNO([FromODataUri]string key)
        {
            Import i = new Import();

            var customer = i.GetCustomer(key).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }

        // GET: Customer(5)
        [HttpGet]
        [ODataRoute("Customer({id})")]
        [EnableQuery]
        public SingleResult<CustomerDTO> Get([FromODataUri]int id)
        {
            Import i = new Import();

            var customer = i.GetCustomer(id).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }
    }
}
使用System.Linq;
Net系统;
使用System.Web.Http;
使用System.Web.OData;
使用System.Web.OData.Routing;
使用模型;
使用自动制版机;
使用AutoMapper.QueryableExtensions;
使用System.Web.OData.Extensions;
使用进口;
使用物品;
使用Microsoft.OData;
命名空间控制器
{
公共类CustomerController:ODataController
{
//获取:CustomerByNo(5)
[HttpGet]
[ODataRoute(“CustomerByCNO({key})”)]
[启用查询]
public SingleResult GetCustomerByNo([FromODataUri]字符串键)
{
导入i=新导入();
var customer=i.GetCustomer(key.ProjectTo().AsQueryable();
返回单一结果。创建(客户);
}
//获取:客户(5)
[HttpGet]
[ODataRoute(“客户({id})”)]
[启用查询]
公共单结果获取([FromODataUri]int-id)
{
导入i=新导入();
var customer=i.GetCustomer(id.ProjectTo().AsQueryable();
返回单一结果。创建(客户);
}
}
}
初始化:

using AutoMapper;
using Models;
using Objects;
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using Microsoft.OData.Edm;

namespace API
{
    public static class WebApiConfig
    {
        public static void ConfigureAPI(HttpConfiguration config)
        {
            config.MapODataServiceRoute(
                routeName: "odata",
                routePrefix: "",
                model: GetEdmModel()
            );

            config.EnsureInitialized();
        }

        private static IEdmModel GetEdmModel()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder
            {
                Namespace = "Controllers",
                ContainerName = "DefaultContainer"
            };
            builder.EntitySet<CustomerDTO>("Customer")
                .EntityType.HasKey(c => c.Id)
                .CollectionProperty(c => c.CustomFields);

            var edmModel = builder.GetEdmModel();
            return edmModel;
        }
    }
}
使用AutoMapper;
使用模型;
使用物品;
使用System.Web.Http;
使用System.Web.OData.Builder;
使用System.Web.OData.Extensions;
使用Microsoft.OData.Edm;
名称空间API
{
公共静态类WebApiConfig
{
公共静态void配置API(HttpConfiguration配置)
{
config.MapODataServiceRoute(
routeName:“odata”,
routePrefix:“”,
模型:GetEdmModel()
);
config.EnsureInitialized();
}
私有静态IEdmModel GetEdmModel()
{
ODataConventionModelBuilder=新ODataConventionModelBuilder
{
Namespace=“Controllers”,
ContainerName=“DefaultContainer”
};
builder.EntitySet(“客户”)
.EntityType.HasKey(c=>c.Id)
.CollectionProperty(c=>c.CustomFields);
var edmModel=builder.GetEdmModel();
返回模型;
}
}
}
当第二个函数按预期工作时,第一个函数没有,并且EnsureInitialized()函数抛出InvalidOperationException,表示它不是有效的OData路径模板,并且未找到任何资源。我怎样才能让它工作?我不太清楚我在这里遗漏了什么

更新1:

将控制器方法更改为:

        [HttpGet]
        [ODataRoute("CustomerByNo(No={no})")]
        public SingleResult<CustomerDTO> CustomerByNo([FromODataUri] int no)
        {
            Import i = new Import();

            var customer = i.GetCustomer(no.ToString()).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }
[HttpGet]
[ODataRoute(“CustomerByNo(No={No})”)]
public SingleResult CustomerByNo([FromODataUri]内部编号)
{
导入i=新导入();
var customer=i.GetCustomer(no.ToString()).ProjectTo().AsQueryable();
返回单一结果。创建(客户);
}
在配置中使用此附加行:

        builder.Function("CustomerByNo").Returns<SingleResult<CustomerDTO>>().Parameter<int>("No");
builder.Function(“CustomerByNo”).Returns().Parameter(“No”);
这样我至少可以访问函数。我不得不把参数也改成int,好像它不喜欢字符串?但是,返回值不是反序列化的,而是像往常一样显示。另外,如果我离开方法声明中的[EnableQuery]行,调用将崩溃,说它不知道如何反序列化,因为它没有绑定到我猜的Customer的entityset

但是,这样做会导致原始错误消息,即找不到资源:

        builder.EntityType<CustomerDTO>().Collection.Function("CustomerByNo").Returns<SingleResult<CustomerDTO>>().Parameter<int>("No");
builder.EntityType().Collection.Function(“CustomerByNo”).Returns().Parameter(“No”);

您必须在约定模型中声明自定义odata函数:

FunctionConfiguration customerByCNOFunction = builder.Function("CustomerByCNO");
customerByCNOFunction.Returns<CustomerDTO>();
customerByCNOFunction.Parameter<string>("key");
FunctionConfiguration customerByCNOFunction=builder.Function(“CustomerByCNO”);
customerByCNOFunction.Returns();
customerByCNOFunction.Parameter(“键”);
更新:

我的第一个答案是声明一个函数,该函数返回odata中不可查询的类型。 要启用查询,函数需要从实体集中返回odata实体:

builder.Function("CustomerByNo").ReturnsFromEntitySet<CustomerDTO>("Customer").Parameter<int>("No")
builder.Function(“CustomerByNo”).ReturnsFromEntitySet(“Customer”).Parameter(“No”)

谢谢!但这不太管用。在返回中添加了CustomerDTO的SingleResult,但这并不重要。它只是给了我一个404。为了确保您使用的是正确的url,自定义odata函数的url是控制器的名称不在url中(我做:)检查我的编辑,也许这会给您提供更多的内部信息,请使用builder.function(“CustomerByNo”).ReturnsCollectionFromEntitySet(“Customer”).Parameter(“否”)这样它就知道结果类型来自CustomerBuilder.Function(“CustomerByNo”).ReturnsFromEntitySet(“Customer”).Parameter(“No”);工作得很有魅力。谢谢D