I am new to asp.net and I have a problem. When the users insert in a editor for a decimal field something other than numbers, they get an error "Field name" is not a number. But I don't want them to receive this message I want them to receive another message. I have no problem with this with required and range validators.
Is there any way for me to do this?
I am not refering necessarily to changing the culture just displaying another message.
Thanks.
Hope I understand your, to change RangeValidator ErrorMessage just initialize ErrorMessage parameter:
[Range(0, 100, ErrorMessage = "Some another error message insert here!")]
[RegularExpression("\d", ErrorMessage = "!!!")]
public decimal DecimalField { get; set; }
This is the actual answer:
Create a class CustomClientDataTypeModelValidatorProvider. Copy the code from the MVC sources. Change the method MakeErrorString to output the appropiate message like this:
private static string MakeErrorString(string displayName)
{
return string.Format(
CultureInfo.CurrentCulture,
Core.Resources.Errors.EroareNuENr,
displayName);
}
I couldn't find a way not to copy the code just extend it as it uses this static method.
If anyone knows this please tell me.
Then, in global.asax, I wrote this:
var cdProvider = ModelValidatorProviders.Providers.SingleOrDefault(p => p.GetType().Equals(typeof(ClientDataTypeModelValidatorProvider)));
if(cdProvider != null)
{
ModelValidatorProviders.Providers.Remove(cdProvider);
ModelValidatorProviders.Providers.Add(
new CustomClientDataTypeModelValidatorProvider());
}
so that the flow would actually be routed to my class and not the class in the asp.net MVC dll
I got the idea from here:
Unfortunately this is is not a trivial task. However you can try the following hack...
Better to do this only on essential fields, as this is more code to maintain.
In the controller's action method
if(ModelState.IsValid)
{
// code
}
else
{
if (ModelState["YourField"].Errors.Count > 0)
{
ModelState["YourField"].Errors.Clear();
ModelState.AddModelError("YourField", "Your custom message here");
}
// code
}
You can set ResourceClassKey of ClientDataTypeModelValidatorProvider class to name of a global resource that contains FieldMustBeNumeric key to replace mvc validation error message of number with your custom message. Also key of date validation error message is FieldMustBeDate.
ClientDataTypeModelValidatorProvider.ResourceClassKey="MyResources"; // MyResource is my global resource
See here for more details on how to add the MyResources.resx file to your project:
The field must be a number. How to change this message to another language?
To change the error message you get after server side validation you need to change 'PropertyValueInvalid' key in your resource file and assign the resource file name to DefaultModelBinder.ResourceClassKey. See this question for details: localize default model validation in mvc 2
Look for solution at the end of this page:
http://jwwishart.wordpress.com/2010/03/22/custom-server-and-client-side-required-validator-in-mvc-2-using-jquery-validate/
I checked this in my MVC 3 RTM project and it works well.
... or use jQuery to change to message on the client.
A quick and simple hack for Customize RangeValidator ErrorMessage --"'Field name' is not a number"-- is using RegularExpression
[Range(0.5, 1000, ErrorMessage = "Amount should be in range {1} to {2}.")]
[DataType(DataType.Currency)]
[RegularExpression(#"\d", ErrorMessage = "Amount is not valid.")]
public decimal Amount{ get; set; }
You could implement your own custom validation attribute: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
It seems that since Para's answer MVC evolved and now the ClientDataTypeModelValidatorProvider accepts a ResourceClassKey property. It uses the FieldMustBeNumeric and FieldMustBeNumeric messages specified in your resource class.
Related
I use MVC5. I've got some issue with file uploading using HttpPostedFileBase. I've got a form where I can can choose a file from my disk and type some information about it(in textbox). When I submit a form the controller action is called. In this action I open file and check if it has some specific data(related with data from textbox). So I do some validation here. I can't do it using JQuery - it's complex. The server side validation is the only option. Finally if validation fails I return model(with file) to the view but after that I've got validation error next to file field but file field is empty. I've read that's hard to return file to the view. I don't want to use ajax to upload file. I want to do it simple. If you got an article that can help, please share it with me.
How can I solve my problem?
I know you mentioned not using AJAX to do file upload, but I think this solution is a very simple one.
Using the following jQuery plugin (https://blueimp.github.io/jQuery-File-Upload/), you can automate that process and if there are any validation issues in your file, then you can return the following model with the error.
string errors = "Errors returned from complex logic";
if (!String.IsNullOrEmpty(errors))
{
// error response
status = new ViewDataUploadFilesResult()
{
name = Path.GetFileName(hpf.FileName),
size = hpf.ContentLength,
error = errors
};
}
Here is the class needed for the response that matches the jQuery file upload documentation: https://github.com/blueimp/jQuery-File-Upload/wiki/Setup
public class ViewDataUploadFilesResult
{
public string name { get; set; }
public int size { get; set; }
public string type { get; set; }
public string url { get; set; }
public string error { get; set; }
}
If I'm understanding correctly, since the file is already on the users computer, you only need to associate the file to the current file they're attempting to upload to returns errors. And to make it so they don't have to reselect the file to upload. I don't see any other reason to need to return the actual file to the user as they already have the file they're uploading.
Hi I have just started Vaadin 7 and have got the BeanValidator working. But, I have some issues. The code I am using is the following:
BeanItem<RegisterBean> item = new BeanItem<RegisterBean>(new RegisterBean());
final FieldGroup binder = new FieldGroup(item);
final TextField email = new TextField("email");
email.addValidator(new BeanValidator(RegisterBean.class, "email"));
The validates fine using the BeanValidator. With the #NotNull tag I am able to validate for Null values as well. However, I would like to give the user visual clues that the field in the form can't be left blank. For this, I used:
email.setRequired(true);
However, after adding the setRequired the BeanValidation for the form no longer works?
Is this a limitation?
How do I get around it?
You should probably rely on the bean validation itself and use the fieldgroup.
My model looks as follows:
#NotNull(message="Please enter a valid email address.")
#Email(message="Please enter a valid email address.")
#Size(min = 3, max = 255, message="Please enter a valid email address.")
#Column(name="P_EMAIL", nullable=true, length=255)
private String email;
In your view do either buildAndBind
Field<?> email = binder.buildAndBind("email");
Or use the annotation #PropertyId("email") in your field declaration. The rest is magic.
Instead of FieldGroupuse BeanFieldGroup.
A problem will be that validation is made preliminary. So install the validators on click. More to that topic can be found here: http://morevaadin.com/content/bean-validation-and-vaadin-comprehensive-example/
To complete the example above, using a BeanFieldGroup, as it got validators, you can use the setValidationVisible method of an AbstractField to turn off preliminary validation, then to turn on in a blurListener and in the buttons clickListeners.
AbstractTextField cName = binder.buildAndBind("Name","name", AbstractTextField.class);
cName.setNullRepresentation("");
cName.setValidationVisible(false);
cName.addBlurListener(new MyBlurListener(cName)); //<-- turn on setValidationVisible there
myButton.addClickListener(event -> {
try {
cName.setValidationVisible(true);
binder.commit();
} catch (CommitException e){
Notification.show("Sending error");
}
});
The error I get when I try to send an email is:
NoViewsFoundException
You must provide a view for this email. Views should be named
~/Views/Email/VerificationEmail.html.vbhtml.txt.cshtml or
~/Views/Email/VerificationEmail.html.vbhtml.html.cshtml (or aspx for
WebFormsViewEngine) depending on the format you wish to render.
Error on line:
Return Email("~/Views/Email/VerificationEmail.html.vbhtml", model)
Can emails not be sent in .vbhtml, must they be sent in .cshtml? How can this work for VB?
Here is my code controller:
Imports ActionMailer.Net.Mvc
Public Class EmailController
Inherits MailerBase
Public Function VerificationEmail(ByVal model As RegisterModel) As EmailResult
[To].Add(model.Email)
From = "me#my.org"
Subject = "Thanks for registering with us!"
Return Email("~/Views/Email/VerificationEmail.html.vbhtml", model)
End Function
End Class
Here is my view:
#modelType MyBlog.RegisterModel
#Code
Layout = Nothing
End code
Welcome to My Cool Site, #Model.UserName
We need you to verify your email. Click this nifty link to get verified!
#Html.ActionLink("Verify", "Account", New With {.code = Model.Email})
Thanks!
After reading a couple of issues and answer, it could get it to work with this:
public override string ViewPath {
get { return AppDomain.CurrentDomain.BaseDirectory + #"\EmailTemplates\"; }
}
Of course you can have vbhtml email templates you just need to be careful with the naming (the .cshtmls exception message are hardcoded so don't be confused on it)
Your view is named correctly as VerificationEmail.html.vbhtml you just need remove all the prefixes from the view name in the Email call:
Return Email("VerificationEmail", model)
Because ActionMailer will be automatically add the prefixes and select the correct template for you.
Note that currently you cannot use relative viewnames like which start with ~ e.g. "~/Views/..." (I don't know wether this is a bug or feature).
So you need put your mail template to the regular view folders e.g.
/Views/{MailControllerName}/
/View/Shared/
Had the same issue as Chad Richardson. To solve the issue which happens when trying to send email from other area just add this code to Application_Start method:
var razorEngine = ViewEngines.Engines.OfType<RazorViewEngine>().First();
razorEngine.ViewLocationFormats = razorEngine.ViewLocationFormats.Concat(new string[]
{
"~/Areas/.../{0}.cshtml"
}).ToArray();
In my ASP.NET MVC application, I have a form and I'm using a ViewModel, so the ModelBinder can bind to my Strongly Typed Class. I'm using DataAnnotations for validation
public class FormViewModel
{
[Required]
public string SomeValue {get;set;}
[Range(0, 10, ErrorMessage="Enter a number between 0 and 10.")]
public byte? SomeOtherValue {get;set;}
}
This works great. The problem however is when the user doesn't enter a valid value for the SomeOtherValue (like abc), a standard MVC-error pops up: 'The value 'abc' is not valid for 'SomeOtherValue'. This is really annoying, as I can't customize this message. I know there are ways to Localize this message, but that just doesn't make sense (I don't want a general message, I want a value-specific value).
I tried applying a RegularExpression-attribute to the 'SomeOtherValue', which only allows byte-values, but probably the standard-validation 'overrides' this validation. Is there some way to apply a custom 'the value is not valid' message for a property, or otherwise disable the standard-message?
Here is a different (non-ideal way, IMHO) to fix it if the custom validation attribute is not working for you. In the controller:
if (!ModelState.IsValid)
{
string fieldName = "ThatFieldName";
var m = ViewData.ModelState[fieldName];
if (m != null && m.Errors.Count > 0)
{
ViewData.ModelState.Remove(fieldName);
ViewData.ModelState.AddModelError(fieldName, "You mucked that field up.");
}
}
I have a page written using .NET MVC. In the model for a Person called PersonModel I have this defined which requires the user to enter some text in the last name field:
<DisplayName("Last Name"), Required()> _
Public Property LastName() As String
Get
Return _LastName
End Get
Set(ByVal value As String)
_LastName = value
End Set
End Property
On the form, there is a checkbox that a user can check to do some other things. Is there a way, using JQuery preferablly, to change that Last Name field to be non-Required? If not using JQuery I am open to other suggestions but since I am doing alot of things when this check box is checked anyways, I was hoping I could add this logic in there. Here is some sample of what I am doing when this box is checked to demonstrate...
function doOwnerBusiness(event) {
if ($(this).is(':checked')) {
$('input[name="People_1__LastName"], label[for="People[1]_LastName"]').hide();
$("#People_1__LastName").hide();
$("#People_1__LastName").val("");
$("#People_1__LastName :input").attr('disabled', true);
$('input[name="People[1]_Suffix"], label[for="People[1]_Suffix"]').hide();
$("#People_1__Suffix").attr('disabled', true);
$('#People_1__Suffix')[0].selectedIndex = 0;
$('#People_1__Suffix').hide();
}
else {
$('input[name="People_1__LastName"], label[for="People[1]_LastName"]').show();
$("#People_1__LastName").show();
$('#People_1__LastName :input').attr('disabled', false);
}
}
Any help with this would be appreciated folks.
Thank you
William
Here is how I am declaring my checkbox and also part of the function where I am trying to check if it is checked or not...
<%=Html.CheckBoxFor(Function(model) model.FirstNameAsBusiness)%>
<%=Html.LabelFor(Function(model) model.FirstNameAsBusiness)%>
Function Nominate(ByVal m As NominationModel, ByVal captchaValid As Boolean) As ActionResult
If Not m.FirstNameAsBusiness.checked AndAlso String.IsNullOrEmpty(m.lastnametext) Then
ModelState.AddModelError("LastName", "Last Name field is required if you don't yada yada...")
Return View()
End If
Short answer: no. You can't bypass the DataAnnotation with a jQuery call.
Technically, the Last Name field isn't required. So, I'd remove the DataAnnotation for Required, and then on the backend, when the user submits the form, verify that a field value exists when the checkbox isn't checked. If the conditional doesn't pass, and an error to ModelState for that field, and redirect to the page. (apologies for the c#):
public ActionResult Index(HomeIndexModel form)
{
if (!form.Checked && string.IsNullOrEmpty(form.LastName))
{
ModelState.AddModelError("LastName", "Last Name field is required if you don't yada yada...");
return View();
}
//conditional requirement passed...
}
If you want to get a little fancier, you can check out this thread, though all of the suggestions here are also server-side:
ASP.NET MVC Conditional validation