Form only works when Id is nullable?! Why?

Last post 09-17-2009 8:57 PM by shapper. 10 replies.

Sort Posts:

  • Form only works when Id is nullable?! Why?

    09-16-2009, 6:49 PM
    • Contributor
      3,569 point Contributor
    • shapper
    • Member since 11-28-2004, 4:15 PM
    • Posts 2,947

    Hello,

    When I submit a Create form the model is always considered invalid.

    However if I change the Id from Int32 to Int32? it works fine ... Any idea why?

    Do all my models need to have the Id as nullable? This is really strange ...

    Here is my view model code (it is working because Id is nullable):

      public class ArticleFormViewModel : PageViewModel {
        public Int32 Id { get; set; }
        public String Content { get; set; }
        public String Title { get; set; }
      } // ArticleFormViewModel


    The action:

        [AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken, ValidateInput(false)]
        public ActionResult Create(ArticleFormViewModel model) {
          if (ModelState.IsValid) {
            articleRepository.Create(Mapper.Map<ArticleFormViewModel, Article>(model));
            session.Commit();
            return RedirectToAction("List");
          } else {
            return View(model);
          }
        } // Create


    And in the view I have the following:

     <%Html.BeginForm("Create", "Article", FormMethod.Post, new { @class = "Horizontal" });%>
        <%Html.RenderPartial("Form");%>
          <%=Html.SubmitButton("Submit", "Submit", new { @class = "Submit" })%>  
          <%=Html.AntiForgeryToken()%>
        </div>


    Thanks,

    Miguel

  • Re: Form only works when Id is nullable?! Why?

    09-16-2009, 7:10 PM
    Answer
    • Contributor
      6,805 point Contributor
    • gerrylowry
    • Member since 07-03-2008, 1:46 AM
    • alliston ontario canada
    • Posts 2,298

    wild guess:  if your Id is an Identity, you likely need to use:

             // POST: /Home/Create 

    [AcceptVerbs(HttpVerbs.Post)]

    public ActionResult Create([Bind(Exclude="Id")] Movie movieToCreate)

    see the example in:

    http://www.asp.net/learn/mvc/tutorial-21-cs.aspx

    Create a Movie Database Application in 15 Minutes with ASP.NET MVC


    Gerry Lowry, Principal
    Ability Business Computer Services ~~ Because it's your Business, our Experience Counts!
    68 John W. Taylor Avenue
    Alliston · Ontario · Canada · L9R 0E1 · gerry.lowry@abilitybusinesscomputerservices.com

    Websites:
    http://abilitybusinesscomputerservices.com
    http://gerrylowryprogrammer.com ~~ résumé & testimonials
    http://veganoccasions.com ~~ recipes by Susan
  • Re: Form only works when Id is nullable?! Why?

    09-16-2009, 7:11 PM
    • Contributor
      6,805 point Contributor
    • gerrylowry
    • Member since 07-03-2008, 1:46 AM
    • alliston ontario canada
    • Posts 2,298

    P.S.:  an Indentity Id does not exist until after the record has been created, hence the need to exclude it.

    Gerry Lowry, Principal
    Ability Business Computer Services ~~ Because it's your Business, our Experience Counts!
    68 John W. Taylor Avenue
    Alliston · Ontario · Canada · L9R 0E1 · gerry.lowry@abilitybusinesscomputerservices.com

    Websites:
    http://abilitybusinesscomputerservices.com
    http://gerrylowryprogrammer.com ~~ résumé & testimonials
    http://veganoccasions.com ~~ recipes by Susan
  • Re: Form only works when Id is nullable?! Why?

    09-16-2009, 7:12 PM
    Answer
    • Participant
      804 point Participant
    • andrewjboyd
    • Member since 05-15-2009, 5:26 AM
    • Brisbane, Australia
    • Posts 173

    I assume your ID is an identity column in the database?  ie the user doesn't set it?

    ID's need to be nullable because they aren't set on the form and to tell you the truth, you shouldn't need an ID in your model because when you create a record you don't need it and when you edit a record the id is being passed in via the url

    Dont forget to click "Mark as answer" on the post that helped you.

    ================================================
    Why catch a fish to feed someone, when you can teach them to fish and they can feed themselves
  • Re: Form only works when Id is nullable?! Why?

    09-16-2009, 7:26 PM
    • Contributor
      3,569 point Contributor
    • shapper
    • Member since 11-28-2004, 4:15 PM
    • Posts 2,947

    andrewjboyd:

    I assume your ID is an identity column in the database?  ie the user doesn't set it?

    Yes it is ...

    andrewjboyd:

    ID's need to be nullable because they aren't set on the form and to tell you the truth, you shouldn't need an ID in your model because when you create a record you don't need it and when you edit a record the id is being passed in via the url

    You are correct. I removed the Id from the view model and it worked fine.

    Thanks,

    Miguel

  • Re: Form only works when Id is nullable?! Why?

    09-17-2009, 6:58 AM
    • Contributor
      3,569 point Contributor
    • shapper
    • Member since 11-28-2004, 4:15 PM
    • Posts 2,947

    Not so fast!!!

    You can't ommit the Id from the model ... Then how would you update the model?

        public ActionResult Edit(ArticleFormViewModel model) {
    
          if (ModelState.IsValid) {
            articleRepository.Update(model);
            session.Commit();

    You will not be able to update the model if the model id does not exist.

  • Re: Form only works when Id is nullable?! Why?

    09-17-2009, 2:18 PM
    • Contributor
      4,616 point Contributor
    • levib
    • Member since 07-23-2007, 7:50 PM
    • Redmond, WA
    • Posts 794
    • AspNetTeam

    Exclude the ID when binding to the actual model, as Gerry suggested.

  • Re: Form only works when Id is nullable?! Why?

    09-17-2009, 5:49 PM
    • Participant
      804 point Participant
    • andrewjboyd
    • Member since 05-15-2009, 5:26 AM
    • Brisbane, Australia
    • Posts 173

    Actually you don't need it in your model if you have your code setup like this

    public ActionResult Edit(int id, ArticleFormViewModel model) {   
      
      if (ModelState.IsValid) {   
        articleRepository.Update(model);   
        session.Commit(); 


    Shouldn't the Model really reflect the fields that are being modified?  The id of the record being modified should be being passed in via the url, for example http://www.test.com/ArticleRepository/Edit/5436

     

    Dont forget to click "Mark as answer" on the post that helped you.

    ================================================
    Why catch a fish to feed someone, when you can teach them to fish and they can feed themselves
  • Re: Form only works when Id is nullable?! Why?

    09-17-2009, 6:54 PM
    • Contributor
      3,569 point Contributor
    • shapper
    • Member since 11-28-2004, 4:15 PM
    • Posts 2,947

    andrewjboyd:

    Shouldn't the Model really reflect the fields that are being modified? 

    To be honest I associated that more when using FormCollection ...

    When using objects most of the code I've seen lately has the Id inside the model.

    But I see a model as more general.

    For example all my view models inherit PageViewModel which contains common data like page Title, Keywords, SelectLists needed on the form, etc.

    In fact if not seing it this way would be impossible to pass some of these things.

    I really like MVC but I think ViewModel was never really discussed and there is a lot of confusion and a lot of different implementations ...

    I hope MVC team release some guidelines and solve some of the problems with MVC 2.0

  • Re: Form only works when Id is nullable?! Why?

    09-17-2009, 8:57 PM
    • Participant
      804 point Participant
    • andrewjboyd
    • Member since 05-15-2009, 5:26 AM
    • Brisbane, Australia
    • Posts 173

    I probably do need to change that statement to "The Model should reflect the variables on the View"

    FormCollection is untyped though.

    For me, the record ID is a constant which can not change, placing this into the Model would allow an injection attack to overwrite details of another record (one of the features & pit falls of MVC), but obviously if you put a Ignore "ID" it wouldn't, but for me also that is extra code you have to add which can be handled with a simple parameter.  I agree, there needs to be some guidelines, I just think if you put the ID in the Model it's not really making it generic enough if you wanted to use it to "create" a record.  I like being able to have 1 Model (generally) for Adding/Editing (for the sake of passing those values you menioned)... just my 2 cents :)

    Dont forget to click "Mark as answer" on the post that helped you.

    ================================================
    Why catch a fish to feed someone, when you can teach them to fish and they can feed themselves
  • Re: Form only works when Id is nullable?! Why?

    09-17-2009, 8:57 PM
    • Contributor
      3,569 point Contributor
    • shapper
    • Member since 11-28-2004, 4:15 PM
    • Posts 2,947

    Hello,

    I removed the id from the model and changed my action to:

        [AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken, ValidateInput(false)]
        public ActionResult Edit(Int32 id, ArticleFormViewModel model) {
          if (ModelState.IsValid) {
            Article article = Mapper.Map<ArticleFormViewModel, Article>(model);
            article.Id = id;
            articleRepository.Update(article);
            session.Commit();
            return RedirectToAction("List");
          } else {
            return View(model);
          }
        } // Edit

    Not sure if this is the best way but it is working and I have the ID as parameter in the action and out of the model.

Page 1 of 1 (11 items)