1

So I'm trying to update a model. Here's how my models are set up:

public class Event{
  public int Id {get;set;}
  public string Name {get;set;}
  public DateTime Date {get;set;}
  public int Organizerid {get;set;}

  public virtual User Organizer {get;set;}
}

public class Organizer{
  public int Id {get;set;}
  public string Name {get;set;}

  pubilc virtual iCollection<Event> Events {get;set;}
}

Now I created a ViewModel for the Event (EventViewModel) as whenever I return the regular Event it would throw a loop error on me and I have to use a [JsonIgnore] on every virtual that I have on each model that I pull up. Also, it prevents the web api to return too much info about the current model. Info that is not needed.

My ViewModel

public class EventVM {
    public string Name {get;set;}
    public DateTime Date {get;set;}
}

With that said, this is how I handled my PUT

[HttpPut]
        public HttpResponseMessage Put(int eventId, EventVM event)
        {
            if (ModelState.IsValid && eventId== event.Id)
            {

                try
                {
                    Event upEvent = dbcontext.Event.FirstOrDefault(e => e.Id == eventId);
                    upEvent.Name = eventVM.Name;
                    upEvent.Date = eventVM.Date;

                    dbcontext.SaveChanges();
                    return Request.CreateResponse(HttpStatusCode.OK);
                }catch(Exception ex){
                    return Request.CreateResponse(HttpStatusCode.BadRequest);
                }
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
        }

My problem is that it's not saving the updates. I would do a TryUpdateModel but it doesn't seem like it can be used with WebApi. Help! Thoughts?

AndreyAkinshin
  • 18,603
  • 29
  • 96
  • 155
gdubs
  • 2,724
  • 9
  • 55
  • 102
  • what database are you using? "icdb.SaveChanges()" I think it should be dbcontext.SaveChanges(), right? – Stay Foolish Mar 29 '13 at 04:00
  • my bad, i just changed it. that came from another project. – gdubs Mar 29 '13 at 04:29
  • have you put debug that? I assume you are using entity framework. and i think you code looks correct to me... just make sure you can retrieve the Event by the id you pass in – Stay Foolish Mar 29 '13 at 05:11
  • yeah i can get the instance with the id. it just desn't seem like it's getting connected to the context. – gdubs Mar 29 '13 at 16:39
  • the problem is your form is probably doing a post, this has already been on here before take a look here: http://stackoverflow.com/questions/8182620/put-or-delete-verb-in-asp-net-mvc-on-html-form as a side note, why are you not just posting the model, or use tryupdatemodel but with formcollection form rather than the model TryUpdateModel(formcollection); – davethecoder Mar 30 '13 at 00:49
  • Like I said on the OP, this is not an MVC Html, it's a Web Api. It doesn't have a tryupdatemodel on the namespaces unlike from the link you posted. I know what you mean about tryupdatemodel on the formcollection as that's what i generally use for posts. The data / values are coming from either a set up from fiddler or an ios app. – gdubs Mar 30 '13 at 01:11
  • I'm not sure what is the problem. Is the problem that entity isn't saved to database with dbcontext.SaveChanges()? Can you fix the code ? You got a lot of errors and mistakes there. One example can be event.Id ( keyword event is reserved and can not be used as variable and Id doesn't exsists in EvenVM ). Please make your example runnable. – jan salawa Mar 31 '13 at 08:40
  • Changed the instance name, still the same. The problem is that the updates I placed on the upEvent is not being saved. I'm trying to figure what the counterpart of TryUPdateModel is for the webapi? Or is there anY? as the tryupdatemodel on the html mvc updates the instance and calling the dbcontext.savechanges saves the changes, and it doesn't seem to have that on the webapi namespaces. – gdubs Mar 31 '13 at 14:08
  • Are you using entity framework as context technology? What access have dbcontext object? – jan salawa Mar 31 '13 at 18:01
  • You test for _eventId== event.Id_ but in your viewmodel EventVM I don't see the Id property? Is this a typo or do you just never get past there? – AardVark71 Apr 03 '13 at 14:22

3 Answers3

0

I'm assuming you know you are hitting the method... so

  1. Check that the params are getting bound, if not you'll never make it past your first check and you won't see an error because the mv params aren't required. Well you'll see a bad request on the client but nothing in code.

  2. As ArdVark71 pointed out, your view model doesn't contain an id

  3. Make sure your dbContext is not null

  4. In your try upEvent.Name = eventVM.Name; upEvent.Date = eventVM.Date; eventVM doesn't exist

  5. Does your entity have requirements that you aren't populating? Like the organizer?

  6. Also, Date & Name are bad variable names, our db guys would go nutz =]

Anyway, sorry if that sounded too much like a code review, but its hard to troubleshoot when there's code issues. Also assuming these are all just typo's you still could have issues with your dbcontext etc. so if everything else seems right, step through your code and look at the dbcontext, does it hide anything on the save, etc?

Good luck

matto0
  • 1,065
  • 2
  • 12
  • 26
0

Assuming you are using Entity Framework and that your example may be somewhat incomplete from the real code.. it could be a problem with detached entities.

Try adding something along the lines of:

upEvent.State = EntityState.Modified);
dbcontext.SaveChanges();

dbcontext.SaveChanges();

See this question for more information.

Community
  • 1
  • 1
JBeagle
  • 2,630
  • 2
  • 18
  • 20
0

Maybe somewhere in your code you have?

context.Configuration.AutoDetectChangesEnabled = false;

After you modify event you could also check this if context sees properties as modified

var nameIsModified = dbcontext.Entry(upEvent).Property(u => u.Name).IsModified;

Also you could force update to database (although I wouldn't consider this as solution but rather as workaround until you diagnose your problem)

dbcontext.Entry(upEvent).Property(u => u.Name).IsModified = true;

Marking a property as modified forces an update to be send to the database for the property when SaveChanges is called even if the current value of the property is the same as its original value - MSDN

Piotr Perak
  • 10,718
  • 9
  • 49
  • 86