3

I had an application that was weakly typed and I decided that it would be best to change it to strongly typed... however I am running into some issues.

My controller delivers a new model to my razor view (which has a small form in it). I use textboxfor(model => mymodel.type) and post it back to my controller. I can see that the post has the needed values but once it hits my controller the model is null.

 [HttpGet]
        public ActionResult LogIn(int Op)
        {
                    LoginWrapperClass newOperation = new LoginWrapperClass();
                    newOperation.newL = new ePSDB();
                    newOperation.newP = new eP(Op, Request.Cookies["State"].Value);
                    return View(newOperation);
            }

  [HttpPost, ValidateInput(true)]
        public ActionResult LogIn(LoginWrapperClass newOperation)
        {
            if (ModelState.IsValid)
            {
                newOperation.LookUp();
                if (newOperation.newP != null)
                {
                    //stuff

                    return RedirectToAction("RecordOp", "Authenticated", newOperation.newP);
                }
            }

View:

@model WebApp.Models.LoginWrapperClass

@{
    ViewBag.Title = "Operation";
}

<div id="indexOp" class="textCenter">
    <div id="time"></div>
    <div id="loader" class="hiddenAndGone"><img src="~/Content/Images/loader.gif"></div>
    <div id="operations">
        @using (Html.BeginForm())
        {
            //Html.AntiForgeryToken();
            <div class="Ops">
                <div>
                    @Html.TextBoxFor(model => model.newL.BADGE_NBR, new { @id = "BADGE_NBR", @class = "readFont", autofocus = "autofocus", autocomplete = "off", placeholder = "" })
                    @Html.TextBoxFor(model => model.newP.PUNCH_TYPE, new { type="number", @class = "hidden" })
                </div>
                <div id="submit" class="hidden">
                    <input type="submit" value="validate" class="validateSubmit"  />
                </div>
            </div>
        }
    </div>
</div>

Basically, through fiddler, I can see the post contains the values I need but the controller's model is null. Why?

What I am posting is this: newL.BADGE_NBR=18845733&newP.PUNCH_TYPE=1


I am adding class declarations here:

 public class LoginWrapperClass
    {
        public ePSDB newL { get; set; } //fixed per Aaron's response... still no binding
        public eP newP{ get; set; }
        public void LookUp()
        {
            using (var db = new PSTestEntities())
            {
                IEnumerable<ePSDB> foundInDb;
                foundInDb = db.ePSDBs.Where(foundE => this.newL.BADGE_NBR.ToString() == foundE.BADGE_NBR.ToString().Substring(3));

                if (foundInDb.Count() > 0)
                {

                    this.newL = foundInDb.First();
                    this.newP.BADGE_NBR = this.newL.BADGE_NBR;
                    this.newP.EMPLID = this.newL.EMPLID;
                }
            }
        }
    }
//This is a partial class that will be added to but as of now this is all
    public partial class ePSDB
        {
            [Key]
            public int P_Key { get; set; }
            public int EMPLID { get; set; }
            [Required]
            public long BADGE_NBR { get; set; }
            public Nullable<System.DateTime> BIRTHDATE { get; set; }
            public string NAME { get; set; }
        }

    public partial class eP
    {
        [Required]
        public long BADGE_NBR { get; set; }
        [Required]
        public int EMPLID { get; set; }
        [Required]
        public System.DateTimeOffset PUNCH_DTTM { get; set; }
        [Required]
        public int PUNCH_TYPE { get; set; }
        public Nullable<double> TL_QUANTITY { get; set; }
        [Key]
        public long P_Key { get; set; }
    }
 public partial class eP
    {
        [NotMapped]
        public bool containsQuestions = false;
        [NotMapped]
        public List<Question> questions { get; set; }
        public eP(int punchType, string state)
        {
            PUNCH_DTTM = DateTimeOffset.UtcNow;
            PUNCH_TYPE = punchType;
            if((punchType == 1 || punchType == 2) & containsQuestions)
                questions = getQuestions(state, punchType);
        }
    private List<Question> getQuestions(string state, int punchType){
        List<Question> Questions = new List<Question>();
      //do stuff
      return Questions
     }
        ///plus other methods not used in this controller/view
    }
public class Question
    {
        public string QuestionName { get; set; }
        public string QuestionString { get; set; }
        public int Answer { get; set; }
    }
user2072256
  • 153
  • 7

1 Answers1

3

You are suffering from this I believe: ASP.net MVC - Model binding excludes class fields?

You have this declaration using fields:

public class LoginWrapperClass
{
    public ePSDB newL;
    public eP newP;
    //...
}

But you need to be using properties:

public class LoginWrapperClass
{
    public ePSDB newL {get;set;}
    public eP newP {get;set;}
    //...
}
Community
  • 1
  • 1
AaronLS
  • 37,329
  • 20
  • 143
  • 202
  • Hi Aaron, thanks for the help. However it looks like this is still not binding correctly even after the get and set. When my view posts back it is looking for a parameterless controller... If I force it to use my controller with the wrapperclass model (by using beginfrom parameters in view) it will post a `null` model. Any ideas? – user2072256 Apr 24 '15 at 18:49
  • @user2072256 Did you look at the request in the browser? I think by default BeginForm generates a GET request, and you action is marked HttpPost. BeginForm lets you specify the Method as Post. A route debugger may help if that doesn't solve it: http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx/ – AaronLS Apr 24 '15 at 20:22