none
Odata 4 Put operation fails RRS feed

  • Question

  • I've a column with ID (Primary Key) and Name in my table. And I've created  a odata controller for that Entity. 

    All operations work fine except Put. 

    which fails with following error:

    "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 PaperSave_API.Controllers.ConfigsController.<Patch>d__a.MoveNext() in e:\\Devlopment\\PaperSave5.3\\Development\\PaperSave\\API\\Controllers\\ConfigsController.cs:line 110\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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at PaperSave_API.Filter.AddChallengeOnUnauthorizedResult.<ExecuteAsync>d__2.MoveNext() in e:\\Devlopment\\PaperSave5.3\\Development\\PaperSave\\API\\Filter\\PaperSaveAuthorizeAttribute.cs:line 149\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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>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.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"

    I make sure that ID is marked a KEY in the EF. not sure what's wrong. Here is the code for my Put handler.

    public async Task<IHttpActionResult> Put([FromODataUri] int key, Delta<Config> patch)
            {
                Validate(patch.GetEntity());

                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                Config config = await db.Configs.FindAsync(key);
                if (config == null)
                {
                    return NotFound();
                }

                patch.Put(config);

                try
                {
                    await db.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ConfigExists(key))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }

                return Updated(config);
            }

    Appreciate any help.

    Thanks,

    Himal

    Monday, April 27, 2015 12:02 PM

Answers

  • Hi,

    Thanks for your reply, Yes, I got the issue. I need to pass the ID column which is my primary key in the body of the request. I wasn't passing the ID assuming it might be retrieving from the URI but that wasnt the case. so in my case my request would be something like

    PUT http://localhost:87894/odata/Config(100)

    body:

    {

    ID: 100,
    Name:'ConfigName'

    }

    Thanks for your help.

    Himal


    Tuesday, April 28, 2015 4:56 AM

All replies

  • Hello himal16,

    >>I make sure that ID is marked a KEY in the EF. not sure what's wrong. Here is the code for my Put handler.

    From the exception, this issue should be caused that in your code, you are trying to update the primary key as:

    config.ID = 1;
    
    db.Configs.Add(config);
    
    db.SaveChanges();
    

    Please check if you have similar code, and if has, please do not do that because in Entity Framework, the primary key is not designed to editable.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, April 28, 2015 3:04 AM
    Moderator
  • Hi,

    Thanks for your reply, Yes, I got the issue. I need to pass the ID column which is my primary key in the body of the request. I wasn't passing the ID assuming it might be retrieving from the URI but that wasnt the case. so in my case my request would be something like

    PUT http://localhost:87894/odata/Config(100)

    body:

    {

    ID: 100,
    Name:'ConfigName'

    }

    Thanks for your help.

    Himal


    Tuesday, April 28, 2015 4:56 AM