How to use remote attribute in entity framework classes - c#

In my application I am creating my EDMX file using Database First Method.
I get classes generated for all of tables there.
I am able to use annotations like Required,Display,StringLength,RegularExpression,etc. there.
I know in my model of MVC I can use annotation named "Remote" by which I can validate my entity property.
Is there any way to use this "Remote" attribute in entity classes ? or may some other way to create custom annotation?
Update:
I have ViewModel Like this
public Exam Exam { get; set; }
public TestInfo Test { get; set; }
Both Exam & TestInfo are entity classes generated by entity framework.
There is property "ExamName" in entity class "Exam" which I want to validate for duplicate names.

Remote is a data annotation used to validate an input user enters in UI. It makes an ajax call to one of your action method (which you can specify) and expects a result value which tells whether this data already exists in your system.
You probably need to create a new view model for your view, instead of using the entity class created by entity framework, for your view. then you can have Remote attribute on that. In your action method ,you may deal with the actual entities to check the existence of the data.
public class RegisterVM
{
[Required]
[Remote("IsAvailable", "Validation")]
public override string UserName { get; set; }
}
Now you may have your IsAvailable action method to check the UserName exists or not. Also make sure now your Register viw is strongly typed to this new RegisterVM viewmodel.
#model RegisterVM
#using(Html.Beginform())
{
// your form controls
}
It does not makes sense to have Remote attribute on an Entity class. It should be on a view model.Otherwise you are mixing things up!

Related

What should a client be sending when creating an entity in ASP.NET Core?

I'm creating an API using ASP.NET Core which has no visual component to it. In my controller I have a POST method, to which the client passes an instance of a model class.
I override some fields of the incoming model and then send it to my database.
class MyModel
{
public Guid ID { get; set; }
public DateTime CreationTime { get; set; }
public String Name { get; set; }
}
[Route("api/[controller]")]
public class IntermediaryController : ControllerBase
{
protected async Task<ActionResult<MyModel?>> Create(MyModel entity)
{
entity.ID = new Guid(); // Storage sets this if it's empty
entity.CreationTime = DateTime.Now;
return _storage.Create(entity);
}
}
I'm wondering since I don't want them submitting their own Guid or DateTime, maybe I should create a cut down model, which just contains the fields they can submit. I'm fairly new to ASP.NET Core Web API, and I'm not sure if that's good practice, or just being overly verbose?
I can imagine ending up with a few versions of every model to cover slight variations of what I want the user to see/submit.
If I did go down this route, would those support classes still be called models, or are they then something else?
Yes, your guess is correct - you should never send Model to or from client. OK, "never say never" - except in the most trivial cases. You need to shape what's called ViewModel or DTO (data transfer object - same thing) that will allow you to do exactly what you describe.
However, in POST APIs your server-side code can add an object to Entity Framework without ID, and assuming that the database generates ID, it will return the object with ID back to the model
Post requests are meant for creating a new record. Ideally, databases should be designed to have the "ID" field as an identity column or your API should have its own logic to create a unique identifier for the record in database.
So, the request object in case of post requests should not contain a property to pass the unique identifier.

Required attribute for property that is not required in the database

I have a form, where some fields are mandatory. A few of the mandatory fields have not always been mandatory, hence there are null values in the database.
If I add [Required] for the property, I will get a SqlNullValueException, because there are null values in the database.
What is the best practice to get a field to behave as if it had a [Required] attribute?
[Required]
public string? foo { get; set; }
You're a bit light on context here, but I assume you are using Entity Framework and you have a class setup for the entity and this is what has your [required] field. I am then assuming you are using this same class with your form.
If this is the case then, I would advise you to create a second class which will act as your view model. This way you have a data model (entity class) and a view model (front end specific class). Then you can easily separate the logic of the two behaviours.
You can use something like AutoMapper to make transferring of property values between the two a little easier too.

asp.net mvc model the same as (database mapped) object?

