Fra*_*rme 37 .net c# entity-framework odata asp.net-web-api
我正试图让OData端点启动并正常工作,我遇到了这个错误,即使谷歌也没什么可说的.
我已经创建了一个Entity Framework EDMX上下文(数据库优先),让设计者从中生成2个模型.
除了$filter查询失败之外,一切正常.
我可以做得很好:
http://localhost:27164/Projects(6587660)
Run Code Online (Sandbox Code Playgroud)
它检索主ID为6587660的Project.
但任何$filter要求如下:
http://localhost:27164/Projects?$filter=ProjectID eq 6587660
Run Code Online (Sandbox Code Playgroud)
将失败并出现以下错误:
URI中指定的查询无效.属性"ProjectID"不能在$ filter查询选项中使用.
我也尝试过查询其他属性,字符串属性.同样的错误.
我已经检查过EF生成的模型在属性上没有任何属性,但它们没有.
这是我在WebApiConfig.cs模块中的Register方法:
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<DB.Project>("Projects");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel()
);
}
Run Code Online (Sandbox Code Playgroud)
这是Projects控制器(GetProjects是进行$ filter查询时的被调用方法):
public class ProjectsController : ODataController
{
private AppContext db = new AppContext();
//I've tried decorating with that: [EnableQuery(AllowedQueryOptions = System.Web.OData.Query.AllowedQueryOptions.All, AllowedArithmeticOperators = System.Web.OData.Query.AllowedArithmeticOperators.All)] and no go
[EnableQuery]
public IQueryable<Project> GetProjects()
{
return db.Projects;
}
// GET: odata/Projects(5)
[EnableQuery]
public SingleResult<Project> GetProject([FromODataUri] int key)
{
return SingleResult.Create(db.Projects.Where(project => project.ProjectID == key));
}
/*
// PUT: odata/Projects(5)
public IHttpActionResult Put([FromODataUri] int key, Delta<Project> patch)
{
Validate(patch.GetEntity());
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Project project = db.Projects.Find(key);
if (project == null)
{
return NotFound();
}
patch.Put(project);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProjectExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(project);
}
// POST: odata/Projects
public IHttpActionResult Post(Project project)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Projects.Add(project);
db.SaveChanges();
return Created(project);
}
// PATCH: odata/Projects(5)
[AcceptVerbs("PATCH", "MERGE")]
public IHttpActionResult Patch([FromODataUri] int key, Delta<Project> patch)
{
Validate(patch.GetEntity());
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Project project = db.Projects.Find(key);
if (project == null)
{
return NotFound();
}
patch.Patch(project);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProjectExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(project);
}
// DELETE: odata/Projects(5)
public IHttpActionResult Delete([FromODataUri] int key)
{
Project project = db.Projects.Find(key);
if (project == null)
{
return NotFound();
}
db.Projects.Remove(project);
db.SaveChanges();
return StatusCode(HttpStatusCode.NoContent);
}
*/
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool ProjectExists(int key)
{
return db.Projects.Count(e => e.ProjectID == key) > 0;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我第一次使用OData和Database First,所以我不确定是什么导致了这一点.
我在.NET 4.5.2上使用Nuget的最新运行时.
luk*_*kea 114
来自文档13.1模型绑定属性:
现在,WebAPI OData的默认设置是:客户端无法在查询中应用$ count,$ orderby,$ select,$ top,$ expand,$ filter,查询如localhost\odata\Customers?$ orderby = Name将失败为BadRequest,因为默认情况下所有属性都不可排序,这是6.0.0中的重大更改
因此,我们现在需要启用OData模型绑定属性,您可以使用以下块中的中间行进行全局操作(另外两个是您的代码):
ODataModelBuilder builder = new ODataConventionModelBuilder();
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null); //new line
builder.EntitySet<DB.Project>("Projects");
Run Code Online (Sandbox Code Playgroud)
但这是一个包罗万象的工作,围绕着这种变化带来的更好的安全性/性能.
因此,您可以,也许应该使用每个实体的流畅API调用启用OData模型绑定属性,如下所示:
builder.EntitySet<DB.Project>("Projects"); //your line of code
builder.EntityType<DB.Project>().Filter("ProjectID");
Run Code Online (Sandbox Code Playgroud)
这个答案可以解决您发布的问题,但是,我希望您需要查看这些文档,以便为项目的其余部分提供全面的解决方案(当然,除非您只是部署一个-line catch all!).
正如名称"模型绑定属性"所暗示的那样,您还可以通过模型上的属性实现所需的内容,这也是文档中的(实际上也是主要关注点).
2017年2月编辑:
每个实体的流畅API中似乎存在一个错误.$expand尽管实体集使用流畅的API设置,但对实体集的调用会间歇性地返回400 Bad Request并在原始问题中出现错误.我不知道这个bug是仅存在于$expand其他查询参数上还是与其他查询参数存在.我也不知道是我的代码是导致问题还是MS错误,因此是其他人遇到的问题.我将很快对此进行调查并更新此答案.现在我正在使用单线捕捉全部; 工作得很好.
进一步编辑:
我刚刚重读了一些文档(试图尽可能地理解这个更新),它们似乎暗示我现在设置的方式(使用Global Config one-line-catch-all加上流畅的API) ,每个实体的流畅API仍将受到尊重,因为:
"查询设置可放置在许多地方,从最低到最高的优先级如下:系统默认值(默认情况下不可查询),全局配置,模型绑定属性,Fluent API."
因此,也许这就是你要做的事情:添加one-line-catch-all然后使用模型绑定属性,流畅API或两者进行微调.我需要对此进行测试并尽快报告...
| 归档时间: |
|
| 查看次数: |
21381 次 |
| 最近记录: |