将OData方法键从整数更改为字符串

时间:2016-04-07 16:39:58

标签: c# rest odata asp.net-web-api2 asp.net-mvc-5

我在切换OData方法时使用字符串作为键而不是整数作为键时遇到问题。无论如何,它似乎都表现为整数?

旧方法(注意整数):

[EnableQuery]
public SingleResult<Order> Get([FromODataUri] int key)
{
    IQueryable<Order> result = db.Orders.Where(o => o.OrderId == key);
    return SingleResult.Create(result);
}

旧网址(效果很好):

api/orders(250)/

新方法(注意字符串):

[EnableQuery]
public SingleResult<Order> Get([FromODataUri] string key)
{
    IQueryable<Order> result = db.Orders.Where(o => o.MyCustomId == key);
    return SingleResult.Create(result);
}

新网址应该最终如下:

api/orders('13-Abc.56.77.Blah.Blah')/

我的Web API路由如下所示:

public static void Register(HttpConfiguration config)
{
    // Web API configuration and routes
    config.MapHttpAttributeRoutes();

    //OData configuration
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Order>("orders");
    builder.EntityType<Order>().Function("getordersummary").Returns<OrderSummary>();

    var _model = builder.GetEdmModel();
    var defaultConventions = ODataRoutingConventions.CreateDefaultWithAttributeRouting(config, _model);
    var conventions = defaultConventions.Except(defaultConventions.OfType<MetadataRoutingConvention>());

    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: "api",
        routingConventions: conventions,
        pathHandler: new DefaultODataPathHandler(),
        model: _model);

    //make uri calls much easier
    config.EnableUnqualifiedNameCall(true);

    //ensure JSON responses
    var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
    config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}

新网址不适用于:

/api/orders('13-2011.01')/
/api/orders(13-2011.01)/
/api/orders('ABC')/
/api/orders(ABC)/

但新网址适用于:

/api/orders(13201101)/
/api/orders(123)/

如果我在调试时在我的新“Get”控制器方法上设置断点,它只会在新url看起来像这样时被点击:

/api/orders(13201101)/

如果新网址如下所示,则不会点击断点:

/api/orders('13-2011.01')/
/api/orders(13-2011.01)/

在我的SQL服务器数据库表中,我创建了主键[MyCustomId]字段。然后我更新了我的EntityFramework模型(.edmx)并将实体键分配给我的[Order]类中的[MyCustomId]字段。网址仍然无法正常工作。

我的路由有什么问题? 为什么新网址只接受整数,当它明确定义为:“[FromODataUri]字符串键”?

**更新:我已经添加了重写处理程序,允许在我的网址中使用“点”。我应该提一下。这工作正常,并在此迁移之前工作。例如,我们有这样的网址:

http://www.mywebsite.com/MyApplication/OrderInfo/OrderSummary/13-2011.01/

只是OData方法不起作用。

1 个答案:

答案 0 :(得分:2)

您尚未更改数据模型中Order实体类型的键属性。用于发现类ODataConventionModelBuilder的关键属性的约定Foo用于查找名为FooIdId的属性(两者都不区分大小写)。因此,Order类的关键属性仍然是OrderId,它是整数值。 (如果您启用MetadataRoutingConvention并检索/api/$metadata,您会看到这种情况。)

由于数据模型表明Order实体类型具有整数值键,因此路由引擎在资源路径/api/orders(key)中查找具有整数语法的值。模型绑定引擎然后愉快地将整数转换为字符串,以用作Get方法中的参数。

您可以通过以下两种方式之一解决问题:

  • MyCustomId重命名为OrderId,并将OrderId重命名为其他
  • 使用Key属性注释MyCustomId,从而覆盖ODataConventionModelBuilder使用的命名约定