【发布时间】:2017-08-03 04:21:19
【问题描述】:
我是 ASP.NET webapi 的菜鸟,这是一个非常简单的情况,我陷入了困境。
我正在使用 webapi+odata
我的模特:
public class CategoryModel
{
public int ID { get; set; }
public string Name { get; set; }
public int ParentID { get; set; }
}
我的自动生成控制器的 put 方法:
public async Task<IHttpActionResult> Put([FromODataUri] int key, Delta<CategoryModel> patch)
{
Validate(patch.GetEntity());
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
CategoryModel categoryModel = await db.Category.FindAsync(key);
if (categoryModel == null)
{
return NotFound();
}
patch.Put(categoryModel);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!CategoryModelExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(categoryModel);
}
还有我的 jquery ajax
jQuery.ajax(
{
url : '/api/Category(3)',
data : { Name:'New Category' },
method : 'PUT',
headers : {
Accept : 'application/json',
},
statusCode: {
401: () => {
console.log('handle the unautherized here');
},
},
beforeSend: (jqXHR, settings) => {},
error : (jqXHR, textStatus, errorThrown) => {
//TODO do some global error reporting
Util.Error(JSON.parse(jqXHR.responseText));
resolve(null);
},
success : (data, textStatus, jqXHR) => {
resolve(data);
},
complete : (jqXHR, textStatus) => {}
}
);
和错误:
{
"odata.error": {
"code": "",
"message": {
"lang": "en-US",
"value": "An error has occurred."
},
"innererror": {
"message": "The property 'ID' is part of the object's key information and cannot be modified. ",
"type": "System.InvalidOperationException",
"stacktrace": " at System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInProperty(Int32 ordinal, Boolean detectOnlyComplexProperties, Boolean detectOnly)\r\n at System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInProperties(Boolean detectOnlyComplexProperties)\r\n at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChangesInScalarAndComplexProperties(IList`1 entries)\r\n at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges()\r\n at System.Data.Entity.Core.Objects.ObjectContext.DetectChanges()\r\n at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)\r\n at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)\r\n at System.Data.Entity.Internal.InternalContext.GetStateEntries()\r\n at System.Data.Entity.Infrastructure.DbChangeTracker.Entries()\r\n at System.Data.Entity.DbContext.GetValidationErrors()\r\n at System.Data.Entity.Internal.InternalContext.SaveChangesAsync(CancellationToken cancellationToken)\r\n at System.Data.Entity.Internal.LazyInternalContext.SaveChangesAsync(CancellationToken cancellationToken)\r\n at System.Data.Entity.DbContext.SaveChangesAsync(CancellationToken cancellationToken)\r\n at System.Data.Entity.DbContext.SaveChangesAsync()\r\n at Notifier.Controllers.CategoryController.<Put>d__3.MoveNext() in E:\\csharp\\notifier\\Notifier\\Notifier\\Controllers\\CategoryController.cs:line 66\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
GET 和 POST 工作正常,但 PUT 和 PATCH 给我这个错误。
请帮帮我...
更新:问题在于这个控制器使用 odata v3 生成的代码,我检查了普通的 webapi 控制器,它工作得很好,所以....
【问题讨论】:
-
你在`await db.SaveChangesAsync();`上遇到错误?
-
@UmairAnwaar 是的
-
数据库表有主键吗?
-
您是否尝试过使用
SingleOrDefault获取对象并设置名称然后输入db.Entry("modifiedObject").State = EntityState.Modiied; db.SaveChanges(); -
@vanloc ID 是主键,如果没有指定另一个,默认情况下 EF 将 ID 作为主键。
标签: c# asp.net asp.net-web-api odata