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; }
Related
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.
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.
How can I ensure that an entity is bigger than an entity before it, such as in my following example of refilling a car with fuel, or a tank with water:
[Required()]
[Range(0.00, 100000.00)]
public double BeforeRefill { get; set; }
[Required()]
[Range(BeforeRefill , 100000.00)]
public double AfterRefill { get; set; }
I want to achieve something like above, how ever it does not work in my code.
Is there a way in which I can create a custom Validation Attribute in which I perform such a check. Or some how implement my own validation so that when I call ModelState.isvalid() it will check?
just inherit from the validationattribute class. see also
http://www.codeproject.com/Articles/301022/Creating-Custom-Validation-Attribute-in-MVC
you can get the object you are checking from validationContext.ObjectInstance and then you can use reflection to find the other value.
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 )]
I want to apply the DebuggerDisplayAttribute to include an memory address value.
Is there a way to have it displayed in hexadecimal?
[DebuggerDisplay("Foo: Address value is {Address}")]
class Foo
{
System.IntPtr m_Address = new System.IntPtr(43981); // Sample value
System.IntPtr Address
{
get { return m_Address; }
}
}
This will display: Foo: Address value is 43981
Instead, I'd like the value to be displayed in hex, like that: Foo: Address value is 0xABCD.
I know that I could apply all kinds of formatting by overriding ToString(), but I'm curious if the same is possible with DebuggerDisplayAttributes.
Thanks in advance!
Yes you can use any method off the properties just as you would normally.
[DebuggerDisplay("Foo: Address value is {Address.ToString(\"<formatting>\"}")] is an example
http://msdn.microsoft.com/en-us/library/x810d419.aspx
There's a tip recommended by https://blogs.msdn.microsoft.com/jaredpar/2011/03/18/debuggerdisplay-attribute-best-practices/
Basically, create a private property, say, DebugDisplay. Have the property return a formatted string of your choice. Then just make use of your new private property in the DebuggerDisplay attribute.
For e.g.
[DebuggerDisplay("{DebugDisplay,nq}")]
public sealed class Student {
public string FirstName { get; set; }
public string LastName { get; set; }
private string DebugDisplay {
get { return string.Format("Student: {0} {1}", FirstName, LastName); }
}
}
I find this way to be much more readable.
If you only want to view values in hex format, there is an option in Visual Studio to display values in that format. While debugging, hover over your variable to bring up the debugging display, or find a variable in your watch or locals window. Right-click on the variable and select the "Hexadecimal Display" option. The debugger will then display all numeric values in hexadecimal format.
In this case, you will get: "Foo: Address value is 0x0000abcd"
Unfortunately I couldn't see any way to really control the format of the string that is displayed by the DebuggerDisplay attribute as you were asking.
From Microsoft's own documentation:
https://learn.microsoft.com/en-us/visualstudio/debugger/format-specifiers-in-csharp?view=vs-2017
You can display a value in hexadecimal format by adding ,h to the evaluation of the expression.
This also works very well with the DebuggerDisplay attribute.