我已经构建了MVC4应用程序,并希望将Asp.Net WebApi与OData v3一起添加到名为Api的单独区域中,但在使用EF set进行路由时,我能够看到$元数据,但无法获得Get动作的结果。 如果我在浏览器中按下此URL(http://localhost:1254/odata/ $元数据),我会得到以下输出。
This XML file does not appear to have any style information associated with it.
The document tree is shown below.
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
<script id="tinyhippos-injected"/>
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0">
<Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="SchoolProject.DAL">
<EntityType Name="NewsAnnouncement">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false"/>
<Property Name="Title" Type="Edm.String"/>
<Property Name="Image" Type="Edm.String"/>
<Property Name="Description" Type="Edm.String"/>
<Property Name="PublishDate" Type="Edm.DateTime" Nullable="false"/>
<Property Name="CreatedDate" Type="Edm.DateTime" Nullable="false"/>
<Property Name="UserName" Type="Edm.String"/>
<Property Name="ShortDescription" Type="Edm.String"/>
</EntityType>
</Schema>
<Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="Default">
<EntityContainer Name="Container" m:IsDefaultEntityContainer="true">
<EntitySet Name="NewsAnnouncements" EntityType="SchoolProject.DAL.NewsAnnouncement"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
但是当我通过实际的uri http://localhost:1245/odata/NewsAnnouncements进行Get操作时,我得到了以下输出
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:1245/odata/NewsAnnouncements'.","MessageDetail":"No type was found that matches the controller named 'NewsAnnouncements'."}
这是WebApiConfig.Cs文件的一部分
public static void Register(HttpConfiguration config)
{
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<NewsAnnouncement>("NewsAnnouncements");
config.Routes.MapODataServiceRoute(routeName: "ODataRoute",
routePrefix: "odata",
model: modelBuilder.GetEdmModel(),
pathHandler: new DefaultODataPathHandler());
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.EnsureInitialized();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}
已编辑:
public class NewsController : ODataController
{
//
// GET: /News/
private SchoolEntities entities = new SchoolEntities();
private bool NewsExists(string key)
{
return entities.NewsAnnouncements.Any(p => p.Id == key);
}
//
//
// The parameterless version of the Get method returns the entire Products collection. The Get method with a key parameter looks up a product by its key (in this case, the Id property).
//The [EnableQuery] attribute enables clients to modify the query, by using query options such as $filter, $sort, and $page
[EnableQuery]
public IQueryable<NewsAnnouncement> Get()
{
return entities.NewsAnnouncements;
}
[EnableQuery]
public SingleResult<NewsAnnouncement> Get([FromODataUri] string key)
{
IQueryable<NewsAnnouncement> result = entities.NewsAnnouncements.Where(p => p.Id == key);
return SingleResult.Create(result);
}
//To enable clients to add a new product to the database, add the following method to ProductsController.
public async Task<IHttpActionResult> Post(NewsAnnouncement newsItem)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
entities.NewsAnnouncements.Add(newsItem);
await Task.Delay(10);
entities.SaveChanges();
return Created(newsItem);
}
//PATCH performs a partial update. The client specifies just the properties to update.
public async Task<IHttpActionResult> Patch([FromODataUri] string key, Delta<NewsAnnouncement> product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var entity = entities.NewsAnnouncements.Find(key);
if (entity == null)
{
return NotFound();
}
product.Patch(entity);
try
{
await Task.Delay(10);
entities.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!NewsExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] string key, NewsAnnouncement updateNews)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (key != updateNews.Id)
{
return BadRequest();
}
entities.Entry(updateNews).State = EntityState.Modified;
try
{
await Task.Delay(10);
entities.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!NewsExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(updateNews);
}
// Notice that the controller overrides the Dispose method to dispose of the EntitiesContext.
protected override void Dispose(bool disposing)
{
entities.Dispose();
base.Dispose(disposing);
}
}
任何建议都将受到高度赞赏。 谢谢。
答案 0 :(得分:0)
最后我找到了答案,因为我手动添加了控制器名称,它与复数实体集'NewsAnnouncements'不同,这就是它显示错误的原因。我更改了控制器名称,类似于实体集'NewsAnnouncementsController'而不是'NewsController'。一切都像魅力一样。
正确的控制器应该看起来像
public class NewsAnnouncementsController /*NewsController*/: ODataController
{
//
// GET: /News/
private SchoolEntities entities = new SchoolEntities();
private bool NewsExists(string key)
{
return entities.NewsAnnouncements.Any(p => p.Id == key);
}
//
//
// The parameterless version of the Get method returns the entire Products collection. The Get method with a key parameter looks up a product by its key (in this case, the Id property).
//The [EnableQuery] attribute enables clients to modify the query, by using query options such as $filter, $sort, and $page
[EnableQuery]
public IQueryable<NewsAnnouncement> Get()
{
return entities.NewsAnnouncements;
}
[EnableQuery]
public SingleResult<NewsAnnouncement> Get([FromODataUri] string key)
{
IQueryable<NewsAnnouncement> result = entities.NewsAnnouncements.Where(p => p.Id == key);
return SingleResult.Create(result);
}
//To enable clients to add a new product to the database, add the following method to ProductsController.
public async Task<IHttpActionResult> Post(NewsAnnouncement newsItem)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
entities.NewsAnnouncements.Add(newsItem);
await Task.Delay(10);
entities.SaveChanges();
return Created(newsItem);
}
//PATCH performs a partial update. The client specifies just the properties to update.
public async Task<IHttpActionResult> Patch([FromODataUri] string key, Delta<NewsAnnouncement> product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var entity = entities.NewsAnnouncements.Find(key);
if (entity == null)
{
return NotFound();
}
product.Patch(entity);
try
{
await Task.Delay(10);
entities.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!NewsExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] string key, NewsAnnouncement updateNews)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (key != updateNews.Id)
{
return BadRequest();
}
entities.Entry(updateNews).State = EntityState.Modified;
try
{
await Task.Delay(10);
entities.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!NewsExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(updateNews);
}
// Notice that the controller overrides the Dispose method to dispose of the EntitiesContext.
protected override void Dispose(bool disposing)
{
entities.Dispose();
base.Dispose(disposing);
}
}