0

Consider the following code snippet. GuestResponse is just a class with some properties as a data model.

When visitors invokes localhost\home\RsvpForm the controller return View without data passed to it so the visitors get a blank HTML form.

After populating the form partially (just for simulating the case IsValid=false), the visitors submit the form back to the server. The server checks the validity of the data, in this case, it is invalid so the server returns View().

What I don't understand is why return View(); rather than return View(gr); still preserves previous filled data? How does the View get the previous filled data when we don't pass model data when invoking return View();?

Controller

public class HomeController : Controller
{


    [HttpGet]
    public ViewResult RsvpForm()
    {

        return View();
    }

    [HttpPost]
    public ViewResult RsvpForm(GuestResponse gr)
    {
        if (ModelState.IsValid)
        {
            return View("ThankYou", gr);
        }
        else
        {
            return View();// rather than return View(gr);
        }
    }

}

View

@model PartyInvites.Models.GuestResponse

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<body>
    @using (Html.BeginForm())
    {
        @Html.ValidationSummary()
        Your name: @Html.TextBoxFor(x => x.Name)
        ... other controls go here ...
        <input type="submit" value="Submit RSVP" />

    }
</body>
</html>
kiss my armpit
  • 3,413
  • 1
  • 27
  • 50

3 Answers3

2

You can see previous data without passing model again because ModelState property remembers those values and they are bound to the view again. ModelState is of type ModelStateDictionary and if you want to clear those thata you have to call ModelState.Clear() from your controller.

UPDATE: For more information about ModelState itself check the anwser for question which was already asked here

Community
  • 1
  • 1
Mariusz
  • 3,054
  • 2
  • 20
  • 31
1

The View is only binded to model so that it will populate data from that model if it is passed while returning View and will post that type of model.

For Example:

@model GuestResponse

then:

@Html.TextBoxFor(x=>x.SomeProperty)

It is mvc own bhaviour in this case View will render with Model though you did return View() without passing Model object, but it will consider in view the Model instance with null properties and will render Controls with empty values.

the expression does not care if your model is null or not as it figures out how to render the textbox by looking at the defined property of the strongly-typed class you have defined.

return View(model)

We are passing model instance to view which will be used for data Binding using the HTML helpers we are using.

return View()

We are passing nothing in view from controller action method . So as it is strongly typed with Model and there is no data to bind to it, so it will renders controls with empty values .

UPDATED:

In validation case, in asp.net mvc validation is done on client side as by default jquery-unobtrusive-validate.js is included which handles validation on client side, so the action is never hit until all the form is valid, if you remove jquery-unobtrusive.js and jquery-unobtrusive-validate.js, then you will see that View is populated empty if Model is not valid.

For more clarification refer this question i asked

Community
  • 1
  • 1
Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
  • ok so in your case if Model is not valid obviously validation will be fired and it's on client side so in actual it never came to post action – Ehsan Sajjad May 29 '14 at 07:26
  • In validation case, in asp.net mvc validation is done on client side as by default jquery-unobtrusive-validat.js is included which handles validation on client side, so the action is never hit until all the form is valid, if you remove jquery-unobtrusive.js and jquery-unobtrusive-validate.js, then you will see that View is populated empty if Model is not valid. – Ehsan Sajjad May 29 '14 at 07:31
  • if you comment all ``js`` in Layout page then you will see that it will return wihout data if it goes in ``else`` – Ehsan Sajjad May 29 '14 at 07:38
  • i mean whereever you have included scripts, mostly it is by default in Views --> Shared --> _Layout.cshtml – Ehsan Sajjad May 29 '14 at 07:50
  • it is correct, its some other thing wrong you are doing – Ehsan Sajjad May 29 '14 at 07:52
0

In addition to thing that the accepted answer explains, View.Model is always overwritten by View.ModelState so invoking View(<model>) is just useless thing.

[HttpPost]
public ViewResult RsvpForm(GuestResponse gr)
{
    if (ModelState.IsValid)
    {
        return View("ThankYou", gr);
    }
    else
    {
        return View(gr);// or  return View(GR); where GR is another object of GuestResponse
    }
}
kiss my armpit
  • 3,413
  • 1
  • 27
  • 50