Search code examples
c#asp.netentity-frameworkjsonresult

SaveChanges not working on JsonResult method (UPDATE INFO)


The problem is basically the Save changes method is not working (updating), the method should receive 3 parameters, item id, user id and the object which contains the updated information from the UI, however the code seems to be something bad because the saveChanges() method is not working.

This is my code:

[HttpPost]
    [AllowAnonymous]
    public JsonResult UpdatePersonalData(int ItemId, int UserId, CND_PersonalData Item)
    {
        try
        {
            if (ModelState.IsValid)
            {
                using (var context = new DexusEntities())
                {
                    CND_PersonalData PersonalData = context.CND_PersonalData.Where(d => d.Id == ItemId && d.UserId == UserId).SingleOrDefault();
                    if (PersonalData == null)
                    {
                        /// Display bad request
                        /// User does not exist and/or is not activated
                        List<RootObject> rootObj = new List<RootObject>();
                        rootObj.Add(new RootObject
                        {
                            msg = "User/Item not found in our DB",
                            code = "error_07"
                        });
                        HttpContext.Response.StatusCode = 404;
                        HttpContext.Response.TrySkipIisCustomErrors = true;
                        JsonRes.Message = rootObj;
                        return Json(JsonRes, JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        PersonalData = Item;
                        context.SaveChanges();
                        context.ChangeTracker.DetectChanges();
                        List<RootObject> rootObj = new List<RootObject>();
                        rootObj.Add(new RootObject
                        {
                            msg = "Information stored/updated successfully",
                            code = "success_05"
                        });
                        HttpContext.Response.StatusCode = 200;
                        JsonRes.Message = rootObj;
                        return Json(JsonRes, JsonRequestBehavior.AllowGet);
                    }
                }
            }
            else
            {
                List<RootObject> rootObj = new List<RootObject>();
                JsonRes.Issue = "The model is not correct";
                rootObj.Add(new RootObject
                {
                    msg = "Model is not valid",
                    code = "error_03"
                });
                HttpContext.Response.StatusCode = 403;
                HttpContext.Response.TrySkipIisCustomErrors = true;// Avoid issues in the HTTP methods
                JsonRes.Message = rootObj;
                return Json(JsonRes, JsonRequestBehavior.AllowGet);
            }
        }
        catch (Exception ex)
        {
            string err = ex.ToString();
            List<RootObject> rootObj = new List<RootObject>();
            JsonRes.Issue = err;
            rootObj.Add(new RootObject
            {
                msg = "Conflict with method, see issue description.",
                code = "error_08"
            });
            HttpContext.Response.StatusCode = 400;// Bad request
            HttpContext.Response.TrySkipIisCustomErrors = true;
            JsonRes.Message = rootObj;
            return Json(JsonRes, JsonRequestBehavior.AllowGet);
        }
    }

What's wrong with my code? Thanks in advance.


Solution

  • As I can see you are not adding an item into the DbSet and calling SaveChanges after:

    When adding an item you should put it into DbSet

    context.CND_PersonalData.Add(item);
    context.SaveChanges();
    

    when you want to update just call SaveChanges after you update loaded object

        var PersonalData= context.CND_PersonalData.Where(d => d.Id == ItemId && d.UserId == UserId).SingleOrDefault();
     PersonalData.Name = item.Name;
    PersonalData.Title = item.Title;
        context.SaveChanges();
    

    You can't just assign passed object to an entity you got from the DB, you need to change properties. If you do it as you did you didn't change values in the loaded object. So when you call SaveChanges nothing is changed. You need to change properties one by one.

    If you don't want to do that then you can attach your item into the db by using Attach method on context.

    context.Attach(item);
    context.SaveChanges();
    

    but you should be careful because if you load and track item with the same id as you are doing before checking if it is null:

    CND_PersonalData PersonalData = context.CND_PersonalData.Where(d => d.Id == ItemId && d.UserId == UserId).SingleOrDefault();
                        if (PersonalData == null)
                        {
    

    then you will get an error during the save because the context is already tracking item with the same ID, so you can remove that check and just check if it exists:

    if (context.CND_PersonalData.Any(d => d.Id == ItemId && d.UserId == UserId))
       {
    

    and then execute your code