Home > Mobile >  Why does the model not pass back to the controller on post?
Why does the model not pass back to the controller on post?

Time:03-16

My model is not passing back to the controller on post. I'm doing this in another part of the application and it works fine. I have probably missed something but I have been over this for two days and I can't see it. I hope you can assist.

My View:

@model Towins.Models.T_Complaints
@{
  ViewBag.Title = "UpsertComplaint";
  Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm("UpsertComplaint_Post", "Home", FormMethod.Post))
{
@Html.AntiForgeryToken()

// The model is working on the get. 
// The date has been supplied in the get and I have it in the view. 
// The Model.Id == 0 as this is the add portion of the upsert. 
// Can't even start working on the update portion as the model is not coming back at all.

<h4>@(Model.Id!=0 ? "Edit" : "Add") Complaint</h4>
<hr />
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.WreckerID)
<div  style="text-align: center">
    <div >
        <div >
            <label for="NewWrecker" >Wrecker Company Name</label>
            <input type="text" disabled  id="WreckerCo" name="WreckerCo" value="@ViewBag.WreckerCo" />
        </div>
    </div>
    <div >
        <div id="DateOfComplaint-group"  data-date-format="dd/mm/yyyy">
            <label for="ComplaintDate" >Complaint Date:&nbsp;</label>
            @Html.EditorFor(model => model.ComplaintDate, "{0:mm/dd/yyyy}", new { htmlAttributes = new { @class = "form-control" } })
            <span ><i ></i></span>
        </div>
    </div>

    // Model Fields deleted for brevity

    <div >
            <div >
                <div >
                    <input type="submit" name="NewComplaint"  value="Save" />
                </div>
                <div >
                    <a href="@Url.Action("ComplaintList", new { wId = ViewBag.WreckerId })" >Back to Complaints List</a>
                </div>
            </div>
        </div>
</div>

}

My Controller: This is posting properly but the model is null

    [HttpPost]
    public ActionResult UpsertComplaint_Post(T_Complaints complaint)

    {

    // complaint is null here.
    // This is as far as I have gotten. I can't copmplete the post code until I
    // can get the model back to this point.

        return RedirectToAction("ComplaintList", new RouteValueDictionary(new { wId = complaint.WreckerID }));
    }

And just for completeness, here is the model:

    public class T_Complaints
{
    public int Id { get; set; }
    [DataType(DataType.MultilineText)]
    public string Complaint { get; set; }
    [DataType(DataType.MultilineText)]
    [Display(Name = "Complainant Info")]
    public string ComplainantInfo { get; set; }
    [Required]
    public int WreckerID { get; set; }
    [Required]
    public bool Resolved { get; set; }
    [Required]
    [DataType(DataType.Date)]
    [Display(Name = "Complainant Date")]
    public DateTime ComplaintDate { get; set; }
    [DataType(DataType.Date)]
    [Display(Name = "Resolution Date")]
    public DateTime ResolutionDate { get; set; }
    [DataType(DataType.MultilineText)]
    public string Resolution { get; set; }
}

Here is the Get Action

       [HttpGet]
    public ActionResult UpsertComplaint(int? cid, string WreckerCo, int wId)
    {
        T_Complaints complaint = new T_Complaints();
        ViewBag.WreckerCo = WreckerCo;
        ViewBag.wId = wId;
        if (cid == null)

        // This is true so this is the block that executes on Add

        {
            complaint.ComplaintDate = DateTime.Now;
            complaint.WreckerID = wId;
            return View(complaint);
        }
        using (con)
        {
            con.Open();
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM [Towins].[dbo].[T_Complaints] WHERE Id = "   cid, con))
            {
                SqlDataReader reader = cmd.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        complaint.Resolved = (bool)reader["Resolved"];
                        complaint.Id = (int)reader["Id"];
                        complaint.Complaint = reader["Complaint"].ToString();
                        ViewBag.WreckerId = reader["WreckerID"];
                        complaint.ComplainantInfo = reader["ComplainantInfo"].ToString();
                        complaint.ComplaintDate = (DateTime)reader["ComplaintDate"];
                        if (reader["ResolutionDate"].ToString() != "")
                        {
                            complaint.ResolutionDate = (DateTime)reader["ResolutionDate"];
                        }
                        complaint.Resolution = reader["Resolution"].ToString();
                    };
                }
                reader.Close();
            }
            con.Close();
        }
        return View(complaint);
    }

Okay. I've gotten some downgrades for insufficient research and not posting the question properly. I'm going to reattempt to get this question answered. I have simplified everything with test code and reposted it here:

My new test model in it's entirety:

namespace Towins.Models
{
    public class T_ComplaintsTest
    {
        public int Id { get; set; }
        public string Complaint { get; set; }
    }
}

My new test View in its entirety:

@model Towins.Models.T_ComplaintsTest

@{
    ViewBag.Title = "AddComplaint";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Add Complaint</h2>


@using (Html.BeginForm("AddComplaint", "Home", FormMethod.Post))
{
    <div  style="text-align: center">
        <div >
            <div >
                @Html.LabelFor(model => model.Complaint)
                @Html.EditorFor(model => model.Complaint, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div >
            <div >
                <div >
                    <input type="submit" name="AddComplaint"  value="Save" />
                </div>
            </div>
        </div>
    </div>
}

And, my action methods in their entirety:

    [HttpGet]
    public ActionResult AddComplaint()
    {
        T_ComplaintsTest complaint = new T_ComplaintsTest();
        complaint.Complaint = "Test";
        return View(complaint);
    }
    [HttpPost]
    public ActionResult AddComplaint(T_ComplaintsTest complaint)

    {
        //Breakpoint here.  Why is complaint null?
        return RedirectToAction("ComplaintList", new RouteValueDictionary(new { wId = 247 }));
    }

When the Get occurs, it successfully renders "Test" in the field. When I hit the submit button, it stops at the breakpoint "return RedirectToAction..." Why at this point is complaint null? I can see no reason for the life of me why it should be null. The view is of this Model. Should it not be there?

CodePudding user response:

The answer is simply that the model binder is getting confused.

Inside your T_Complaints class, you have a property called Complaint.
In your post action, you used complaint as the model name:

public ActionResult AddComplaint(T_ComplaintsTest complaint)

Simply changing the model name in the controller will make things less complicated for the model binder and your model won't be null.

public ActionResult AddComplaint(T_ComplaintsTest complaintsTest) // this won't be null anymore.
  • Related