Rahul
Rahul

Reputation: 2751

Asp.Net WebApi 2 PUT method not updating nested collection

A Asp.Net WebApi application consist of following classes Movie and Song. (one to many relationship)

public class Movie : PropertyChangedBase //(Implementation of INotifyPropertyChanged)
    {
        public Movie()
        {
            Songs = new ObservableCollection<Song>();
        }

        private int? _id;
        public int? Id
        {
            get { return _id; }
            set
            {
                _id = value;
                NotifyOfPropertyChange(() => Id);
            }
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                NotifyOfPropertyChange(() => Title);

            }

        }


        private ICollection<Song> _songs;
        public ICollection<Song> Songs
        {
            get { return _songs; }
            set
            {
                _songs = value;
                NotifyOfPropertyChange(() => Songs);
            }
        }
    }

    public class Song : PropertyChangedBase //(Implementation of INotifyPropertyChanged)
    {
        private int _id;
        public int Id
        {
            get { return _id; }
            set
            {
                _id = value;
                NotifyOfPropertyChange(() => Id);
            }
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                NotifyOfPropertyChange(() => Title);
            }
        }
    }

Web Api PUT Method:

// PUT: api/Movie/5
        [ResponseType(typeof(Movie))]
        public IHttpActionResult PutMovie(int id, Movie movie)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != Movie.ID)
            {
                return BadRequest();
            }

            db.Entry(Movie).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
            }
            return Ok(movie);
        }

When creating a new record, Movie and collection of songs created successfully. Its possible to edit(update) the values of class Movie.

Im calling PutMovie method to update the existing records.

Problem: 1) When adding new songs to the existing collection, no changes got updated. No errors but no song rows created in DB.

2) When updating existing values in Song, no changes got updated. No errors but no song values modified in DB.

Note: I'm using a c# client to consume web api.

Please help me to solve this.

Upvotes: 1

Views: 2240

Answers (2)

slasky
slasky

Reputation: 3086

I had this problem when using .Net Core 2.x with Entity Framework Core 2.2.1. I found that in addition to marking the nested entity as Modified, I also had to attach the nested entity to the DbContext, as it wasn't being tracked automatically from an .Include() call.

db.Attach(movie.Song);
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();

Upvotes: 1

tschmit007
tschmit007

Reputation: 7800

from here you can read:

Note that if the entity being attached has references to other entities that are not yet tracked, then these new entities will attached to the context in the Unchanged state—they will not automatically be made Modified. If you have multiple entities that need to be marked Modified you should set the state for each of these entities individually.

that is your songs are considered as Unchanged. That is why they are not updated.

Upvotes: 2

Related Questions