在 Microsoft.AspNet.OData V5.9.1及更低版本中,您可以通过调用WebApiConfig.cs中的EnableAlternateKeys()来启用备用密钥,如下所示:
config.EnableAlternateKeys(true);
此选项已与其他内容一起删除:
config.EnableCaseInsensitive(true);
如何在 Microsoft.AspNet.OData V6 +中启用EnableAlternateKeys选项?
答案 0 :(得分:3)
在OData WebAPI 6中已经发生了变化。自从引入了v6依赖注入(参见docs)。这意味着更改了配置服务的旧方法。从现在开始,您应该在MapODataServiceRoute方法
中注册所有必要的服务和路线public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
setErrorDetailPolicy();
var model = BuildEdmModel();
// Web API routes
config.MapODataServiceRoute("routeName", "routePrefix", builder =>
builder.AddDefaultODataServices()
.AddService<IEdmModel>(ServiceLifetime.Singleton, s => model)
.AddService<IEnumerable<IODataRoutingConvention>>(ServiceLifetime.Singleton, sp => ODataRoutingConventions.CreateDefaultWithAttributeRouting("routeContact", config))
.AddService<ODataUriResolver>(ServiceLifetime.Singleton, s => new AlternateKeysODataUriResolver(model))
);
}
这里重要的一行是最后一行:
.AddService<ODataUriResolver>(ServiceLifetime.Singleton, s => new AlternateKeysODataUriResolver(model))
启用此功能后,我发现我的模型在识别AddAlternateKeyAnnotation
扩展方法时遇到问题。这是通过将实例强制转换为EdmModel
(而不是使用IEdmModel
来解决的)。我的ModelBuilder类看起来像这样:
internal static IEdmModel GetModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "MyNamespace";
var personsSet = builder.EntitySet<PersonDTO>("Persons");
builder.EntityType<PersonDTO>().HasKey(k => k.Id);
var model = builder.GetEdmModel();
// model is built, add alternateKey annotation as necessary
// first, find entity type
IEdmEntityType t = model.FindDeclaredEntitySet("Persons").EntityType();
// now find the properties we want to use as alternateKey
var firstNameProp = t.FindProperty("FirstName");
var lastNameProp = t.FindProperty("LastName");
// and finally add the annotation
((EdmModel)model).AddAlternateKeyAnnotation(t, new Dictionary<string, IEdmProperty> {
{
"FirstName", firstNameProp
},
{
"LastName", lastNameProp
}
});
return model;
}
请注意,仍有一些便利方法。来自文档:
你可能还会发现我们仍然保留了之前的重载 MapODataServiceRoute采用批处理程序,路径处理程序,HTTP 消息处理程序等。它们基本上包装了第一个重载 这需要一个configureAction。我们保留它们的原因是我们 希望为用户提供创建OData服务的便利 他们熟悉的API的轴承。
如果您想知道第一行的作用:
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
这是因为默认情况下在OData v6中禁用所有查询选项(再次参见docs)。您应该在每个控制器/操作上启用它们,或者像我一样启用它们,并全局启用它们(这就是上面的行)。
答案 1 :(得分:0)
jonathan.meesschaert答案中缺少的内容是您在OData控制器中的操作的签名。
在我的情况下,我具有以下备用密钥:
((EdmModel)edmModel).AddAlternateKeyAnnotation(
entityType,
new Dictionary<string, IEdmProperty>() {
{ "Text", edmProperty }
});
和关联的控制器动作是:
public MenuItem Get([FromODataUri]string keyText)
请注意,您无需使用[HttpGet]
或[ODataRoute("Menus(Text={Text})")]
即可使其正常运行。但是,关键部分是我必须在参数名称后附加 key 。没有它,它就不能在OData v7.1.0上运行