Remote Validation seems buggy - asp.net-mvc

imagine this situation:
SetUp
in the default MVC3 project, create a new complex type in the AccountModels.cs
public class GlobalAccount
{
public GlobalAccount()
{
this.LogOn = new LogOnModel();
this.Register = new RegisterModel();
}
public LogOnModel LogOn { get; set; }
public RegisterModel Register { get; set; }
}
In the RegisterModel change the UserName to:
[Required]
[Remote("UserNameExists", "Validation", "", ErrorMessage = "Username is already taken.")]
[RegularExpression(#"(\S)+", ErrorMessage = "White space is not allowed.")]
[Display(Name = "Username (spaces will be stripped, must be at least 6 characters long)")]
public string UserName { get; set; }
The UserNameExists method in a Validation controller is as follow:
public class ValidationController : Controller
{
public JsonResult UserNameExists(string UserName)
{
string user = null;
if (!String.IsNullOrWhiteSpace(UserName) && UserName.Length >= 6)
user = UserName == "abcdef" ? "ok" : null;
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", UserName), JsonRequestBehavior.AllowGet);
}
}
Now in the Register View, use the GlobalAccount Model instead of the RegisterModel
the username input box will be like:
#model Your.NameSpace.Models.GlobalAccount
and
<div class="field fade-label">
#Html.LabelFor(model => model.Register.UserName, new { #class = "text" })
#Html.TextBoxFor(model => model.Register.UserName, new { spellcheck = "false", size = "30" })
</div>
this will result in something like this, in the HTML
<div class="field fade-label">
<label class="text" for="Register_UserName"><span>Username (spaces will be stripped, must be at least 6 characters long)</span></label>
<input data-val="true" data-val-regex="White space is not allowed." data-val-regex-pattern="(\S)+" data-val-remote="Username is already taken." data-val-remote-additionalfields="*.UserName" data-val-remote-url="/beta/Validation/UserNameExists" data-val-required="The Username (spaces will be stripped, must be at least 6 characters long) field is required." id="Register_UserName" name="Register.UserName" size="30" spellcheck="false" type="text" value="">
</div>
Debug
If you use FireBug to check what's going on ... the Remote Validation is sending the attribute name instead of the attribute id to the Validation method (the UserNameExists one) as:
Register.UserName instead of Register_UserName
So I can't fetch this value ... ever :(
Is this really a bug or is something that someone already found and I couldn't get from Googling it?
Here is a simple image of the actual problem:

How about:
public ActionResult UserNameExists(
[Bind(Include = "UserName")]RegisterModel register
)
{
string user = null;
if (!String.IsNullOrWhiteSpace(register.UserName) && register.UserName.Length >= 6)
user = register.UserName == "abcdef" ? "ok" : null;
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}
Another possibility is to define a special view model:
public class UserNameExistsViewModel
{
public string UserName { get; set; }
}
and then:
public ActionResult UserNameExists(UserNameExistsViewModel register)
{
string user = null;
if (!String.IsNullOrWhiteSpace(register.UserName) && register.UserName.Length >= 6)
user = register.UserName == "abcdef" ? "ok" : null;
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}
What is annoying is that the following doesn't work:
public ActionResult UserNameExists(
[Bind(Prefix = "Register")]string UserName
)
Go figure :-) I would probably go with a custom view model. It looks cleanest.

I know this is marked as answered, but as I'm having the same issue I thought I would contribute another variation that is working for me.
The class in my case is "Food" and the field I'm attempting to remote validate is "Name". The textbox is being created by an EditorFor control:
#Html.EditorFor(model => model.Name)
Remote validation is set on the Food class field:
[Remote("FoodNameExists")]
public string Name { get; set; }
And this calls a method:
public ActionResult FoodNameExists(string Name) {
As per the original question, rather than this being passed to the FoodNameExists method as "Name", or even "Food_Name", which is the Id value created by the EditorFor helper, it is getting passed as the name attribute which is "Food.Name"... which of course is not something I can set as an input parameter.
So, my hack is simply to ignore the input parameters and look in the QueryString:
var name = Request.QueryString["Food.Name"];
...this returns the correct value, which I validate against and I'm off to the races.

This is the simpliest way I found to do it, just adding data-val-- attributes in HtmlAttributes of DropDownListFor, inside the view. The following method works with RemoteValidation too, if you do not need remote validation, simply remove the elements containing data-val-remote-*:
#Html.DropDownListFor(m => m.yourlistID, (IEnumerable<SelectListItem>)ViewBag.YourListID, String.Empty,
new Dictionary<string, object>() { { "data-val", "true" },
{ "data-val-remote-url", "/Validation/yourremoteval" },
{ "data-val-remote-type", "POST" }, { "data-val-remote-additionalfield", "youradditionalfieldtovalidate" } })
I hope it may help. Best Regards!

Related

Is there a way to clear modelstate errors on the client?

I have a model with a list of child objects. I have created a custom validation attribute, implemented IValidatableObject on the model and i get an error message as expected. The problem is that once the property has an error in the modelstate, i can't get the updated value to post back to the server. They get cleared out some time between hitting the submit button and receiving the model in the controller.
if i call ModelState.Clear() in the controller action, i don't get any messages but the new values post as expected. The model is however picking up on the custom attribute because ModelState.IsValid == false
I'm thinking the best way to handle this is to call ModelState.Clear() on the client somehow after $(ready) so i get the validation messages but can also have the changed values post to the server. Is this possible or is there a better way to do this?
Parent Model
public class PayrollPlanModel : IMapFrom<Data.PayrollPlan>
{
public int? PayrollPlanId { get; set; }
[Required]
public string Name { get; set; }
public List<PlanOptionFormModel> Options { get; set; }
}
Model List property on parent with custom attribute
public class PlanOptionFormModel : IValidatableObject
{
public int PlanOptionValueId { get; set; }
public int PayrollPlanId { get; set; }
public string PlanName { get; set; }
public int PlanOptionId { get; set; }
public string Description { get; set; }
[UIHint("_Money")]
[RequiredIf("Selected", true)]
public decimal? Value { get; set; }
public bool Selected { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Selected && !Value.HasValue)
{
yield return new ValidationResult("Add a value.");
}
}
}
Custom Attribute (Shamelessly stolen from here)
public class RequiredIfAttribute : ValidationAttribute
{
RequiredAttribute _innerAttribute = new RequiredAttribute();
public string _dependentProperty { get; set; }
public object _targetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this._dependentProperty = dependentProperty;
this._targetValue = targetValue;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var field = validationContext.ObjectType.GetProperty(_dependentProperty);
if (field != null)
{
var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
if ((dependentValue == null && _targetValue == null) || (dependentValue.Equals(_targetValue)))
{
if (!_innerAttribute.IsValid(value))
{
string name = validationContext.DisplayName;
return new ValidationResult(ErrorMessage = name + " Is required.");
}
}
return ValidationResult.Success;
}
else
{
return new ValidationResult(FormatErrorMessage(_dependentProperty));
}
}
}
Page snippet
for (int i = 0; i < Model.Options.Count; i++)
{
<div class="row">
<div class="col-md-3">
#Html.HiddenFor(m => Model.Options[i].PlanOptionValueId)
#Html.HiddenFor(m => Model.Options[i].PayrollPlanId)
#Html.HiddenFor(m => Model.Options[i].PlanOptionId)
#Html.HiddenFor(m => Model.Options[i].Description)
</div>
<div class="col-md-1 text-right">
#Html.CheckBoxFor(m => Model.Options[i].Selected, new { #data_textbox = "optionValue_" + i.ToString(), #class = "form-control modelOptionSelector" })
</div>
<div class="col-md-2 text-right">
<h4>#Model.Options[i].Description</h4>
</div>
<div class="col-md-1">
#Html.EditorFor(m => Model.Options[i].Value, Model.Options[i].Selected ? new { HtmlAttributes = new { id = "optionValue_" + i.ToString(), #class = "planOptionValueEditor" } } : (object)new { HtmlAttributes = new { disabled = "disabled", id = "optionValue_" + i.ToString(), #class = "planOptionValueEditor" } })
#Html.ValidationMessageFor(m => Model.Options[i].Value)
</div>
</div>
}
<br />
Editor Template
#model decimal?
#{
var defaultHtmlAttributesObject = new { };
var htmlAttributesObject = ViewData["htmlAttributes"] ?? new { };
var htmlAttributes = Html.MergeHtmlAttributes(htmlAttributesObject, defaultHtmlAttributesObject);
string attemptedValue = "";
ModelState modelStateForValue = Html.ViewData.ModelState[Html.IdForModel().ToString()];
if (modelStateForValue != null)
{
attemptedValue = modelStateForValue.Value.AttemptedValue;
}
}
#(Html.Kendo().CurrencyTextBoxFor(m => m)
.HtmlAttributes(htmlAttributes)
.Format("c")
.Spinners(false)
)
Controller
[HttpPost]
public ActionResult EditPlan(PayrollPlanModel model)
{
if(ModelState.IsValid)
{
}
else
{
}
return View(model);
}
It makes no sense to attempt to attempt to clear ModelState errors from the client. ModelState is only set within the controller method (by the DefaultModelBinder) when you make a request to the method. In any case, your issues are not related to ModelState being valid or invalid in the controller method.
There are a number of changes you need to make to your code:
You should delete your EditorTemplate for decimal? It means that any property of that type is going to use that template. Instead replace your
#Html.EditorFor(m => Model.Options[i].Value, ...)
with
#(Html.Kendo().CurrencyTextBoxFor(m => m.Options[i].Value)....
in the main view.
If you really do want to use a template, then make it a named template (which is called using #Html.EditorFor(m => Model.Options[i].Value, "yourTemplateName"), but in any case, you need to remove the code relating to attemptedValue and modelStateForValue (including the if block) - the EditorFor() methods will always correctly use values from ModelState if they exist.
Next, your RequiredIfAttribute does not implement IClientValidatable so you will not get client side validation. You could use the foolproof library, or if you want to write your own, refer this answer for the full implementation of a RequiredIfAttribute, including the scripts for client side validation.
Next, you need to delete the IValidatableObject implementation (the Validate() method) from your model. That is just repeating the validation that the [RequiredIf] attribute is doing, and you should avoid mixing ValidationAttribute's with IValidatableObject (refer The Complete Guide To Validation In ASP.NET MVC 3 - Part 2 for more detailed information).
Finally, the Kendo().CurrencyTextBoxFor() method hides the input and renders its own html. By default, hidden inputs are not validated, so you need to reconfigure the validator. In the main view, add the following script (after the jquery-{version}.js, jquery.validate.js and jquery.validate.unobtrusive.js scripts
<script>
$.validator.setDefaults({
ignore: []
});
.... // other scripts as required
<script>

How to set default value to empty EditorFor-field when post a form i .NET MVC

I have a form in .NET MVC 5. where the user can write a number, default is "0", If the user deletes a number e.g. "233" an leaving the field empty. The form would not submit.
How can I submit the form with an empty field?
public class myModel
{
public int nummer { get; set; }
public myModel(){}
public myModel(int i) {this.nummer = i;}
}
razor code:
using (Html.BeginForm("myAction", "myController", FormMethod.Post, new { #class = "form-inline" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text- danger" })
#Html.EditorFor(model => model.nummer, new { htmlAttributes = new { #class = "form-control " } })
<input type="submit" value="submit" name="btnSubmit"/>
}
I am not interested in a validation error message, but to have the value set to "0", by default.
The DefaultModelBinder initializes your model using the parameterless constructor (your second constructor is never called). You will need to make the property nullable to prevent client and server side validation errors
public int? nummer { get; set; }
and then in the POST method, test for null and if so, set the value to 0
if(!model.nummer.HasValue)
{
model.nummer = 0;
}
Alternatively you could write your own ModelBinder that tests for a null value and in the ModelBinder, set the value to 0
You will need to set your nummer field to be a nullable type, like so:
public class myModel
{
public int? nummer { get; set; }
...
}
This will allow a user to submit the form without a value entered.
Then within your controller action you will need to assign a default value if the field is null:
if (model.nummer == null) model.nummer = 0;
Alternatively, you could use a private property like so:
public class myModel
{
private int? privateNummer { get; set; }
public int? nummer
{
get { return this.privateNummer == null ? 0 : this.privateNummer; }
set
{
this.privateNummer = value;
}
}
}
in your controller before passing the model back to the view do this ..
model.find(id);
model.nummer =0;
return View(model)

remote validation in mvc affected edit

I was trying to validate the user name through remote validation in client side and it's working fine in while adding the duplicate field in create Module but now it is not allowing me to edit the record using same name it's showing me the same error which I defined for create. I tried all the possible ways but not succeeded please help me. I have followed these link but it's not working in either way.
http://stackoverflow.com/questions/4778151/asp-net-mvc-3-remote-validation-to-allow-original-value
http://stackoverflow.com/questions/6407096/asp-net-mvc-3-remote-attribute-passing-3-fields
here is my code what i have tried so far .please help experts.
[Required]
[Remote("IsUserAvailable", "User", HttpMethod = "Post", ErrorMessage = "User already exist.", AdditionalFields = "InitialUserName")]
[RegularExpression(#"^(?![\W_]+$)(?!\d+$)[a-zA-Z0-9 ]+$", ErrorMessage = "Invalid UserName ")]
public string UserName { get; set; }
[HttpPost]
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, string initialUserName)
{
var result = uDbContext.Users.FirstOrDefault(a => a.UserName == UserName);
if (result == null)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json(JsonRequestBehavior.AllowGet);
}
#model User.ViewModel.ViewModelUser
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(m => m.User.UserId)
#Html.LabelFor(m.User.UserName)
#Html.TextBoxFor(m => m.User.UserName)
#Html.ValidationMessageFor(m.User.UserName)
#Html.Hidden("initialUserName", Model.User)
</div>
</div>
}
Please help experts to complete my assignment.
User appears to be a complex object so
#Html.Hidden("initialUserName", Model.User)
is likely to generate something like
<input type="hidden" name="initialUserName" value="YourAssemly.User" ... />
which is not going to help with validation.
You could ignore the validation by sending back the original name using
#Html.Hidden("InitialUserName", Model.User.UserName)
#Html.Hidden("User.InitialUserName", Model.User.UserName)
and then compare the values in the controller using
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, string initialUserName)
public JsonResult IsUserAvailable([Bind(Prefix = "User.UserName")]string UserName, [Bind(Prefix = "User.InitialUserName")]string initialUserName)
{
if (UserName == initialUserName)
{
// Nothing has changed so signal its valid
return Json(true, JsonRequestBehavior.AllowGet);
}
// Check if the user name already exists
var result = uDbContext.Users.FirstOrDefault(a => a.UserName == UserName);
return Json(result == null, JsonRequestBehavior.AllowGet);
}
Side note: jquery remote validation is a GET call so the [HttpPost] attribute is not necessary
Edit
After debugging both the jquery-validate.js and jquery-validate-unobtrusive.js files, it turns out that the name attribute of any AdditionalFields must include the same prefix as the property being validated, and that the [Bind(Prefix="..")] attribute is then also required on those parameters in the method (refer amendments above)
An alternative might to create a simple class to post back to, for example
public class ValidateUserNameVM
{
public string UserName { get; set; }
public string InitialUserName { get; set; }
}
and
public JsonResult IsUserAvailable([Bind(Prefix = "User")]ValidateUserNameVM model)
{
if (model.UserName == model.InitialUserName)
....
Your validation function is incomplete. Put a [Required] attribute on the UserName property of your model and try this:
public JsonResult IsUserAvailable(string userName, string initialUserName)
{
if (userName.Trim().ToLower() != (initialUserName ?? "").Trim().ToLower())
{
var result = YourMethodToCheckTheDatabaseForUsernameIsAvailable(userName);
return Json(result, JsonRequestBehavior.AllowGet);
}
return Json(true, JsonRequestBehavior.AllowGet);
}
For Who Get Null in the second paramter this simple idea could help
public JsonResult IsUserNameAvailable(string Name, string EditNameIssue)
{//it will return true if match found elese it will return false. so i add !
if (Name == EditNameIssue)
{
return Json(true, JsonRequestBehavior.AllowGet);
}
else
{
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
}
Go to The Class and add string EditNameIssue to the class so it could be sent to the controller
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
public string EditNameIssue { get; set; }
}
And Edit the Remote attribute to send this addtional property
[Remote("IsUserNameAvailable","Employees",ErrorMessage ="User Name Already Taken",AdditionalFields = "EditNameIssue")]
public string Name { get; set; }
This Logic may help if you add a name to edit textbox that is already taken
public JsonResult IsUserNameAvailable(string Name, string EditNameIssue)
{//it will return true if match found elese it will return false. so i add !
//Edit Request
if (Name == EditNameIssue)
{
//this mean he didn't change the name
return Json(true, JsonRequestBehavior.AllowGet);
}
else if (Name != EditNameIssue)
{
//if he change the name in the edit go and check if the new name exist
//note if he modify and reenter it origin name it will be also erro he has to reload
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
else if (string.IsNullOrEmpty(EditNameIssue))
{//this mean you came from create request as there is no EditNameIssue in this view
return Json(!db.Employees.Any(e => e.Name == Name), JsonRequestBehavior.AllowGet);
}
else
{//just for the completeness
return Json(false, JsonRequestBehavior.AllowGet);
}
}

Custom validation error not displayed

I have an MVC 3 application and am trying to display a custom validation error. The normal validation errors that are generated by the model, i.e. Required, are displayed on the page. Now I am checking if a user exists and if so, adding a error message:
if (userExists)
ModelState.AddModelError("UserName", UserManagementResources.UserAlreadyExistsText);
return View(model);
On the view I have a validation summary and a Html.ValidationMessage("UserName"), but neither one is displaying the error. I have used this successfully on other pages. The only difference with this page I can see is, that it uses the RequiredIf validator scripts.
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx
Any ideas how to solve this problem are appreciated. Thanks.
Edit
I am returning the validation message through the Remote validation. If I look what the network is doing, it's returning the error message, but it is still not displayed on the view.
[Required]
[DataType(DataType.EmailAddress)]
[Remote("IsUserAvailable", "Validation", ErrorMessage = "Ein Benutzer mit dieser Email existiert bereits.")]
[Display(Name = Resources.EmailText, ResourceType = typeof(Resources))]
public string Email
{
get { return User.Email; }
set { User.Email = value; }
}
The View:
#Html.LabelFor(u => u.Email, Resources.Email + " (Login) *")
#Html.EditorFor(u => u.Email)
#Html.ValidationMessageFor(u => u.Email)
<br clear="all" />
The Remote Validation Controller:
public class ValidationController : Controller
{
public JsonResult IsUserAvailable(string Email)
{
bool userExists;
using (var userModel = new UserManagementModel())
{
userExists = userModel.UserExists(Email);
}
if(userExists)
return Json(UserManagementResources.UserAlreadyExists, JsonRequestBehavior.AllowGet);
else
return Json(true, JsonRequestBehavior.AllowGet);
}
}
Why don't you use the Remote validation for this?
Why posting back just to check if user exists?
example:
public class RegisterModel
{
[Required]
[Remote("UserNameExists", "Validation", "", ErrorMessage = "Username is already taken.")]
[RegularExpression(#"(\S)+", ErrorMessage = "White space is not allowed.")]
[Display(Name = "Username")]
public string UserName { get; set; }
}
and create a Validation Controller having the UserNameExists method like
public JsonResult UserNameExists(string UserName)
{
var user = _db.Users.Where(x => x.username.Equals(UserName));
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}
When you change the version of your jQuery.js you have to change the validation.js file as well. Different versions are not compatible to each other and you might see strange behaviour in different browsers when you mixup the files.

How to clear textboxes defined with MVC HTML helpers

I can't figure out how to do this very simple thing: My page contains a set of textboxes that a user can fill out to add an item to a list. Then the item shows up in a dropdown list.
At that point, I want the "add" textboxes to be cleared. This is the behavior expected by most users, I think. The item has been added; now the textboxes should be empty, ready for the next item to be entered.
However, I can't seem to clear them when I am using Html helpers, e.g., Html.Textbox(...). I like these controls because of the way they "remember" the input in case of input error. However, unlike webforms controls, you can't set them programmatically. They continue to retain the values until the user enters something else.
Is there any way around this behavior? I thought of clearing them in javascript, but I don't want to do that if there are any errors.
UPDATE some of the code;
One of my textboxes in the view:
<h6 style="margin-top: 0px">Add custom email template:</h6>
<div style="margin-top: 10px">
<div class="label">Name:</div>
<%= Html.TextBox("addName", "", new { #class="formtext", style="width: 400px" }) %>
<div class="alerttext"><%= Html.ValidationMessage("addName") %></div>
</div>
The class I am using for model binding:
public class ManageEmailTemplatesSubmittedData
{
[RegularExpression(RegExpressions.templateNameRestrict, ErrorMessage="Names should begin with a character and consist of only characters and numbers")]
public string addName { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string addDescription { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string addSubject { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string addTemplate { get; set; }
public string templates { get; set; }
[RegularExpression(RegExpressions.templateNameRestrict, ErrorMessage = "Names should begin with a character and consist of only characters and numbers")]
public string editName { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage="Invalid entry; please omit unusual characters")]
public string editDescription { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string editSubject { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string editTemplate { get; set; }
}
My action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CustomEmails(SubmitButtons buttons, ManageEmailTemplatesSubmittedData data)
{
bool saved = false;
string selectedTemplate = data.templates;
if (ModelState.IsValid)
{
ButtonStyles buttonStyles = ButtonStylesCreator.GetSelectListButtonStyles(rc.persistedData.loggedInUser.userType);
Notification notification = new Notification(rc);
if (buttons.addTemplate == buttonStyles.addEmailTemplateButtonValue)
{
// add an email template
notification.SaveCustomTemplate(data.addName, data.addName, data.addTemplate, data.addSubject, data.addDescription);
saved = true;
}
else if (buttons.saveTemplate == buttonStyles.saveTemplateValue)
{
// update an email template
notification.SaveCustomTemplate(data.templates, data.editName, data.editTemplate, data.editSubject, data.editDescription);
selectedTemplate = "";
saved = true;
}
}
ConfigureEmailsModelBuilder builder = new ConfigureEmailsModelBuilder(rc, rc.persistedData.loggedInUser.userID, selectedTemplate, true, saved);
return View(builder.Build());
}
ConfigureEmailsModelBuilder constructs the view model, which includes a SelectList that is the dropdown list of the items that have been added. (The view is strongly typed to the type generated by builder.Build).
The HTMLHelper's first look at the ModelState and ViewData to see if any values match their key and then finally use whatever value you provide them.
If you need to reset the textboxe's value you also need to clear the ModelState entry with the matching key. Another alternative is redirecting to the same page instead of simply rendering a view via javascript or with MVC.
This is working for me on an MVC3 site log on page.
ModelState.Clear();
model.UserName = string.Empty;
model.Password = string.Empty;
ModelState.AddModelError("", "The user name or password provided is incorrect.");
This will clear the login textboxes used for password and username, and keep any model errors.

Resources