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.
Related
I am new to Entity Framework. I started with database first approach which created my classes corresponding to the tables I selected. I am using WPF. Unfortunately there is a problem occurred while EF6 was mapping classes. The assigned type for a field is byte while in some cases the value exceeds the byte constraints. So, I want to replace it with either int or double. How do I change the model field types without any changes made for the used database?
namespace DataChrome{
public partial class REGISTRY_MEST{
public byte MEST { get; set; } //Wrong typed field
public string MESTNAME { get; set; }
public Nullable<byte> IDSTRAT { get; set; }
public Nullable<int> MESTOLD { get; set; }
}
}
So, giving 7 hours to this problem I found the right solution. All you need is just to set user mapping rules in appconfig file. For more details: visit this page.
The type change should be possible by editing the edmx model: click the MEST property of the class inside the edmx model, then set the Type accordingly in the Properties Window and save the model.
You are running a risk by doing this, as it might be possible to store a value too big for the column if you just change the type this way. You noted that you are using Oracle as the underlying DB, so it might very well be the case that EF generated a "wrong" type for that property.
If you are absolutely sure that the DB will accept the expanded type (int, double) then it should be safe to edit the property as I mentioned at the start. Otherwise you would have to change the DB and generate the class anew - you might need to delete the class from the model and add it again, because not all changes to the table are picked up by the automatic update process.
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!
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.
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.
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.