Mark
Mark

Reputation: 133

Trouble posting from MVC form

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

Upvotes: 0

Views: 54

Answers (3)

DavidB
DavidB

Reputation: 2596

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...

Upvotes: 0

Mikael
Mikael

Reputation: 40

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.

Upvotes: 1

Iridio
Iridio

Reputation: 9271

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

Upvotes: 1

Related Questions