0

I am quite new to MVC, and am having a bit of trouble submitting a form and having the controller pick up the posted values.

What seems to be happening is that while the form does post to the correct method in the controller, the model that is passed through is full of empty values - as if it's not being populated by the form.

I've tried to create it in the same way as the default Login control, but I'm obviously missing something somewhere. Can anyone please shed any light?

My code is below:

MODEL

Public Class ContactUsDetails Private _name As String Private _email As String Private _details As String Public ReadOnly Property Name() As String Get Return _name End Get End Property Public ReadOnly Property Email() As String Get Return _email End Get End Property Public ReadOnly Property Details() As String Get Return _details End Get End Property Public Sub New(ByVal name As String, ByVal email As String, ByVal details As String) _name = name _email = email _details = details End Sub Public Sub New End Sub End Class 

VIEW

@ModelType TestMVC.ContactUsDetails @Code ViewData("Title") = "ContactUs" End Code @Using Html.BeginForm() @<fieldset> <legend>Contact Us</legend> <div class="editor-label"> @Html.LabelFor(Function(m) m.Name) </div> <div class="editor-field"> @Html.TextBoxFor(Function(m) m.Name) </div> <div class="editor-label"> @Html.LabelFor(Function(m) m.Email) </div> <div class="editor-field"> @Html.TextBoxFor(Function(m) m.Email) </div> <div class="editor-label"> @Html.LabelFor(Function(m) m.Details) </div> <div class="editor-field"> @Html.TextBoxFor(Function(m) m.Details) </div> <p> <input type="submit" value="Submit" /> </p> </fieldset> End Using 

CONTROLLER

Namespace TestMVC Public Class FormsController Inherits System.Web.Mvc.Controller ' ' GET: /Forms Public Function ContactUs() As ActionResult Return View() End Function <HttpPost()> _ Public Function ContactUs(model As ContactUsDetails) As ActionResult If ModelState.IsValid Then End If Return View(model) End Function End Class End Namespace 
4
  • Your model looks strange, where do you call the constructer? You should also be passing the model to the view initially. Commented May 9, 2013 at 10:04
  • It probably is strange, I suspect I'm doing it wrong - only started looking at MVC a couple of weeks ago. It doesn't need to the contructor with the parameters, no. It does however throw an error if the parameterless contstructor is not there when the blank form initially loads. Commented May 9, 2013 at 10:10
  • When you say 'pass the model to the view initially', what do you mean? Does that remove the need for the parameterless constructor? Commented May 9, 2013 at 10:14
  • Ill post how I do it in an answer below, give me a sec Commented May 9, 2013 at 10:18

3 Answers 3

1

I'm not too expert with VB, but I your model should have the properties editable, looking at your code it seems that your modle is readonly. So the model binder can not fill in the values

Sign up to request clarification or add additional context in comments.

1 Comment

Well spotted, that was it. Can't believe I didn't see that! Thanks for the help!
1

The model binder does not populate the model by calling a constructor, but by setting property values. Hence, your model properties must not my read only.

1 Comment

Yep, Iridio just pointed that out to me. Making the properties get/set worked a treat. Thanks for the help, much appreciated!
0

MODEL:

 public class FileSetViewModel { public int FileId { get; set; } [DisplayName("From Policy")] public string FromPolicy { get; set; } [DisplayName("Policy location")] public string PolicyLocation { get; set; } [DisplayName("Policy type")] public string PolicyType { get; set; } [DisplayName("File name")] public string FileName { get; set; } [DisplayName("Device Type")] public string DeviceType { get; set; } } public class FileSetListViewModel { public List<FileSetViewModel> FileSetList { get; set; } } 

VIEW:

@section DeviceContent { <h2>File set</h2> @if (Model.FileSetList.Count() > 0) { <table> <caption>Files loaded on current device</caption> <thead> <tr> <th scope="col">From Policy</th> <th scope="col">Policy Location</th> <th scope="col">Policy Type</th> <th scope="col">File Name</th> <th scope="col">Device Type</th> <th scope="col">View</th> </tr> </thead> <tbody> @foreach (var fileSet in Model.FileSetList) { <tr> <td>@fileSet.FromPolicy</td> <td>@fileSet.PolicyLocation</td> <td>@fileSet.PolicyType</td> <td>@fileSet.FileName</td> <td>@fileSet.DeviceType</td> <td><a href="#" onclick="popitup('viewer/@fileSet.FileId');">View</a></td> </tr> } </tbody> </table> } } 

Controller:

 [HttpGet] public ActionResult Index(int id) { FileSetListViewModel model = _policiesLogic.GetFilesSetForDevice(id); return View(model); } [HttpPost] public ActionResult Index(FileSetListViewModel model) { // preconditions if (null == model) throw new ArgumentNullException("model"); if (ModelState.IsValid) { // Do stuff } else // Validation error, so redisplay data entry form { return View(model); } } 

Even if the model is empty i always pass an instance to the view, though i could be wrong as this is my first mvc project as well...

1 Comment

Ah, OK. I haven't done that as I didn't think it necessary in this case. It's a contact us feedback form, so it's not pre-populating with anything. It's purely a on-way transaction.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.