I have a viewmodel with a property defined like so:
public decimal decProperty { get; set; }
I have found this enforced "required" validation when I would like to allow nulls. To me specifying 0.00 is explicitly different to null ie the user is stating that the value is 0.00 while the latter means that the value is n/a.
The only way around this that I have found is to redefine the property as a string with regex validation:
[RegularExpression(#"\d+(\.\d{1,2})?", ErrorMessage = "Invalid decimal")]
public string strProperty { get; set; }
I am correct in my thinking and solution?
Thanks in advance.
A decimal property cannot ever be null though, try decimal? instead:
public decimal? decProperty { get; set; }
You could use a nullable decimal:
public decimal? decProperty { get; set; }
Doing so, if the user doesn't provide any value for the decProperty, it's value would be null. Otherwise, it would contain the value that the user provided.
This cannot be done with decimal, because null is not a valid decimal value. On the other hand a nullable decimal can has a a value the null or any valid decimal value.
If you want to read more about nullable types, please have a look here.
Related
I have got a class like this
Model:
public class Circle
{
[Required(ErrorMessage = "Diameter is required")]
public int Diameter { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Color { get; set; }
}
Testing:
[TestMethod]
public void TestCircle()
{
Circle circle = new Circle();
circle.Diameter = 5;
circle.Color = "Black";
ValidationContext contex = new ValidationContext(circle, null, null);
Validator.ValidateObject(circle , contex);
}
I was expecting it'd fail whenever Diameter or Color is null. However, the above testing only failed when the string parameter, Color, is null. Why? How should I do in order to validate Diameter as well?
You shouldn't use the Required attribute with numeric properties. Use the Range attribute instead:
The RequiredAttribute attribute specifies that when a field on a form
is validated, the field must contain a value. A validation exception
is raised if the property is null, contains an empty string (""), or
contains only white-space characters.
RequiredAttribute only validates against null (and empty strings), but an int is non-nullable and becomes 0 by default.
You could make it nullable (with int?) or you could use a different kind of attribute. As DmitryG says, you could use the RangeAttribute if there's a certain range of numbers that are acceptable to you, but if not I think the only way would be a CustomValidationAttribute with a function to compare the value to zero.
EDIT: Given that it's a diameter, I guess you need to make sure it's positive, and not just unequal to zero. In this case a RangeAttribute may indeed be best, with 1 as the minimum and Int32.MaxValue as the maximum.
This question already has answers here:
Is there any difference between type? and Nullable<type>?
(9 answers)
Closed 9 years ago.
When I reverse engineer my classes I get the following:
public Nullable<bool> Correct { get; set; }
public Nullable<bool> Response { get; set; }
I coded:
public bool? Correct { get; set; }
public bool? Response { get; set; }
Can someone tell me if there is any difference between these two. I have not seen the Nullable<bool> before and I'm not sure why it does not just create a "bool".
Note: I changed my coded to bool? in response to comments by Jon
"A Nullable can be assigned the values true false, or null. The ability to assign null to numeric and Boolean types is especially useful when you are dealing with databases and other data types that contain elements that may not be assigned a value. For example, a Boolean field in a database can store the values true or false, or it may be undefined."
Nullable Types
Can someone tell me if there is any difference between these two. I
have not seen the Nullable before and I'm not sure why it does
not just create a "bool"
technically there is no difference in Nullable and bool?. Whatever you write they will compile down to Nullable in IL. so no difference. The ? is just C# compiler syntax.
why require system for Nullable
it is because it is used as a type. And type needs to be in a namespace.
But there is a difference in bool and bool?. As bool is a simple value type that cannot be assigned null value whereas you can assign value to bool?.
Nullable represents a value type that can be assigned null and it lies in the namespace System.
Further as it can be assigned null therefore you can check whether it has value or not like this
if(Correct.HasValue)
{
//do some work
}
Nullable<bool> and bool? are equivalent ("?" suffix is a syntactic sugar).
Nullable<bool> means that in addition to typical bool values: true and false,
there's a third value: null.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx
Null value could be useful if you work with uncertain values, e.g. in some
cases you can't tell if the instance is correct one or not, if any response
has been given; for instance in your case
// true - instance is correct
// false - instance is incorrect
// null - additional info required
public bool? Correct { get; set; }
// true - response was given
// false - no response
// null - say, the response is in the process
public bool? Response { get; set; }
Yes there is difference between Nullable<bool> and bool.
public Nullable<bool> Correct { get; set; } // can assign both true/false and null
Correct = null; //possible
whereas
in your case you can't have it
public bool Correct { get; set; } //can assign only true/false
Correct = null; //not possible
Maybe the previous guy who coded may not exposed to bool? dataType.
System.Nullable<bool> is equivalent to bool?
Update: There is no difference between Nullable<bool> and bool?
There is no difference.
Hint: Nullable<Nullable<bool>> n; // not allowed
Source msdn Nullable Types
I've decorated a class with:
[Required(ErrorMessage = "Price is required.")]
public decimal Price { get; set; }
But when validating it with code:
for each (PropertyInfo prop in Me.GetType().GetProperties())
{
if (prop.GetIndexParameters().Length = 0)
{
for each (ValidationAttribute validatt in prop.GetCustomAttributes(GetType(ValidationAttribute), True))
{
if (!validatt.IsValid(prop.GetValue(Me, Nothing))
{
retval.Add(New PropertyValidationError(prop.Name, string.Format("There is a problem with the {0} property. It is flagged with the {1}", prop.Name, validatt.GetType.Name), validatt.ErrorMessage));
}
}
}
}
I'm finding that a value of 0 is being treated as fulfilling the "requiredness", which is not what I intended (in fact, I wanted to allow any value other than zero) - is it my validation code doing the wrong thing, or is there a way to use decorate with a ValidationAttribute that will fail for default values for value types?
When you're using a value type, such as decimal, it's impossible to not have a value. As such, that attribute is effectively meaningless.
It would be a better idea to use [Range], as this allows you to specify meaningful values. However, this will not allow you to handle "any non-zero value" (though you could easily handle any positive non-zero value).
Your criteria, as stated, would require creating a custom validation attribute to validate, as "any value other than default(T)" is not a built-in validation.
What about make you value type variable nullable?
public decimal? Price { get; set; }
Use the range validation attribute.
[Range(min, max, ErrorMessage )]
The error I get is this:
The 'SalesValue' property on 'ItemSale' could not be set to a 'Decimal' value.
You must set this property to a non-null value of type 'Single'.
But I already did:
[Table("ItemSales")]
public class ItemSale {
[Key]
public int ID { get; set; }
....
public Single SalesValue { get; set; }
}
Here is my LINQ, simple enough:
from x in database.ItemSales
select x
I am using Entity-Framework Code First
How do I solve this?
Have you checked the precision of the column type ? That was an error i once came along which, as far as i remember, was very similar to yours.
As far as i remember, the precision had to be 2, but had another value.
I have a numeric property on my model and i am using editorfor on my razor view with it. The field is not mandatory but the default validation makes the user enter a value because it wont accept an empty string for a number. I have ended up changing the model property to a string and then putting my own custom validation attribute on the property. This cant possibly be the correct way of getting what i want....can it??
[NonMandatoryDoubleValidation("Latitude")]
public string Latitude { get; set; }
What you need is a nullable double: double?. That way your variable will accept empty string or null value as well as double values. However, you'll need to check if it's empty each time you use it with Latitude.HasValue and use Latitude.Value to get its value.
How about a nullable double:
[Required]
public double? Latitude { get; set; }