2
votes

I am redirecting my viewModel from the HttpPost of View1 to the HttpGet of View2. This works without problems. There the user has to accept the terms and agreemens. This should get changed in the viewModel to true (before it is false). And then redirect to the HttpPost of view2.

There something goes wrong. The HttpPost ActionResult of View2 receives the viewModel with all Parameters as NULL (before they were filled)

How can I fix this?

Here is my HttpGet ActionResult for View2:

public ActionResult Verify(QuestionViewModel viewModel)
{
    //Anrede in Viewbag
    if (viewModelVeri.Per_Salutation == 2)
    {
        ViewBag.Per_Salutation = "Frau";
    }
    else
    {
        ViewBag.Per_Salutation = "Herr";
    }

    int? per_region_id = viewModelVeri.Per_Region;
    int per_region_id_nullable = Convert.ToInt32(per_region_id);

    Region region = _repository.GetRegionById(per_region_id_nullable);

    QuestionViewModel viewModel2 = new QuestionViewModel()
    {
        Reg_Name = region.Reg_Name
    };

    //Regionsname in Viewbag
    ViewBag.Reg_Name = viewModel2.Reg_Name; 

    return View(viewModel);
}

And here's my HttpPost ActionResult for View2:

[HttpPost]
public ActionResult Verify(QuestionViewModel viewModel, string tbButton)
{
    //here the ViewModel-Parameters are already NULL

My View:

<div class="panel-body">

@using (Html.BeginForm("Verify", "QuestionForm", FormMethod.Post, new { id = "verifyform" }))
{
@Html.AntiForgeryToken()
    <div class="ctrl-row">
       <div class="form-group">
           <div class="container-fluid">
                 @Html.LabelFor(model => model.Per_Salutation, new { @class = "control-label col-sm-1" })
                 <div class="col-sm-3">
                     @ViewBag.Per_Salutation
                  </div>
            </div>
        </div>
    </div>

    <div class="ctrl-row">
        <div class="form-group">
            <div class="container-fluid">
                @Html.LabelFor(model => model.Per_Name_Last, new { @class = "control-label col-sm-1" })
                <div class="col-sm-3">
                    @Html.DisplayFor(model => model.Per_Name_Last, new { @class = "control-label col-sm-1 non-zero-num" })
                </div>
                @Html.LabelFor(model => model.Per_Name_First, new { @class = "control-label col-sm-1" })
                <div class="col-sm-3">
                    @Html.DisplayFor(model => model.Per_Name_First, new { @class = "control-label col-sm-1 non-zero-num" })
                </div>
            </div>
        </div>
    </div

    <div class="ctrl-row">
        <div class="form-group">
            <div class="container-fluid">
                @Html.LabelFor(model => model.Per_EMail, new { @class = "control-label col-sm-1" })
                <div class="col-sm-8">
                    @Html.DisplayFor(model => model.Per_EMail, new { @class = "control-label col-sm-1 non-zero-num" })
                </div>
            </div>
        </div>
    </div>

    <div class="checkbox">
        <input type="checkbox" id="NutzungsbedingungenAngenommen " />
        <label for="NutzungsbedingungenAngenommen ">
Ich erkläre mich mit den Nutzungsbedingungen einverstanden.
        </label>
    </div>

    <button class="btn btn-default" type="submit" name="tbButton" value="questsend">Senden</button>
}

<script>
    $(document).ready(function () {
        $(".non-zero-num").val($(this).val() == 0 ? ' ' : $(this).val());
    })

    $('#verifyform').on('click', '[value="questsend"]', function () {
        if ($('#agree').is(':checked')) {
            return true;
        }
        else {               
            return false;
        }
    });

</script>

EDIT

Here my QuestionViewModel

public class QuestionViewModel
{
    //Other Properties

    [Required(ErrorMessage = "Bitte die Nutzungsbedingungen annehmen!")]
    public bool NutzungsbedingungenAngenommen { get; set; }
}

My HttpPost Controller for View1:

[HttpPost]
public ActionResult DefaultForm(QuestionViewModel viewModel, string tbButton)
{
    if (ModelState.IsValid)
    {
        try
        {
            if (tbButton.Equals("questsend"))
            {
                return RedirectToAction("Verify", viewModel);
            }
            else if (tbButton.Equals("questupload"))
            {
                //write to DB
                return View(viewModel);
            }
            else
            {
                 dropdownPopulate(viewModel);
                 return View("DefaultForm", viewModel);
            }
        }
        catch
        {
            dropdownPopulate(viewModel);
            return View(viewModel);
        }
    }
    else
    {
        dropdownPopulate(viewModel);
        return View(viewModel);
    }
}
2
I don't get why the HttpGet for View2 has QuestionViewModel parameter. Please show the code of HttpPost for View1 and the code before return View(viewModel); in HttpGet for View2.ekad
@ekad My View1 is a form where the user fills out his data. then the httppost controller redirects this to view2 where the user can say if everything is correct or if he wants to go back and correct something. the viewModel-Parameter in view2 is because i need the data from the viewmodel to show it to the userShaorandra

2 Answers

0
votes
  • Make sure you declare what model should be used by Razor.

    @model QuestionViewModel
    
  • Make sure the name and id of your HTML inputs are in the format expected by the MVC modelbinder. I recommend using the provided HtmlHelpers instead of writing the input tags by hand.

    @Html.CheckBoxFor(m => m.Agree)
    
  • Remove the string tbButton parameter from your POST action

0
votes

The problem is you use Html.DisplayFor to display the property values of viewModel in View2, so the values won't be submitted to the HttpPost method, hence viewModel is null when HttpPost for View2 is executed. Only values in <input>, <textarea> and <select> tags will be submitted.

You can submit the values of viewModel to the HttpPost for View2 by adding Html.HiddenFor inside Html.BeginForm for all properties of viewModel. You should also use Html.CheckBoxFor(m => m.NutzungsbedingungenAngenommen) for the checkbox. Something like below should work

@using (Html.BeginForm("Verify", "QuestionForm", FormMethod.Post, new { id = "verifyform" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Per_Salutation)
@Html.HiddenFor(m => m.Per_Name_First)
@Html.HiddenFor(m => m.Per_Name_Last)
.... // Html.HiddenFor for the rest of QuestionViewModel properties

....
.... // the rest of your code inside the form tag
.... // remove <input type="checkbox" id="NutzungsbedingungenAngenommen " />

@Html.CheckBoxFor(m => m.NutzungsbedingungenAngenommen)
<button class="btn btn-default" type="submit" name="tbButton" value="questsend">Senden</button>
}