C-Pfef
C-Pfef

Reputation: 129

MVC Validation not working

I have a view that has a textbox to enter a user name and then two checkboxes. It will be use to add said user name to the roles marked by the checkboxes. The text box should not allow empty/null strings to be entered and if the user name already exists, warn the person.

View

@model QIEducationWebApp.Models.UserAdmin

<h1 class="page-header">Add New User</h1>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <table class="table">
        <tr>
            <th class="table-row">
                User Name:
            </th>
            <td class="table-row">
                @Html.TextBoxFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </td>
        </tr>
        <tr>
            <th class="table-row">
                Role:
            </th>
            <td class="table-row">
                @Html.DropDownListFor(model => model.UserRole,
                    @ViewBag.Roles as SelectList, " -- Select Role -- ", new { @class="form-control" })
                @Html.ValidationMessageFor(model => model.UserRole)
            </td>
        </tr>
        <tr><td class="table-row-blank"></td></tr>
        <tr>
            <td class="table-row-button">
                <input class="button" type="submit" value="Create" />
                <input type="button" class="button" value="Cancel" 
                    onclick="location.href='@Url.Action("AllUsers")'" />
            </td>
        </tr>
    </table>
}

Model

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[Required(ErrorMessage = "Required")]
[Remote("ExistUser", "Admin", HttpMethod = "POST",
    ErrorMessage = "User is assinged, Edit instead")]
[DataMemberAttribute()]
public global::System.String UserName
{
    get
    {
        return _UserName;
    }
    set
    {
        OnUserNameChanging(value);
        ReportPropertyChanging("UserName");
        _UserName = StructuralObject.SetValidValue(value, false);
        ReportPropertyChanged("UserName");
        OnUserNameChanged();
    }
}
private global::System.String _UserName;
partial void OnUserNameChanging(global::System.String value);
partial void OnUserNameChanged();

Controller validation method

[HttpPost]
public JsonResult ExistUser(String UserName)
{
    bool exist = db.UserAdmins.Any(u => u.UserName == UserName);

    return Json(!exist);
}

Controller post method

[Authorize(Roles = "Director")]
[HttpPost]
public ActionResult AddNewUser(UserAdmin user)
{
    if (ModelState.IsValid)
    {
        db.UserAdmins.AddObject(user);
        db.SaveChanges();
        return RedirectToAction("AllUsers");
    }
    ViewBag.Roles = new SelectList(db.UserRoles, "UserRoleID", "UserRole1", user.UserRole);
    return View(user);
}

Currently it allows empty strings to be passed in on submit instead of showing the error. And my custom validation isn't even firing off and my debug is getting hit.

I have used this in other parts of the application and those still work.

P.S. If you guys need more code, just let me know and I'll get it up.

EDIT:: Completely different code than the original post.

Volkan Paksoy pointed out my missing ModelState.IsValid and view return.

And for the client side validation i was missing my

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Upvotes: 1

Views: 7199

Answers (2)

Colorado Matt
Colorado Matt

Reputation: 349

Maybe you do not have client side validation enabled, in which case it will do the post even if the fields are not correct. Also, in your post controller method you aren't checking validity of ModelState, which may be invalid, meaning there's a validation issue you aren't trapping for. Add this to your controller method:

if (ModelState.IsValid) { do work };

And make sure you have these lines in web.config to enable client side (JavaScript) validation, in which case the post won't happen until the field values are valid:

<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

Upvotes: 1

Volkan Paksoy
Volkan Paksoy

Reputation: 6977

First off, as @Chris Bohatka suggested, you have to use your model as the parameter (User class in this case)

Then you have to check the status of the ModelState like this:

if (!ModelState.IsValid)
{
    // There is an error on the page, load the same view to display the errors
}

// Model is fine, carry on with the other stuff...

I debugged and saw the "Must enter a User Name" in ModelState errors collection so what you have to do is return to the same view so that user can see the error and fix it.

Upvotes: 1

Related Questions