我刚刚开始使用Web Api OData,我发现自己想要做一些能够做标准ApiController的事情,即从Id字段以外的字段中获取对象。我知道这样做是标准的,例如在基于它的Id:
获取对象时[Queryable]
public SingleResult<Group> GetGroup([FromODataUri] int key)
{
return SingleResult.Create(db.Groups.Where(group => group.GroupId == key));
}
但是,如果我想通过groupName字段获取分组,我该怎么办?我尝试过这个类似于ApiController的东西:
控制器:
public Group GetGroup([FromODataUri] string groupName)
{
var group = _repository.GetGroupByGroupName(groupName);
if (group == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return group;
}
存储库:
public Group GetGroupByGroupName(string groupName)
{
Group group = (from u in _db.Groups
where u.GroupName == groupName
select u).FirstOrDefault();
return group;
}
我的WebApiConfig看起来像这样:
public static void Register(HttpConfiguration config)
{
config.EnableCors();
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
// OData
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<City>("Cities");
modelBuilder.EntitySet<Stage>("Stages");
modelBuilder.EntitySet<Team>("Teams");
modelBuilder.EntitySet<Fixture>("Fixtures");
modelBuilder.EntitySet<Roster>("Rosters");
modelBuilder.EntitySet<Standing>("Standings");
modelBuilder.EntitySet<Group>("Groups");
var model = modelBuilder.GetEdmModel();
config.Routes.MapODataRoute("ODataRoute", "odata", model);
}
我希望能够使用odata / Groups / GroupName基于组名获取组对象,但我目前所拥有的组对象不起作用。我该怎么做,或者我是从完全错误的方向接近这个?
答案 0 :(得分:1)
您已经在使用QueryableAttribute
,因此如果您定义了以下内容:
[Queryable]
public IQueryable<Group> Get()
{
// Returns all groups as a queryable (do not execute query here!)
}
然后,您可以使用ajax请求和任何odata查询来访问它,例如:
http://server/Api/Group?$filter=GroupName eq 'test'
查询是在客户端上构建的,不受服务器参数的限制。
答案 1 :(得分:0)
假设您仍然需要调用自定义函数。 OData V4 允许这样做。问题有点陈旧,但我相信它今天仍然有效。
首先,您需要为ODataConventionModelBuilder指定一个命名空间,因为OData V4需要此操作和函数:
var builder = new ODataConventionModelBuilder();
builder.Namespace = "Default";
请注意,这可能会导致IIS给出404,因为IIS会解释该点。为了防止这种情况,add the following到您的Web.config:
<system.webServer>
<handlers>
<clear/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="/*"
verb="*" type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
然后,您还需要声明该函数:
builder.EntitySet<Group>("Groups").EntityType
.Collection
.Function("GetGroupByName")
.ReturnsFromEntitySet<Group>("Groups")
.Parameter<string>("name");
注意函数是在COLLECTION上声明的,所以它绑定到它。然后是ODataController方法:
[ODataRoute("Groups/Default.GetGroupByName(name={name})")]
[HttpGet]
public IHttpActionResult GetGroupByName([FromODataUri]string name)
{
return Ok(new Group() or whatever);
}
只有在使用参数时,才需要ODataRoute注释。它按顺序定义:实体集,命名空间,方法和参数。
然后您可以使用:
http://localhost:xxxx/api/Groups/Default.GetByGroupName(name='sausage')
另外,请参阅this SO answer以传递多个参数