C# Web API 2:更新导航属性(实体)
我正在寻找一些关于Web API功能的指导,这些功能在MVC中很容易更新具有导航属性的实体 在MVC中,其实现方式如下:C# Web API 2:更新导航属性(实体),c#,asp.net,wcf,entity-framework,asp.net-web-api,C#,Asp.net,Wcf,Entity Framework,Asp.net Web Api,我正在寻找一些关于Web API功能的指导,这些功能在MVC中很容易更新具有导航属性的实体 在MVC中,其实现方式如下: [AcceptVerbs(HttpVerbs.Post)] [ValidateAntiForgeryToken] public virtual async Task<ActionResult> Update(Page page) { Guard.IsNotNull(page, "page"); va
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public virtual async Task<ActionResult> Update(Page page)
{
Guard.IsNotNull(page, "page");
var pageToUpdate = await this.repository.Query.Include(p => p.Tags).Include(p => p.Name).SingleOrDefaultAsync(p => p.Pk == page.Pk);
if (pageToUpdate == null)
{
return this.RedirectToRoute(H.Constants.Routes.Error.Index, new
{
view = H.Constants.Views.Error.ViewPages.NotFound
});
}
if (this.TryUpdateModel(pageToUpdate))
{
this.repository.BeginTransaction();
this.repository.Update(pageToUpdate); // Updates related entities!
await this.repository.CommitTransactionAsync();
return this.RedirectToRoute(H.Constants.Routes.Data.Read);
}
return this.View(H.Constants.Views.FolderNames.ViewPages.FormatWith(H.Constants.Views.Data.ViewPages.Update), pageToUpdate);
}
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
公共虚拟异步任务更新(第页)
{
Guard.IsNotNull(第页,“第页”);
var pageToUpdate=wait this.repository.Query.Include(p=>p.Tags).Include(p=>p.Name).SingleOrDefaultAsync(p=>p.Pk==page.Pk);
如果(pageToUpdate==null)
{
返回此.RedirectToRoute(H.Constants.Routes.Error.Index,新建
{
视图=H.Constants.Views.Error.ViewPages.NotFound
});
}
if(此.TryUpdateModel(pageToUpdate))
{
this.repository.BeginTransaction();
this.repository.Update(pageToUpdate);//更新相关实体!
等待此消息。repository.CommitTransactionAsync();
返回此.RedirectToRoute(H.Constants.Routes.Data.Read);
}
返回this.View(H.Constants.Views.FolderNames.ViewPages.FormatWith(H.Constants.Views.Data.ViewPages.Update),pageToUpdate);
}
所有的导航属性都会更新,生活也会很好
在WebAPI中尝试这一点时,并没有这么多。相关实体未更新。例如:
[HttpPatch]
[HttpPut]
public virtual async Task<IHttpActionResult> Update(int pk, Page page)
{
Guard.IsNotNegativeOrZero(pk, "pk");
if (this.ModelState.IsValid)
{
if (page.Pk == pk)
{
try
{
this.repository.BeginTransaction();
this.repository.Update(page); // Doesn't update related entities.
await this.repository.CommitTransactionAsync();
return this.StatusCode(HttpStatusCode.NoContent);
}
catch (DbUpdateConcurrencyException dbUpdateConcurrencyException)
{
if (this.repository.Query.Any(p => p.Pk == pk))
{
return this.InternalServerError(dbUpdateConcurrencyException);
}
return this.NotFound();
}
}
return this.BadRequest();
}
return this.BadRequest(this.ModelState);
}
[HttpPatch]
[HttpPut]
公共虚拟异步任务更新(int-pk,第页)
{
卫兵。不负或零(pk,pk);
if(this.ModelState.IsValid)
{
如果(page.Pk==Pk)
{
尝试
{
this.repository.BeginTransaction();
this.repository.Update(第页);//不更新相关实体。
等待此消息。repository.CommitTransactionAsync();
返回此.StatusCode(HttpStatusCode.NoContent);
}
捕获(DbUpdateConcurrencyException DbUpdateConcurrencyException)
{
if(this.repository.Query.Any(p=>p.Pk==Pk))
{
返回此.InternalServerError(dbUpdateConcurrencyException);
}
返回此.NotFound();
}
}
返回此.BadRequest();
}
返回此.BadRequest(此.ModelState);
}
这在今天的Web API中可以实现吗?或者Web API当前是不完整的Microsoft产品
编辑:WebAPI中不存在使用示例更新且未引用WCF的TryUpdateModel。您可能还发现您在实体的序列化方面存在问题。出于这两个原因,我使用将ViewModels映射到EF实体,您可以使用automapper中的映射来处理导航属性 web API方法如下所示:
public HttpResponseMessage Post(MyViewModel model)
{
if (someValidationCheckHere)
return new HttpResponseMessage(HttpStatusCode.BadRequest);
_myService.Update(Mapper.Map<MyViewModel, MyEntity>(model));
return new HttpResponseMessage(HttpStatusCode.OK);
}
公共httpresponsemessagepost(MyViewModel模型)
{
如果(someValidationCheckHere)
返回新的HttpResponseMessage(HttpStatusCode.BadRequest);
_myService.Update(Mapper.Map(model));
返回新的HttpResponseMessage(HttpStatusCode.OK);
}
正如其他人所说,服务最终由存储库进行更新。在本例中,我将使用automapper忽略导航属性,但您可以配置automapper以按自己喜欢的方式处理它们:
Mapper.CreateMap<MyViewModel, MyEntity>()
.ForMember(x => x.NavigationProperty, opt => opt.Ignore());
Mapper.CreateMap()
.FormMember(x=>x.NavigationProperty,opt=>opt.Ignore());
我在global.asax中的application\u start静态类中设置了所有映射。您是否混淆了传输层(WCF/WebAPI)和ORM?我不明白
context.Update(entity)
与WebAPI有什么关系。不,它是WCF和WebAPI背后的实体框架,每个都有不同的行为。WebAPI很好,只是你用错了。WebApi与它处理web请求的数据和实体无关。Api控制器应获取输入并将其发送给服务,服务将更新实体等。@RyanMendoza,什么是上下文。更新?听起来像是ORM。如果是这样的话,那绝对与WebAPI无关。我不确定我的问题是否翻译得很好。例如,在MVC中有UpdateModel和TryUpdateModel,允许方法接收部分模型并只更新模型的相关部分。这在WebAPI中并不存在,尽管它似乎是以MVC为模型的。您好,感谢您的回复。您能否在提供的示例中提供一个AutoMappers角色的示例,以解决TryUpdateModel的不足?