I have the following setup: fluent nhibernate + asp.net mvc 4.
I have a seperate project in VS where all my objects are stored, these objects are directly mapped to the database.
However, to display data from these objects in the views, I need 'models'.
Do I need to create new model objects, based on these database mapped objects, or can I just pass these database objects as a model to the view? (is this a good idea?)
Thanks!
In my opinion you should create additional ViewModel classes. If some changes are to be made to the data that get displayed, it's easier to just modify these models; your domain mappings will not be affected by some particular "rendering" circumstances.
Another advantage would be that you can decorate the properties with formating attributes, without enforcing these settings on future projects that depend on your domain.
For example, say you have the following Customer class in your base project:
public class Customer
{
public string Name { get; set; }
public string Address { get; set; }
}
You can add a [Required] attribute on the Name property to make it mandatory. If for a particular project you need to also make the Address property mandatory, you would decorate it with another [Required] attribute. If you directly use the domain model classes, you will enforce that the Address property would always be required, even though the project requirements would not state that. This can be further extended to different validation attributes and also additional data that you may want to sent to the view along with the model (such as composite fields).
This is largely a design decision that depends on the size of the project, etc. Without getting into too much detail, the short answer is yes, you can use your database objects/models directly in your Views.
Sometimes it may be desirable to create specific view models if you only want to show a subset of the fields, or do different validation than the database in your View. You can then can validate this view model in your controller and if everything is okay, map it to your nHibernate models.

Why are buddy classes used for validation?

I am curious as to why data validation is done using buddy classes. Consider the following example, where MyEntity is a Linq-to-SQL or Linq-to-Entities entity, and the class below is a partial class enhancing the entity.
[MetadataType(typeof(MyEntity.MyEntityMetadata))]
public partial class MyEntity
{
private class MyEntityMetadata
{
[Required(ErrorMessage = "The title is required.")]
public string Title { get; set; }
}
}
Why is the design so? When they designed DataAnnotations, why was this "buddy pattern" selected? Why not place the attributes directly in the entity?
I assume this prevents generated entities from overwriting custom Meta Data information.
The reason is practical - in linq-to-sql and linq-to-entities, the code representing the classes regenerated every time the object model is updated. In order for the annotations not to be overwritten when this happens, they need to be in a separate "buddy" class.
If you're using Data Annotations in a different context - say for a view model - then they can go on the original class itself.

Attaching validation to EF objects used in MVC controllers/views?

We're throwing together a quick project (CRUD forms) and decided to skip view models and use EF entities directly in controllers and views. Since I'm not used to this approach, I'm confused about handling validation.
For example: a DB field has a length of 25. How does that get transferred (if it can) to a validation constraint in my view? If i was using an intermediate model, I would attach attributes to the model properties and it would work. How would I do this using EF objects directly? Thanks.
This can be done using MetadataType attribute on the Ef generated classes. The EF generates partial classes. So those can be extended and attribute added to it. Then another "buddy class" can be written that can have member decoration. For example
[MetadataType(typeof(EFGeneratedClass_MetaData))]
public partial class EFGeneratedClass
{
}
public partial class EFGeneratedClass_MetaData
{
[Required]
[Display(Name="Member1 Display")]
public string Member1 {get; set;}
}
Easiest thing to do is to use the DataAnnotations attributes that are in the System.ComponentModel.DataAnnotations anmespace.
MVC respects those and will populate your ModelError collection if any fail. In the case of your example, you could add a using statement for that namespace and then just flag a property with
[StringLength(25)]
and call it a day.
You need to use a partial 'buddy' meta class and decorate it with validation attributes.
For example, say your entity was 'Foo':
[MetadataType(typeof(FooMetadata))]
public partial class Foo {}
public class FooMetadata
{
//apply validation attributes to properties
[Required]
[Range(0, 25)]
[DisplayName("Some Neato Property")]
public int SomeProperty { get; set; }
}
For more information see this link on MSDN:
Customize Data Field Validation in the Model
Cheers.

Categories