Range validation - make exceptions to the rule - c#

I have a class with a property which has a range attribution on it.
[Required]
[Range(5, 9999)]
public double Price { get; set; }
Which is respected at all times and on any user input.
But on one specific code path, where i am automating some entries, i want to be able to set the Price to 0. So i want to programmatically tell this model class to ignore this requirement.
Is it possible? If so how?

This seems like a duplicate of this question, but maybe I'm not completely understanding your requirements.
For your scenario I might try implementing the IValidatableObject interface so that way you can control the validation logic rather than using a declarative validation pattern.

I would suggest you to create a derived type of System.ComponentModel.DataAnnotations.ValidationAttribute. The implementation can be similar to RangeAttribute class with additional parameter of exceptional values.
Have a look at this MSDN article for details on how to do this.

Related

Asp.net mvc: an object reference is required Error while calling a function in [Required(ErrorMessage)

I am creating a web app in asp.net-mvc in which I am sending a Required ErrorMessage from my model, but the problem is, I want to translate the message as per user's preference,
so I did something like below
[Required(ErrorMessage = convertErrorMessage("Text to translate"))]
public string Reviews { get; set; }
public string convertErrorMessage(string text)
{
//convertingText in different language
return convertedText;
}
but I am getting the below error
an object reference is required for non static field
on the below line
[Required(ErrorMessage = convertErrorMessage("Text to translate"))]
what can I do, if I want to achieve this?
You cannot call methods to initialize attributes, because these values have to be known at compile time. There are two possible other ways though:
ASP.NET MVC supports standard ways to doing localization, which is the recommended way to go. It is a very broad topic, so I can only leave a few links [1], [2] here. Notice that even the RequiredAttribute you are using has properties ErrorMessageResourceName and ErrorMessageResourceType - these are strong hints that you should be using standard tooling for standard tasks.
If you still want to stick to what you have, define your own attribute and implement your custom logic in there:
class RequiredLocalizedAttribute : RequiredAttribute {
// override ErrorMessage get
// or ErrorMessageString get
}
However, I would strongly advise looking into option 1 instead. You may need a bit more time to learn and implement this, and that won't be time wasted, and may save you lots of headache as you application grows

ASP.NET MVC: Custom Validation by DataAnnotation depending on configuration

I'm using DataAnnotation for client and server validation of my view model. I would like to ask you about the best practices of using custom validation.
I have two forms, which use the same view model:
public class RecipientViewModel
{
[Required]
public string Address1 { get; set; }
public string Address2 { get; set; }
}
What I want to achieve, it is that the first form should validate the Address2 field, but the second form did not. Of course my view model is much bigger and I want to do it generic as much as possible.
Is there any possibility to pass a list of fields to be validated and how? For example view could pass it to view model somehow?
Please clarify your question or show more code.
In general the Annotations are very good to check expected structures or a certain kind of expected data. Like length, presence, type.
For other more complicated, complex business cases. Good implementation will have a business layer or a domain design which handles these use cases.
So define your use cases and think about an layer between controller and data model. Maybe something like a validation Services which gets injected into the viewmodel.
HTH
EDIT: You probably want to take a look at - Validating with a Service Layer from the ASP.NET site - http://www.asp.net/mvc/overview/older-versions-1/models-(data)/validating-with-a-service-layer-cs] which shows some of the conepts - the technology might have changed slightly since the article is from 2009 but you got the idea.

Validation strategies

I have a business model with many classes in, some logical entities within this model consist of many different classes (Parent-child-grandchild.) On these various classes I define constraints which are invariant, for example that the root of the composite should have a value for Code.
I currently have each class implement an interface like so...
public interface IValidatable
{
IEnumerable<ValidationError> GetErrors(string path);
}
The parent would add a validation error if Code is not set, and then execute GetErrors on each child, which in turn would call GetErrors on each grandchild.
Now I need to validate different constraints for different operations, for example
Some constraints should always be checked because they are invariant
Some constraints should be checked when I want to perform operation X on the root.
Some additional constraints might be checked when performing operation Y.
I have considered adding a "Reason" parameter to the GetErrors method but for a reason I can't quite put my finger on this doesn't feel right. I have also considered creating a visitor and having a concrete implementation to validate for OperationX and another for OperationY but dislike this because some of the constraint checks would be required for multiple operations but not all of them (e.g. a Date is required for OperationX+OperationY but not OperationZ) and I wouldn't like to have to duplicate the code which checks.
Any suggestions would be appreciated.
You have an insulation problem here, as your classes are in charge of doing their own validation, yet the nature of that validation depends on the type of operation you're doing. This means the classes need to know about the kinds of operations that can be performed on them, which creates a fairly tight coupling between the classes and the operations that use them.
One possible design is to create a parallel set of classes like this:
public interface IValidate<T>
{
IEnumerable<ValidationError> GetErrors(T instance, string path);
}
public sealed class InvariantEntityValidator : IValidate<Entity>
{
public IEnumerable<ValidationError> GetErrors(Entity entity, string path)
{
//Do simple (invariant) validation...
}
}
public sealed class ComplexEntityValidator : IValidate<Entity>
{
public IEnumerable<ValidationError> GetErrors(Entity entity, string path)
{
var validator = new InvariantEntityValidator();
foreach (var error in validator.GetErrors(entity, path))
yield return error;
//Do additional validation for this complex case
}
}
You'll still need to resolve how you want to associate the validation classes with the various classes being validated. It sounds like this should occur at the level of the operations somehow, as this is where you know what type of validation needs to occur. It's difficult to say without a better understanding of your architecture.
I would do a kind of attribute-based validation:
public class Entity
{
[Required, MaxStringLength(50)]
public string Property1 { get; set; }
[Between(5, 20)]
public int Property2 { get; set; }
[ValidateAlways, Between(0, 5)]
public int SomeOtherProperty { get; set; }
[Requires("Property1, Property2")]
public void OperationX()
{
}
}
Each property which is passed to the Requires-attribute needs to be valid to perform the operation.
The properties which have the ValidateAlways-attribute, must be valid always - no matter what operation.
In my pseudo-code Property1, Property2 and SomeOtherProperty must be valid to execute OperationX.
Of course you have to add an option to the Requires-attribute to check validation attributes on a child, too. But I'm not able to suggest how to do that without seeing some example code.
Maybe something like that:
[Requires("Property1, Property2, Child2: Property3")]
If needed you can also reach strongly typed property pointers with lambda expressions instead of strings (Example).
I would suggest using the Fluent Validation For .Net library. This library allows you to setup validators pretty easily and flexibly, and if you need different validations for different operations you can use the one that applies for that specific operation (and change them out) very easily.
I've used Sptring.NET's validation engine for exactly the same reason - It allows you to use Conditional Validators. You just define rules - what validation to apply and under what conditions and Spring does the rest. The good thing is that your business logic is no longer polluted by interfaces for validation
You can find more information in documentation at springframework.net I will just copy the sample for the their doc to show how it looks like:
<v:condition test="StartingFrom.Date >= DateTime.Today" when="StartingFrom.Date != DateTime.MinValue">
<v:message id="error.departureDate.inThePast" providers="departureDateErrors, validationSummary"/>
</v:condition>
In this example the StartingFrom property of the Trip object is compared to see if it is later than the current date, i.e. DateTime but only when the date has been set (the initial value of StartingFrom.Date was set to DateTime.MinValue).
The condition validator could be considered "the mother of all validators". You can use it to achieve almost anything that can be achieved by using other validator types, but in some cases the test expression might be very complex, which is why you should use more specific validator type if possible. However, condition validator is still your best bet if you need to check whether particular value belongs to a particular range, or perform a similar test, as those conditions are fairly easy to write.
If you're using .Net 4.0, you can use Code Contracts to control some of this.
Try to read this article from top to bottom, I've gained quite a few ideas from this.
http://codebetter.com/jeremymiller/2007/06/13/build-your-own-cab-part-9-domain-centric-validation-with-the-notification-pattern/
It is attribute based domain validation with a Notification that wraps those validations up to higher layers.
I would separate the variant validation logic out, perhaps with a Visitor as you mentioned. By separating the validation from the classes, you will be keeping your operations separate from your data, and that can really help to keep things clean.
Think about it this way too -- if you mix-in your validation and operations with your data classes, think of what are things going to look like a year from now, when you are doing an enhancement and you need to add a new operation. If each operation's validation rules and operation logic are separate, it's largely just an "add" -- you create a new operation, and a new validation visitor to go with it. On the other hand, if you have to go back and touch alot of "if operation == x" logic in each of your data classes, then you have some added risk for regression bugs/etc.
I rely on proven validation strategy which has implemented in .net framework in 'System.ComponentModel.DataAnnotations Namespace' and for example used in ASP.NET MVC.
This one provides unobtrusive way to apply validation rules (using attributes or implementing IValidatableObject) and facilities to validate rules.
Scott Allen described this way in great article 'Manual Validation with Data Annotations'.
if you want to apply validation attributes on interface then look at MetadataTypeAttribute
to get better understanding how it works look at MS source code

How do i validate classfields?

Is this a good aproach to making sure the fields has valid values for a database?
internal class Customer
{
private string _CustomerId;
internal string CustomerId
{
get
{
return (_CustomerId==null?string.Empty:(_CustomerId.Length>20?_CustomerId.Substring(0,20):_CustomerId));
}
set
{
_CustomerId = value;
}
}}
Regards Sven
A cleaner technique would be to annotate your properties with validation attributes and use a library to validate the entities.
Examples include:
Enterprise Library Validation Block
Castle Validator
NHibernate Validator
System.ComponentModel.DataAnnotations namespace
Then, depending on the library selected, your code would resemble:
public class Customer
{
[StringLengthValidator(20)]
public virtual string CustomerId { get; set;}
}
Your way of validating input is very brittle. You are excepting any possible input (for the CustomerId in this case) and sanitize it when it is requested. This might work in this basic scenario, but in a lot of cases you can't sanitize the input. You are basically correcting the mistakes of the user and making assumptions of what he intended. How will you do that with an mail address? For instance, must the mail address 'stevenhotmail.com' be converted to 'steven#hotmail.com' or to 'stevenhot#mail.com'. Besides this, there is also the possibility of a programming error. Would you want your program try to fix your own programming errors. This will give you headache. Or what will you do when two properties of the same entity have to be compared?
A better solution would be to allow the entity to become in an invalid state and check it's validity just before saving it to the database. When it’s state is invalid, don’t try to automatically correct the changes, but just throw an exception or communicate the errors back to the user.
There are multiple approaches of doing this. You can for instance implement an IsValid() method on each entity or use a validation framework.

NHibernate Validator One Value OR Another

Is it possible with NHibernate validators to get a validator that will validate one or other properties? In the example below either FirstName OR Surname is required.
[OneOrOther("Group")]
public string FirstName {get; set; }
[OneOrOther("Group")]
public string Surname {get; set; }
I think this post (http://devlicio.us/blogs/billy_mccafferty/archive/2009/07/30/writing-a-custom-nhibernate-class-validator.aspx) can be applied nicely in this case. I think the only difference is that the sample uses a mutually exclusive condition (one or the other, but not both -- XOR).
Yes you can create a property on the object to test whether the condition holds true and then use one of the nhibernate decorators to check that it is valid i.e. true.
From the documentation:
AssertTrue property check that the method evaluates to true (useful for constraints expressed in code rather than annotations)
This is by far the simplest method to implement the particular problem you have described, you can create a custom class level validator but hey its maybe more work than you need.

Categories

Resources