我正在使用ODAP v4和Web API 2.2 .
我有一个名为“Person”的实体,其复合键为“FirstName”和“LastName” . 看起来像这样:
public class Person {
public string FirstName {get; set;}
public string LastName {get; set;}
public double Age {get; set;}
}
为了支持复合键,我在默认约定之上添加了一个uri约定,它看起来像这样:
public class CompositeKeyRoutingConvention : EntityRoutingConvention
{
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
{
var action = base.SelectAction(odataPath, controllerContext, actionMap);
if (action != null)
{
var routeValues = controllerContext.RouteData.Values;
if (routeValues.ContainsKey(ODataRouteConstants.Key))
{
var keyRaw = (string)routeValues[ODataRouteConstants.Key];
var compoundKeyPairs = keyRaw.Split(',');
if (!compoundKeyPairs.Any())
{
return action;
}
foreach (var compoundKeyPair in compoundKeyPairs)
{
var pair = compoundKeyPair.Split('=');
if (pair.Length != 2)
{
continue;
}
var keyName = pair[0].Trim();
var keyValue = pair[1].Trim();
routeValues.Add(keyName, keyValue);
}
}
}
return action;
}
我的呼叫代码试图访问这样一个人的年龄:
http://localhost:46028/Person(firstName='Blah',LastName='Blu')/Age
我收到此错误:
{“error”:{“code”:“”,“message”:“找不到与请求URI匹配的HTTP资源'http://:46028 / Person(firstName ='Blah',LastName ='Blu') / Age' . “,”innererror“:{”message“:”找不到路由约定来为OData路径选择一个动作,模板'〜/ entityset / key / property' . “,”type“:”“, “堆栈跟踪”:”” } } }
我的控制器有两种方法:
public IQueryable<Person> Get()
{
return _db.People;
}
public Person Get([FromODataUri] string firstName, [FromODataUri] string lastName)
{
var person = _db.People
.FirstOrDefault(x => x.FirstName == firstName && x.LastName== lastName);
if (person == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return person;
}
1 回答
原来有一个简单的解决方案 . Web API不能很好地支持复合键,它们有一个PropertyRoutingConvention,它正是我正在寻找的,除了它不适用于复合键 .
通过创建下面给出的“CompositeKeyPropertyRoutingConvention”修复它:
最后一个类做了一些mumbo jumbo来处理“,”在密钥本身的数据里面,还没有在数据中用“'”进行测试,我建议你这样做 .