MVC5 website newbie / Annotations on properties of autogenerated modell - annotations

i'm new to mvc 5, and I would like to build an asp.net application to interact with an existing database. I'm using VIsual studio 2013 and Entity Framework 6.
I've generated an ADO.net Entity Data Model from an existing database and I'm currently trying to find out the best way to make data validations, to avoid wrong inputs (let's take as example the field Email from entity Users).
The right way seems to be to use Annotations on partial classes. But i don't know how to add an annotation (on the new partial class that i created for that) if the original property declaration is on the autogenerated file.
The autogenerated class, looks like:
namespace Test.Models
{
...
public partial class Users
{
public string Email { get; set; }
}
...
}
Following the idea behind [this post] (Add data annotations to a class generated by entity framework), i'm trying to make a partial class to write the annotations there, like that:
namespace Test.Models
{
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(UsersMetaData))]
public partial class Users
{
[Someanotations]
public string Email { get; set; }
}
}
But on the partial class, i get:
1) Error on the line of "[MetadataType(typeof(UsersMetadata))]", saying that UsersMetadata could not be found, and
2) Error on the line where "public string email", saying that the property is already declared (which sounds logic for me).
How should i annotate on the new partial class the property that is declared on the autogenerated model?
It is possible to define a Regex to be used on the anotation?
Thanks for your time,
John

You're almost there. UserMetadata is actually another class that you apply the annotations to. I usually put both of these in the same file.
[MetadataType(typeof(UsersMetaData))]
public partial class Users
{
}
class UsersMetaData
{
[Someanotations]
public string Email { get; set; }
}

Related

Only allow write access on property to Entity Framework

Is there any way to only allow Entity Framework classes to write/read the EmailJson property ? The code works without this but it would be much cleaner if this property could not be altered by any code since having invalid json in it would throw an exception.
I cannot use a backing property because of the generic requirement.
public class EmailEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string EmailJson { get; set; }
public T GetEmail<T>() where T : BaseEmailModel
{
return JsonConvert.DeserializeObject<T>(EmailJson);
}
public void GetEmail<T>(T emailModel) where T : BaseEmailModel
{
EmailJson = JsonConvert.SerializeObject(emailModel);
}
}
I suggest using a seperate data access tier (for example a class 'EmailEntityService') that is responsible for all access to EmailEntity. All code throughout your solution should only use this service then. If you move EmailEntity to a seperate project you can ensure that access to it is only possible via EmailEntityService (if you keep that service in a project holding a reference to the 'entity project').
So at the end you have (at least) three projects:
1: Entity project
2: Entity services project (with a reference to 1, this project ensures entities cannot be altered directly)
3: Business logic project (with a reference to 2 but not to 1 to prevent direct access to entities)
Since entity classes are just POCOs I don't see any other possibilities to do this on a more technical/basic way.

How do I implement Business Logic on auto generated entities in Microsoft MVC2?

I'm new to MVC and I'm trying to figure out how to implement business logic in the auto generated Entities in an MVC project.
I know that if I create my own Model class I can put [Required] and other attributes on the fields but there doesn't seem to be an option to do that in the .edmx file.
Is there something I'm missing here?
Should I be creating my own classes that use the entities and put the logic in there?
It seems like there should be a way for me to do less work.
Thanks!
This can be achieved by using the buddy-class functionality in .NET implemented specifically for this reason. Once you have created your entities in your .ebmx file you can create partial classes to accompany your entities which define your business rules in a 'buddy class'.
[MetadataType(typeof(ProductMetadata))]
public partial class Product {
internal sealed class ProductMetadata {
[DisplayName("Name")]
[Required]
public string Name { get; set; }
[DispayName("Price")]
[Required, Range(1,10000)]
public decimal Price { get; set; }
[DisplayName("Description")]
public string Description { get; set; }
}
}
In the example above, assume that you already have a "Product" type defined in your object context which has properties for "Name", "Price", and "Description". So long as the buddy class type referenced by the MetadataTypeAttribute has matching property names, the attributes applied to the properties in the buddy class will be applied to the implementation type.
Note: if there are any property names in the buddy class which do not match the implementation type, you will get a runtime error. You only need to create matching properties in the buddy class for the properties you are interested in applying business rules to; all properties are optional.

ASP.NET MVC | Where I should to put DataAnnotations in model

A models already exists. They are situated in another project. Where I should put DataAnotations in that project or my one? Should I use partial classes? I would like to put DataAnatation because I want javascript validation to work on client.
You can't use partial classes across assemblies, so that option is out.
You can create DTOs (data transfer objects) that are copies of the ones in the other assembly, annotate them and map.
For easy mapping you can use a tool like auto mapper. If the property names match, it will essentially do all the work for you.
Create a partial class for your Model. like this:
[MetadataType(typeof(Log_Validation))]
public partial class Log : IEntity
{
}
then create a new class Log_Validation which does all the data annotations stuff.
public class Log_Validation
{
[DisplayName("Level")]
[Required(ErrorMessage = "Please provide a level")]
public String Level { get; set; }
}

Ria service generated code not support partial class

I'm using Ria service class library. This contains 2 library named RiaClasslibrary RiaClasslibrary.Web.
Riaclasslibrary.Web contains ADO.NET entity data model and named BaseModel. BaseModelcontains tPage class.
My problem is
I'm inserting separated tPage class. This class contains 2 public property. show below
public sealed partial class tPage : EntityObject
{
public List<tPage> Children { get; set; }
public tPage Parent { get; set; }
public Boolean IsSelected { get; set; }
}
After I'm inserting DomainService and building RiaClasslibrary.Web class library. But ria service generated code doesn't contains above properties.
You have a question. Why you separate tPage class. You simply insert those 3 property in Modelbase.Designer code.
My answer is: Database doesn't contain those 3 property and If I'm inserting properties in the code, properties removed after updating Entity Model.
#ebattulga
I don't know if you still have this issue, but I will post the answer because I came to similar issue.
The answer for
After I'm inserting DomainService and
building RiaClasslibrary.Web class
library. But ria service generated
code doesn't contains above
properties.
is quite easy but hard to find.
You can read here in section "Shared Code" http://www.silverlightshow.net/items/WCF-RIA-Services-Part-5-Metadata-and-Shared-Classes.aspx
If you want to see custom properties from partial classes on the Client you have to rename class file name from MyClass.cs to simply MyClass.shared.cs. This will create partial class in the code generated Client side.
HTH
Daniel SkowroĊ„ski

How to save manual change after a update using Entity framework designer?

I'm using entity framework designer to build entities. I found the designer really hard to use because it overwrite all your manually change after each model update using the designer. How did you round off this problem? Thanks!
What sorts of things are you manually changing? The entity still has to be mappable to the database schema.
You can extend or add functionality by declaring a partial class.
Don't make any change to the entities in the generated file -- I think it says that in the header.
All of the entities are generated as partial classes, which means you can declare "more" of the class elsewhere.
Here is an example:
public partial class Name
{
public string First { get; set; }
}
public partial class Name
{
public string Last { get; set; }
}
Although I have two different class declarations, potentially in different files and folders within the project, it gets compiled as one class.
I can now use the Name class like this:
var name = new Name();
name.First = "Jane";
name.Last = "Doe";
As you can see, the properties from both declarations are unified in an object of type Name.
To apply this to EF, leave the partial entity class alone, and declare a separate partial class with the same name to add functionality.
There is an alternative third-party tool. For more information, refer this. Currently, Devart Entity Developer doesn't include the Update From Database functionality. The Update From Database feature is on our roadmap.