Reputation: 149
Background: I am extremely new to MVC, c#, and .net in general. I am working from the MVC4 internet application template in visual studio 2012.
I want to display model binding errors using bootstrap's alert classes rather than the unordered list produced by Html.ValidationSummary(). This is the hacked together mess that I came up with:
StringWriter writer = new StringWriter();
foreach (ModelState state in ViewData.ModelState.Values) {
foreach (var error in state.Errors) {
writer.Write(error.ErrorMessage);
break;
// In this case the error messages are all the same,
// so I just break out when I get to the first one.
}
}
if (writer.ToString() != "") {
<div class="alert">@writer.ToString()</div>
}
It is in the Login.cshtml view and pops up an alert style box on a failed login.
Does anyone have any better suggestions on how to display the model binding errors using custom html/css? I just threw this together based on googling and guesswork mostly, any advice would be much appreciated.
Found this similar question: Change default ValidationSummary template in MVC4
I don't know if the solution provided allows for as much flexibility though, but let me know if I'm wrong.
Upvotes: 1
Views: 1736
Reputation: 19241
You can write custom html helper to display validation errors in any way you want. Following is just an example.
public static string MyValidationSummary(this HtmlHelper helper)
{
string errorMessage = string.Empty;
if (!helper.ViewData.ModelState.IsValid)
{
errorMessage += "<div class='alert'>";
foreach (var key in helper.ViewData.ModelState.Keys)
{
foreach(var err in helper.ViewData.ModelState[key].Errors)
errorMessage += "<span>" + helper.Encode(err.ErrorMessage) + "</span> <br>";
}
errorMessage += "</div>";
}
return errorMessage;
}
Via above helper you can display your model errors with @Html.MyValidationSummary()
. Have not tested the code, there might be errors.
Upvotes: 2
Reputation: 931
Honestly, the most flexible way is to have the controller return JSON. The more you work with ASP.Net MVC the more times you will wish you has raw JSON to work with. The following is a contrived example where
The controller code is similar to:
[HttpPost]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public JsonResult Login(LoginView login)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Select(kvp => kvp.Value.Errors.Select(e => e.ErrorMessage));
return Json(new { success = "false", message = errors });
}
//Perform whatever actions you need
// return Json(response);
}
and have a function executed onSuccess similar to:
@using (Ajax.BeginForm("Login", "Home", new AjaxOptions
{
HttpMethod = "POST",
OnBegin = "loginBegin",
OnSuccess = "loginSuccess"
}))
{
//You could create this modelview elsewhere and add any properties you need
var login = new InputLoginView();
login.rememberme = true;
//form code here
}
Where loginSuccess is a Javascript function similar to:
function loginSuccess(result) {
if (result.success) {
window.location = result.returnurl;
}
else {
//whatever actions you want to take
$('#login_password').val('');
$('#login-btn').button('reset');
var msg = new alertMsg();
msg.title = 'Login Problem';
msg.body = result.message;
$('#alertError').trigger('show', msg);
}
}
Upvotes: 1