J4X
J4X

Reputation: 119

MVC HTTP Post input return null

Controller:

public ActionResult MyController()
{
    ViewBag.DateNow = DateTime.Now.ToString("yyyy-MM-dd");
}

[HTTPPost]
public ActionResult MyController(string fromDate)
{
    ViewBag.DateNow = fromDate;
}

View:

@using (Html.BeginForm("MyController", "Account", FormMethod.Post))
{
    //datepicker class: bootstrap-datepicker.js
    <input id="fromDate" type="text" class="datepicker" />

    <buttontype="submit" value="Search" class="btn btn btn-primary">
        Search
    </button>
}

What I'm trying to achieve is before POST the data that pass into ViewBag.DateNow is the current date and it successfully bring in to the view. However when I'm trying to fill up the input form with (eg: 2016-05-10) and click on the Search button. But seems like the fromDate string return NullReferenceException. I'm trying out with some solution online but I still can't get it right and that's why I decided to get this posted up. Thanks in advance!

Upvotes: 2

Views: 2070

Answers (2)

Brendan Vogt
Brendan Vogt

Reputation: 26028

For this to work properly you need to specify the name attribute in your textbox. It needs to be the same value as the input variable in your HTTP post action method, namely fromDate. Currently the id attribute is set to fromDate:

<input id="fromDate" name="fromDate" type="text" value="@ViewBag.DateNow" />

If you do not specify this name attribute then when you post your form fromDate will always be null. Specifying it like above will make sure that fromDate will always have a value (if entered).

I want to go a bit off-topic here, I would like to suggest that you make use of view models for your form submissions. Instead of having individual input variables in your action method you can just have your view model as input parameter.

I wrote an answer as to what view models are here, please go and read it if you have the time:

What is ViewModel in MVC?

Working on your example, I would have a view model that contains just one property, namely FromDate. FromDate will contain the value in your textbox. It is setup as a string because you want to pass it a formatted date value:

public class TestModel
{
     public string FromDate { get; set; }
}

This value will be set in your HTTP get action method and the view model will be sent to the view:

public ActionResult Index()
{
     TestModel model = new TestModel();
     model.FromDate = DateTime.Now.ToString("yyyy-MM-dd");

     return View(model);
}

In your view you will accept this view model and create the form accordingly:

@model WebApplication_Test.Models.TestModel

@using (Html.BeginForm())
{
     @Html.TextBoxFor(m => m.FromDate)
     <button type="submit">Search</button>
}

When you submit this form, you need an HTTP post action method to handle the submission. Because the view is bound to the view model, the action method will accept it as an input parameter:

[HttpPost]
public ActionResult Index(TestModel model)
{
     // Do what you need to do
     string date = model.FromDate;

     return View(model);
}

Your way of doing it is also correct. I have just shown you an alternative way to do it. Some day you might have a huge form with many input values, then my approach will be 'cleaner'.

Upvotes: 2

Husni Salax
Husni Salax

Reputation: 2020

Try this:

1) Replace with [HttpPost] instead of [HTTPPost]

2) You should add name=" " for input like this:

 <input id="fromDate" name="fromDate" type="text" class="datepicker" />

Upvotes: 2

Related Questions