简体   繁体   中英

MVC unobtrusive validation queries

I'm using unobtrusive validation in MVC for a search application, and on the whole it works well, except for 2 things that I can't find any answers for. I've used it before, and I don't remember these being an issue, so it could just be my setup in this application.

The first issue is that it immediately tells me that the search query input is invalid, or at least shows the error message for it, despite it being valid to begin with. It has some text added to it via the model, so it has a value when the page loads, therefore I can't understand why the unobtrusive validation fails it and shows the error message it when it loads.

The second issue is that it doesn't see a whitespace (" ") string as an error despite being 'required' and having 'AllowEmptyStrings' set to false, along with a 'ConvertEmptyStringToNull' DisplayFormat. I thought this would catch the whitespace, but it isn't doing.

I've overcome both these issues, the first by calling the validation manually in Document.Ready, which proves that the input is indeed valid. And the second by adding a manual check before the form is submitted. Both of these are convoluted, especially the first issue, I'd like to know why it doesn't work as expected, and avoid this issue in the future

The relevant parts of the code are below:

The SearchVM view model with the searchTerm property and the annotations.

public class SearchVM : PageDetails
{               
    public string SpellingSuggestion { get; set; }
    public List<Result> SearchResults { get; set; }
    public int ResultsCount { get; set; }

    private string searchTerm = "";
    [Display(Name = "Search the website")]
    [Required(ErrorMessage = "Please enter a search term", AllowEmptyStrings = false)]
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string SearchTerm { get
        {
            return searchTerm;
        }
        set {
            //Strip out bad characters from the search term
            if (value != null) { 
                searchTerm = Regex.Replace(value, @"[‘’#!@\$%]", "");
            } else
            {
                searchTerm = "";
            }
        }
    }
}

The Index view where the query is displayed:

@model SearchVM
@{
    Model.Title = "Search the website";
    Model.Description = "Search the website.";
    Model.Keywords = ", website, search, google, find, websearch";
    Model.Class = "search";
}
<main class="search">
    @using (Ajax.BeginForm("Results", new AjaxOptions { UpdateTargetId = "results", OnComplete= "moreInfoDropDown(), spellingSuggestion()" }))
    {
        @Html.LabelFor(m => m.SearchTerm)
        <div>
            @Html.TextBoxFor(m => m.SearchTerm, new { maxlength = 30, autocomplete = "off" })
        </div>
        <input type="image" src="~/Images/search/icon.png" alt="Search" tabindex="3" />
        @Html.ValidationMessageFor(m => m.SearchTerm)
    } 
    <div id="results">
        @if (Model.SearchResults != null)
        {
            @Html.Partial("_ResultsIntro", Model)
        }
    </div>
</main>

And the controller that calls the view (in this scenario, the query is null, so it always calls the Index with the searchTerm set to "Search the website"):

// GET: Search
public ActionResult Index(SearchVM searchVM, string query)
{
    // If there is a query added to the URL, use it
    if (!string.IsNullOrWhiteSpace(query)) {
        searchVM.SearchTerm = query;
    }
    // Re-load the typical index with no results if the search term is empty
    if (string.IsNullOrWhiteSpace(searchVM.SearchTerm))
        {    return View(new SearchVM() { SearchTerm = "Search the website" });
    }
    // Return the index with the queried result (if applicable)
    return View(GSA.Query(searchVM.SearchTerm, 0));
}

Thank you in advance for any help you can give. I don't think any other parts of the code are relevant, but please let me know if you need to see more, and I will add it to the question.

As Stephen Muecke said in his comment, I was incorrectly passing the searchVM model to the controller, and therefore it was already invalid before being passed to the view. Removing that parameter, and instead initialising a new instance of the model solved the issue.

Thanks to Stephen for pointing this out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM