DataModel validation in c# - c#

I've a c# application(in fact it runs into a windows service or like a windows application).
In receive the configuration for one run of the service/application from an XML file.
This XML file is in fact only my data serialized/deserialized in XML. It's one of my other application that generate it.
Before running the business code, I would like to ensure that the configuration file is valid.
By this I mean things like "This String must not be null", "This TimeSpan must have a value greater than XYZ", ...
So only verification that can be made by seing the content of the field(no need to access to something else).
It reminds me a lot the Data Annotation that I used in asp.Net MVC, and I would like if there is something similar for simple c# code, without having to load the whole asp.net MVC dll.
My other option is to implement a method "Validate()" which throw an exception if one field is incorrect, but I will have a lot of if(String.IsNullOrEmpty() and other dummy validations.
I do not want to implement myself a big validator that uses reflexion, it's a bit overkill for only a small configuration file verification.
The application which generate those file could also be interessted to use those same validation.
Edit: I've to use .Net 3.5

This question looks like a duplicate of the following SO question.
Using ASP.Net MVC Data Annotation outside of MVC
Edit: Seeing as you say the ValidationContext isn't available I would recommend writing some custom code that uses Reflection and evaluates all the attributes on the properties for you.
See the answer to this question for an example of how it can be done.
ASP.Net MVC 2 Controller's TryValidate doesn't validate the List<> items within the model

I used the IDataErrorInfo(the same class will be used in the wpf application). And with a custom method where I check every possible attribute here.
Here is the method:
public Boolean IsModelValid()
{
Boolean isValid = true;
PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in properties)
{
if (!p.CanWrite || !p.CanRead)
{
continue;
}
if (this[p.Name] != null)
{
isValid = false;
}
}
return isValid;
}

Related

.Net 6.0 Blazor Server: Proper approach to checking IsUnique against the backend DB for Email / Phone number on Blazor form

I have a .net 6.0 Blazor Server web application that is essentially a basic registration form (contact information: First Name, Last Name, Email, Phone, etc).
I'm trying to create a custom ValidationAttribute (EmailUniqueAttribute) that will check for uniqueness of the form's email field against the backend database. If it exists already IsValid returns false , else if it doesn't it returns true.
The problem I'm encountering is that it appears that you can only pass constant arguments into a custom ValidationAttribute? In this case the argument that would need to be used in the validation is a boolean value that is determined at runtime based on user input to the email field and the result of a database query to check for its existence (IsUnique).
I thought about injecting my service to the back end calls into the custom ValidationAttribute and checking for uniqueness at the time of validation (anti pattern debates aside) but it looks like support for DI into a ValidationAttribute isn't available until .Net 7.1 preview based on other articles and questions I've read on this topic here.
How exactly should I go about this?
Well there are several ways to solve it:
A first one would be to setup the email-column inside your database with a unique constraint (you can do this for every solution/way). Duplicate entries will then throw an error on save. Simply catch the save-error and show them to your frontend.
Another way would be to handle errors a bit earlier by using the OnSubmit method of your EditForm. Inject a Service that reads all mail-entries from your database and check them against the entered email address. It should be sufficient to call the service once at OnInitialized to prevent multiple database selections for probably the same list.
A more convenient way for the user would be to use the above mentioned service to check the mail uniqueness while typing into the InputText field. You can hook up to several events there like #oninput.
You could also use some custom Validation packages like FluentValidation that extend the validation system by a more complex system which allows more complicated conditions to check against.
EDIT:
You can still make use of a custom attribute if desired:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public class EmailUniquenessAttribute : DataTypeAttribute
{
private EmailService _service;
public EmailUniquenessAttribute() : base(DataType.EmailAddress)
{
// You can use your DI system to get the desired service here
_service = new EmailService();
}
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
if (value is not string valueAsString)
{
return false;
}
return _service.EmailAlreadyExistsInDatabase(valueAsString);
}
}

Common Message/Error/Status to used across jquery or C#

There are times when we use same error or success message/checking of some status both in jquery & c#.
For consistency, we can define all message/status flag in as static class and use it wherever needed in c#.
Just an example:
C#
public class MyConstant
{
public static string Admin = "AdminRole";
public static string Approver= "ApproverRole";
}
if(userRole==MyConstant.Admin || userRole==MyConstant.Approver)
{
//more work
}
jquery:
if(userRole=="AdminRole" || userRole=="ApproverRole")
{
//more work
}
In stead hard coding msg/status in jquery, I would prefer approach similar to C#. Would be better to have common place to pull for client/service side.
How can I achieve similar in jquery? Better to say, How can I share common msgs/status flags between jquery & C#. I can think of following options:
Use Database. Cons: hitting DB every time may not be good idea.
Define some classes/property for msgs/status flags separately in jquery. Cons: duplicate; have to ensure all of them in sync.
maybe CMS but not necessarily, will be used in every application
Is there any better approach to share common Message/Error/Status to used across jquery or C#?
Thoughts?
One possible solution is T4 (text templates).
Just imagine a T4 which iterates each enumeration value (why classes of constants? use enumerations!) and creates an object literal like this in JavaScript:
var Roles = { "AdminRole": 1, "ApproverRole": 2 };
If you've never heard about T4, it's the text templating engine behind Visual Studio templates. For example, Entity Framework uses it to generate model classes.
Once you've created the text template, you can sync C# enumeration to JavaScript object literal from Visual Studio when you build your project or running the template manually (right-click on T4 and choose "Run custom tool").
Learn more about T4
I would consider enums for status codes, but you can stay with your strings (no problem). To better address JavaScript part use solution presented here: https://stackoverflow.com/a/2383215/3170952, that is:
my.namespace.Roles = {
ADMIN: "Admin",
APPROVER: "Approver"
}
Then you have one place where you define literals in JS. Better yet, you can weave C# literals into your JS (if you define it in one of ASP.NET MVC views or have other mechanism of incorporating C# into JS files). Then you have one place of definition statically checked during compilation time.

