0

I'm trying to follow best practices to add data validation to my UI. I want to add the data validation to the ViewModel and then if that data is valid, submit the form to the controller. However, the data the controller receives is always null values. Any idea what I'm doing wrong? This whole MVVC architecture is confusing me. I had it working when I was submitting the form using the model but I can't get data validation on the model?

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> CreateResource(AddResourceViewModel model)
        {
            if (ModelState.IsValid)
            {
                await (//does something);
            }
            return View();
        }

ModelView:

public class AddResourceViewModel
{

        public string User { get; set; }       
        public string ResourceName { get; set; }
        public int ResourceId { get; set; }
        public string Model { get; set; }
        public float Latitude { get; set; }
        public float Longitude { get; set; }
        public decimal Amount { get; set; }
        public int UnitId { get; set; }
        public int PrimaryEsfId { get; set; }
        public IEnumerable<string> Capabilities { get; set; }
        public IEnumerable<int> AdditionalEsfs { get; set; }

        public Resource Resource { get; set; }


}

Beginning of cshtml form:

@model erms.ViewModel.AddResourceViewModel
<form asp-controller="AddResource" asp-action="NewResource" method="post" class="form-horizontal">
<div class="panel panel-default">
    <div class="panel-body">
        <form asp-controller="AddResource" asp-action="CreateResource" method="post" class="form-horizontal">

            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="ResourceId" class="col-md-2 control-label">Resource ID:</label>
                <div class="col-md-10">
                    <input asp-for="ResourceId" class="form-control" value="@Model.Resource.ResourceId" readonly />
                    <span asp-validation-for="ResourceId" class="text-danger"></span>
                </div>
            </div>
Tieson T.
  • 20,774
  • 6
  • 77
  • 92
vercingortix
  • 199
  • 2
  • 15

3 Answers3

2

replace return View(); to return View(model);.

Cologler
  • 724
  • 6
  • 18
1

This kind of stuff makes me so frustrated when learning new architecture but I've figured it out. It is a naming convention issue. I've addressed the issue and it is now working properly:

The conflicting names were:

public string Model { get; set; }

from my ViewModel, and:

public async Task<IActionResult> NewResource(AddResourceViewModel model)

from my controller. So the Model is conflicting with the model...

According to: http://ideasof.andersaberg.com/development/aspnet-mvc-4-model-binding-null-on-post

Do not name your incoming variables in the Action the same as you do in the model being posted. That will mess up the Model Binder.

vercingortix
  • 199
  • 2
  • 15
0

Perhaps I'm thinking the problem would be you're not using razor to submit the form. This is what I have in mind:

@model <AddResourceViewModel>

@using(Html.BeginForm()) {

<div asp-validation-summary="All" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="ResourceId" class="col-md-2 control-label">Resource ID:</label>
            <div class="col-md-10">
                @Html.TextboxFor(x => x.ResourceId)
                @Html.ValidationMessageFor(x => x.ResourceId)
            </div>
        </div>
}

Since this is what I usually use to validate my form, perhaps this is worth considering. I might be wrong though.

Sonny Recio
  • 99
  • 1
  • 8
  • I added the form controller submission on the cshtml for the tag helper. I should have mentioned this is using .NET Core so TagHelpers have taken the place of Html Helpers: https://dannyvanderkraan.wordpress.com/2016/04/19/asp-net-core-1-0-goodbye-html-helpers-and-hello-taghelpers/ – vercingortix Nov 13 '16 at 02:28