9

I have an edit page for my model. When i post model back to my controller, Id property is 0. How can i maintain Id property on post?

I'm posting model to view, so Id property is set on get request. My code is below.

View:

@model xandra.Models.ProjectModel

@using(Html.BeginForm())
{ 
    @Html.HiddenFor(m => m.Id) 
    @Html.LabelFor(m => m.Name)
    @Html.TextBoxFor(m => m.Name)

    <br />

    @Html.LabelFor(m => m.Description)
    @Html.TextAreaFor(m => m.Description)

    <br />

    @Html.LabelFor(m => m.Website)
    @Html.TextBoxFor(m => m.Website)

    <br />

    @Html.LabelFor(m => m.Active)
    @Html.CheckBoxFor(m => m.Active)

    <input type="submit" value="Save" />
}

Controller:

[Authorize]
[HttpGet]
[InitializeSimpleMembership]
public ActionResult EditProject(string id)
{
    using (var entity = new dixraContext())
    {
        var project = entity.Projects.FirstOrDefault(m => m.UrlName == id);


        return View(project);
    }
}

[Authorize]
[HttpPost]
[InitializeSimpleMembership]
public ActionResult EditProject(ProjectModel model)
{
    using (var entity = new dixraContext())
    {
        var project = entity.Projects.FirstOrDefault(m => m.Id == model.Id);

        project.Name = model.Name;
        project.Description = model.Description;
        project.Website = model.Website;
        project.Tags = model.Tags;
        project.Active = model.Active;

        entity.SaveChanges();

        return RedirectToAction("GetProject", project.UrlName);
    }
}

And my model

public class ProjectModel
{
    [Key]
    [Required]
    public long Id { get; set; }

    [Required(AllowEmptyStrings=false)]
    public string Name { get; set; }

    [Required(AllowEmptyStrings=false)]
    public string Description { get; set; }

    [Required]
    public DateTime CreatedDate { get; set; }

    [Required]
    public int Creator { get; set; }

    public string Website { get; set; }

    [Required]
    public int CategoryId { get; set; }

    public virtual List<TagModel> Tags { get; set; }

    public string UrlName { get; set; }

    public bool Active { get; set; }
}
Sefa
  • 8,865
  • 10
  • 51
  • 82

7 Answers7

8

I've seen this happen before, it could be a bug. I have been able to work around it by adding the properties I need to be included in the post by not using the specific's view template syntax.

Instead of this:

@Html.HiddenFor(m => m.Id)

Use this:

<input type="hidden" value="@Model.Id" name="Id"/> 
Ricardo Sanchez
  • 6,079
  • 3
  • 24
  • 31
1

I believe this is to do with asp.net MVC always forcing the model to be returned to the user as was posted to the server. You can override this behaviour using the following attribute...

void ControllerAction([Bind(Exclude = "Id")]SomeModel model)
{
  //action stuff here
}
1

I had the same problem. There was identity specification missing on the DB table primary column, e.g. int identity(1,1). After fixing, entity framework stopped setting the id column to 0.

Milan Švec
  • 1,675
  • 17
  • 21
1

Had the same problem. Here is solution: In controller class in action function (handled posted data) add line:

ModelState.Remove("Id");

If you don't do it, any value assigned by you to the Id property in the Model will be replaced with the value from POST request. So your Id change in the Model has no effect without removing it from ModelState.

Jarek L
  • 19
  • 2
0

@Sefa

You are missing the id in controller action.

project.id = model.id; (missing)

project.Name = model.Name;
project.Description = model.Description;
Code_Tracer
  • 121
  • 1
  • 2
  • 8
0

If you are posting between pages make sure you do not have a hiddenfor on the page the value would be submitted. For example if page 1 sets value a to 1 and routes to page 2 then page 2 would have value a set as 1. However if you route page 2 back to page 1 and page 1 has a hiddenfor for the value you passed to page 2, it would be set the value to 0 if its a long or decimal. I hope this helps if someone is dealing with this problem posting values between different pages.

abovetempo
  • 140
  • 2
  • 9
0

I had the same problem, what solved it for me: changing the setter function from private to public.

mtz
  • 1