What does [Required] do?

I found nothing on the web what [Required] actually does. The msdn-article is not explorative at all.
static class Program
{
public static Main()
{
var vustomer = new CustomerClass();
}
}
public class CustomerClass
{
public string m_FirstName;
[Required]
public string m_LastName;
}
As far as i understand, that should throw an exception since m_LastName is required, but not set. But i don't get one. I don't get what it's good for and what this actually does.
RequiredAttribute, like all other attributes, does nothing by itself other than annotate something (in this case, a field of a type). It is entirely up to the application that consumes the type to detect the presence of the attribute and respond accordingly.
Your sample program does not do this, so the attribute does not have any visible effect. Certain frameworks such as ASP.NET MVC and WPF do check for and respond to the presence of the attribute.
This attribute is used by the Validator class to add validation errors based on any types that inherit from ValidationAttribute. This is used by MVC model validation, for example.
In C#, attributes are almost decoration to classes and properties.
Except for a few security related attributes, most do nothing. They are used by a higher-level framework to do something.
In the case of ASP.NET 4 MVC, only when the object is part of a request that attribute is used to generate an error.
If you want to use that attribute in any other environment, you must write code to inspect it.
It won't do anything from a plain old public static void Main()
Documentation on RequiredAttribute:
Specifies that a data field value is required.
However this validation is typically only performed in the UI layer. It is not "baked" into the constructor or other low-level usage. If you want to manually fire the validation you could do something like:
var customer = new CustomerClass();
var context = new ValidationContext(customer, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(customer, context, results);
if (!isValid)
{
foreach (var validationResult in results)
{
Console.WriteLine(validationResult.ErrorMessage);
}
}
To add to the current answers, these are some of the practical uses I can think of out of my head:
Entity Framework use this to model the database as not nullable fields.
Javascript client side validation provides javascript libraries for checking if the input field has any data, else prevent the form submission avoiding unnecesary roundtrips to the server.
Server side validation (when doing model binding) also check when you are posting a model with that decorator that the attribute passed in is in the request. This determines if the model state should be set to an invalid state or not. (1)
There are also annotation for JSON.NET library that changes how the model is serialized/unserialized. I'm pretty confident (but not sure) that the Validate Schema of Json.net does take into consideration the 'Required' attribute when validating a schema.
Other attribute decorators are used on web services, but 'Required' is not one I know has it uses in this scenario.
Web api uses this attribute to mark the property as required on documentation help pages and model binding.
You can create your own application logic that can be aware of the 'Required' property. For example, on a view to mark the property with an * in the label if it's required.
This are some uses but you are not limited to them.
(1) Note: if your property is, for example, an int and you decorate it with Required, model state will never be on a invalid state. You should use Nullable properties for this use-cases.

How To Do Validation in Silverlight/RIA When A Call To Database Is Required?

I feel like there is a better way to do this than how I am doing it now.
I am using Silverlight 4, RIA and EF (with an Oracle adapter). I am inserting a record into a table and doing a lot of validation on it with Validation attributes, but I have one piece of validation that requires querying the DB to check existing records before the new one can be inserted (this seems like it should be common and easy requirement, no?)
Right now, I am doing this client-side with an Invoke method on the DomainService. This seems lame and dumb. But I can't figure out how to do this server-side where it really belongs.
It seems like there should be a way to handle all of this server-side and inform the client of a validation error, but I can't quite figure it out and hardly anyone seems to approach this one particular validation scenario.
WCF RIA provides a means to attach validation to entities on the serverside. You build a class as detailed below naming it Rules.
public static partial class FooRules
{
public static ValidationResult FooIDUnique(Foo foo, ValidationContext context)
{
bool check = false;
using (FooEntities fe = new FooEntities())
{
check = fe.Foo.Any(f => f.FooId == foo.fooId);
}
if (!check)
return ValidationResult.Success;
return new ValidationResult("FooID error msg,", new string[] { "FooID" });
}
}
I've put together an example app that shows adding validation client and server side with RIA.
You can download it here.
I don't know how to link to the specific entry but check out this thread....
http://forums.silverlight.net/forums/p/212555/502113.aspx

Validating a class using DataAnnotations

I have a class that I am using to model my data in MVC. I have added some DataAnotations to mark fields that are required and I am using regular expressions to check valid Email Addresses. Everything works fine if the object is posted back to MVC and I have the ModelState property that I can check to confirm that the class is valid but how do I check to see if the class is valid outside of MVC using the same class and Data Anotations that I have already set up?
Here's a method that I've used in the past with Data Annotations to get all of the errors on an annotated object (it could use some improvements, but it's a good starting point:
public static IEnumerable<ErrorInfo> GetErrors(object instance)
{
return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(String.Empty), instance);
}
There doesn't appear to be anything built into .NET 3.5. If you can develop against .NET 4, though, there is a Validator class that provides what you need:
Validator class on MSDN

Categories