I need your help. I am working with MVC3-Razor application. I need to validate a textbox on View (.cshtml file) in such a way that, the starting 2 characters must be "PR" and 4th character must be "2". This is the requirement. How would i achieve this functionality? Any suggestions, it would be great help. Thanks for your precious time.
Model
public class RegisterModel
{
public int ID { get; set; }
[RegularExpression(#"^PR[a-zA-Z0-9]2([a-zA-Z0-9]*)$", ErrorMessage = "Please enter valid Name.")]
[Required(ErrorMessage = "Name is required.")]
public string Name { get; set; }
}
View
#using (Html.BeginForm("DYmanicControllerPage", "Test", FormMethod.Post, new { id = "FrmIndex" }))
{
<div>
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
</div>
}
Related
I am having strange issue, MVC dropdown selected value is not preselected on page Load.
My Models are:
public class DocumentTypesViewModel
{
[Required(ErrorMessage = "DocumentType is required")]
public int OHDocumentTypeId { get; set; }
public string OHDocumentTypeDescription { get; set; }
}
public class ClientAdvancedSearchViewModel
{
[Display(Name = "Name")]
public string Name { get; set; }
[Display(Name = "DocumentType")]
public string DocumentTypeId { get; set; }
public IEnumerable<SelectListItem> DocumentTypes { get; set; }
}
In My Controllers I am populating the ClientAdvancedSearchViewModel like this
[HttpGet]
public ActionResult ClientAdvancedSearch()
{
ClientAdvancedSearchViewModel clientAdvancedSearchViewModel = iClientReferralRecordsRepository.GetDocumentMetadata();
//DocumentTypes Dropdown
var ddlDocumentTypes = iDocumentTypeRepository.GetDocumentTypes();
clientAdvancedSearchViewModel.DocumentTypes = new SelectList(ddlDocumentTypes, "OHDocumentTypeId", "OHDocumentTypeDescription",clientAdvancedSearchViewModel.DocumentTypeId);
return View(clientAdvancedSearchViewModel);
}
Finally in the View:
<td>
<div class="editor-label">
#Html.LabelFor(model => model.DocumentTypes)
</div>
<div class="editor-field">
#Html.DropDownListFor(x => x.DocumentTypeId, Model.DocumentTypes, "Please Select", new { #id = "ddlDocumentType" })
</div>
</td>
I believe the Name of the dropdown is same is x => x.DocumentTypeId, becuase of this I think, my value is not preselected.
This is the ViewSource for generated HTML for the Drop Down
<select id="ddlDocumentType" name="DocumentTypeId">
<option value="">Please Select</option>
<option value="20">records</option>
<option value="21"> record1</option>
..
How can I rename my dropdownlist name or How can I solve my problem?
Thank you
Updated: Added the missed line
ClientAdvancedSearchViewModel clientAdvancedSearchViewModel = iClientReferralRecordsRepository.GetDocumentMetadata();
Your code on your view is just right. You forgot to set the value for DocumentTypeId. This is your code as you posted:
[HttpGet]
public ActionResult ClientAdvancedSearch()
{
//DocumentTypes Dropdown
var ddlDocumentTypes = iDocumentTypeRepository.GetDocumentTypes();
clientAdvancedSearchViewModel.DocumentTypes = new SelectList(ddlDocumentTypes, "OHDocumentTypeId", "OHDocumentTypeDescription",clientAdvancedSearchViewModel.DocumentTypeId);
return View(clientAdvancedSearchViewModel);
}
And you missed this:
clientAdvancedSearchViewModel.DocumentTypeId = some_value;
Also, do you intend to have DocumentTypeId as an int instead of a string?
UPDATE:
You can also check that you set the id like this:
#Html.DropDownListFor(x => x.DocumentTypeId, new SelectList(Model.DocumentTypes, "Id", "Value", Model.DocumentTypeId), new { #id = "ddlDocumentType" })
Notice I used the overload with new SelectList. I don't remember all the overloads and I do it like that all the time, so you might check our the other overloads that suits your need.
I am using ASP.NET MVC 3 TextBoxFor in a form and would like to use type="email" for easier input for at least some mobile devices but cannot find how to set it using TextBoxFor. Is this not easily possible?
In View
#Html.LabelFor(m => m.Email)
#Html.TextBoxFor(m => m.Email)
In model
[StringLength(50)]
public string Email { get; set; }
(Already using a data annotation to protect size constraint in DB)
Try to use
#Html.TextBoxFor(m => m.Email, new { #type = "email" })
http://msdn.microsoft.com/en-us/library/ee703538.aspx (htmlAttributes)
You're using it the wrong way.
Use EditorFor in View:
#Html.LabelFor(m => m.Email)
#Html.EditorFor(m => m.Email)
In model, add the [DataType( DataType.EmailAddress )] Data Annotations property:
[DataType( DataType.EmailAddress )]
public string Email { get; set; }
Try adding [DataType( DataType.EmailAddress )] to the email property.
[DataType( DataType.EmailAddress )]
[StringLength(50)]
public string Email { get; set; }
[StringLength(50)]
[DataType(DataType.EmailAddress, ErrorMessage = "Invalid Email Address")]
public string EmailAddress { get; set; }
Try to add this. I think it works.
I have a class marked as follows:
public class MyClass{
[Display(Name="First Name")]
public string FirstName{get;set;}
}
In the Razor view I am accessing it like so, where MyClass is a property on the model:
#Html.Label("MyClass.FirstName")
However the value defined in the Display attribute isn't displayed. If I write:
#Html.LabelFor(model => model.MyClass.FirstName)
This works fine, however for the solution I am working on I have to use the first method. What have I missed on the first method?
UPDATE
Thanks for looking at this question, the problem was caused by the model be altered before the partial view was called. This mean that the model being evaluated against was not the model I was expecting.
The problem is now resolved.
If you are strongly typing your view with the MyClass model try
#Html.LabelFor(model => model.FirstName)
Here is an example from one of my projects.
First the view model class
public class UsersRegisterViewModel
{
[Display(Name = "E-Mail Address")]
[Required(ErrorMessage = "E-Mail address is required")]
[Email(ErrorMessage = "Not a valid e-mail address")]
[Remote("UserNameIsAvailable", "Validation", ErrorMessage = "Username is not available")]
public string UserName { get; set; }
[Display(Name = "Password")]
[Required(ErrorMessage = "Please enter a password")]
public string Password { get; set; }
[Display(Name = "Verify Password")]
[Required(ErrorMessage = "Please confirm your password")]
[Compare("Password", ErrorMessage = "Passwords don't match")]
public string VerifyPassword { get; set; }
[Required(ErrorMessage = "Please enter a display name")]
[Remote("DisplayNameIsAvailable", "Validation", ErrorMessage = "Display name is not avalable")]
public string DisplayName { get; set; }
}
Now the View (Ignore the AJAX goo)
#model UsersRegisterViewModel
<div id="user-register" class="site-contol">
<h2>Account Registration</h2>
<p></p>
#using (Ajax.BeginForm("Register", "Users", null, new AjaxOptions
{
HttpMethod = "post",
UpdateTargetId = "user-registration",
InsertionMode = InsertionMode.Replace,
OnSuccess = "registrationCallBacks.onSuccess",
OnFailure = "registrationCallBacks.onError"
}, new {#id = "frm-sign-in"}))
{
<ul>
<li>#Html.LabelFor(m => m.UserName)</li>
<li>#Html.TextBoxFor(m => m.UserName) #Html.ValidationMessageFor(m => m.UserName)</li>
<li>#Html.LabelFor(m => m.Password)</li>
<li>#Html.PasswordFor(m => m.Password) #Html.ValidationMessageFor(m => m.Password)</li>
<li>#Html.LabelFor(m => m.VerifyPassword)</li>
<li>#Html.PasswordFor(m => m.VerifyPassword) #Html.ValidationMessageFor(m => m.VerifyPassword)</li>
<li>#Html.LabelFor(m => m.DisplayName)</li>
<li>#Html.TextBoxFor(m => m.DisplayName) #Html.ValidationMessageFor(m => m.DisplayName)</li>
<li>
<ul>
<li><input type="submit" name="sb-register" value="Create Account"/></li>
</ul>
</li>
</ul>
}
</div>
An article view model
public class ArticleViewModel : ViewModelBase
{
[Required(ErrorMessage = "Required")]
public string Title { get; set; }
[Required(ErrorMessage = "Choose the language")]
public BELocale Locale { get; set; }
}
public class BELocale : BEEntityBase
{
public string OriginalName { get; set; }
public string FriendlyName { get; set; }
public string TwoLetterISOName { get; set; }
}
A view "AddLocaleForArticle"
#model Models.ArticleViewModel
#using (Html.BeginForm("VefifyAddingLocaleForArticle", "Administration"))
{
#Html.TextBoxFor(m => m.Title, new { disabled = "disabled" })
#Html.DropDownListFor(m => m.Locale,
new SelectList(ViewBag.AvalaibleLocales, "ID", "OriginalName"), "Select a language"
)
#Html.ValidationMessageFor(m => m.Locale)
<input type="submit" value="Save" />
}
An action
public ActionResult VefifyAddingLocaleForPhoto(ArticleViewModel article)
{
//article.Locale == null for some reason.
//but article.Title isn't null, it contains the data
return RedirectToAction("AddingLocaleForPhotoSuccess", "adminka");
}
Why article.Locale is equal null and how to fix it?
When the form is submitted a dropdown list sends only the selected value to the controller. So you cannot expect it to populate an entire complex object such as BELocale using a dropdownlist. The best you could is to populate its ID property and fetch the remaining of the object from your data store using this id.
So you will have to modify your dropdownlist helper so that it is bound to the id property of the locale as first argument:
#Html.DropDownListFor(
m => m.Locale.ID,
new SelectList(ViewBag.AvalaibleLocales, "ID", "OriginalName"),
"Select a language"
)
Now inside the corresponding controller action you will get the id:
public ActionResult VefifyAddingLocaleForPhoto(ArticleViewModel article)
{
// article.Locale.ID will contain the selected locale id
// so you can use this information to fetch the corresponding BELocale object
...
}
You may fill dropdown like this in your view model
public List<KeyValuePair<int, String>> locale
{
get
{
return _localerepo.Findlocals().Select(x => new KeyValuePair<int, string>(x.ID, x.OriginalName)).ToList();
}
}
In your view use this
<%:Html.DropDownListFor(x => x.ID, new SelectList(Model.locale, "key", "value"), "--Select locale--")%>
<%= Html.ValidationMessageFor(model => model.ID)%>
This is very basic but it always returns false on the compare validation. Anyone else running in to this problem?
public class UsersRegisterUserViewModel
{
[DisplayName("E-Mail Address")]
[Required(ErrorMessage = "E-Mail Address is required")]
[RegularExpression(#"^[A-Za-z0-9_\-\.]+#(([A-Za-z0-9\-])+\.)+([A-Za-z\-])+$", ErrorMessage = "Invalid E-mail Address")]
public string RegUsername { get; set; }
[Required]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "Passwords must match")]
[DataType(DataType.Password)]
public string RegConfirmPassword { get; set; }
}
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
//element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
element = $(options.form).find(":input[name='" + fullOtherName + "']")[0];
MVC3 Compare attribute is buggy when comparing passwords independently of Account Controller. It seems it is hardcoded to only work with Account controller.
1. Cut and past email, password, confirm password from RegisterModel into a new file called ViewModels/ShortRegister.cs
2. Cut razor code ( email, password, confirm password) from register view and past it into partial view, call it "_shortRegistration".
3. Create a new controller called "ShortRegistration". Add the partial view into ShortRegistation.
5. Add related jquery scripts
Create a link on home page to ShortRegistration.
Confirmation error message always fires error message.
Remove the email from the partial view confirmation, The Compare functionality works.
Add userName to the partial view and view-model, Compare functionality fails, again password confirmation error message always displays error message.
Has this bug been fixed? I disabled Compare attribute and wrote jquery and CCS to fix this! I am more than happy to email the code to prove that Compare is buggy.
Hmm, no, I am not running into such problems. I've just tested the following code and it worked perfectly fine as expected.
Model:
public class UsersRegisterUserViewModel
{
[DisplayName("E-Mail Address")]
[Required(ErrorMessage = "E-Mail Address is required")]
[RegularExpression(#"^[A-Za-z0-9_\-\.]+#(([A-Za-z0-9\-])+\.)+([A-Za-z\-])+$", ErrorMessage = "Invalid E-mail Address")]
public string RegUsername { get; set; }
[Required]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "Passwords must match")]
[DataType(DataType.Password)]
public string RegConfirmPassword { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new UsersRegisterUserViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(UsersRegisterUserViewModel model)
{
return View(model);
}
}
View:
#model UsersRegisterUserViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.RegUsername)
#Html.EditorFor(x => x.RegUsername)
#Html.ValidationMessageFor(x => x.RegUsername)
</div>
<div>
#Html.LabelFor(x => x.Password)
#Html.EditorFor(x => x.Password)
#Html.ValidationMessageFor(x => x.Password)
</div>
<div>
#Html.LabelFor(x => x.RegConfirmPassword)
#Html.EditorFor(x => x.RegConfirmPassword)
#Html.ValidationMessageFor(x => x.RegConfirmPassword)
</div>
<input type="submit" value="OK" />
}
So now the question becomes: how is your code different than mine?