Dynamic data annotation in mvc - asp.net-mvc

i am creating instance of class by using Activator in c# mvc.
but i have to add attribute for example
[required]
dynamically to the instance.
so how can i do it.

Related

Created DbConfiguration dynamically in EF6

I'm using EF 6.4.4 in .NET 5, and want to associate a MyDbConfiguration with a MyDbContext. However, the only way to do this appears to declare MyDbContext with a DbConfigurationType attribute. For example:
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
But an attribute is static, and I need to create MyDbConfiguration dynamically, via a dependency injection framework. Is there any way to do this?

Partial class on a model when Entity Framework is in separate library

I am not sure if this is the correct way to go, if so, please advise otherwise.
This is an ASP.Net MVC 4 site using EF 5.x
Suppose you have your Entity Framework in a class library on it's own.
Code Generation Item has now generated all of your Models (the xxx.tt section of your EF mode)
This project is then added/referenced in the development of a site.
You can now access the data via the EF.
Now - in the site project I want to create a partial class of one of my EF models, for example "Users", with an additional property that isn't in the DB.
In the past on a web forms project when the EF was part of the project and not a reference I would simply create the partial class and all would be good; my "Users" would now have a bunch of other stuff in it that wasn't database related but needed on the "User".
I can't seem to get this to work in this MVC project where the EF is in a separate project.
I have tried doing this for example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyTestEntity.Entity;
namespace MyTestMVCSite.Models
{
public partial class Email
{
public string OtherEmail {
get { return "me#myEmail.com"; }
}
}
}
I have also tried inheriting the EF models class, like this:
public partial class Email : MyTestEntity.Entity.Email
{
public string OtherEmail {
get { return "me#myEmail.com"; }
}
}
Nothing I seem to be doing gives me access to "OtherEmail"
What I actually want to be able to do is create a partial class for some of my models and then have this partial class implement an interface so i can inject an instance of this interface into another object rather than overloading.
Am i talking crazy nonsense?
You cannot have two partial classes referring to the same class in two different assemblies (projects). Once the assembly is compiled, the meta-data is baked in, and your classes are no longer partial. Partial classes allows you to split the definition of the same class into two files.
Is it possible to have two partial classes in different assemblies represent the same class?
If you wish to augment your models with additional properties used for display purposes, then you should consider using view models, and a mechanism for mapping data to and from your models to view models.
You can then perform validation independently from the model based on the current view. View models will also protect you from accidentally exposing properties on your model that you do not wish users to alter through post data, even if you haven't explicitly specified them in your view.

display dataannotation depend on other property MVC4

i Have a property CountryText that contain the text to show for the property country, So i need to do somehing like this:
[Display(Name=CountryText)]
public string Country { get; set; }
public string CountryText { get; set; }
How can I do it please??
UPDATE:
It's not possible to do it.
You would need a custom attribute to decorate your properties, and a custom model metada provider (usually inherited from DataAnnotationsModelMetadataProvider, which is the default in MVC apps). The custom provider would be neccessary to set the metadata defined in your custom attribute.
The problem is that you cannot access the model from the model metada provider. You can acces information on the types (model type, container type, attributes...) but not a concrete instance of the model, so you cannot get a property value and use it in the provider.
Alternative
You can however use a Html.Label to show the field title.
If you want to make it more "automatic" you can alwasy write a custom html helper which creates the label for you. This helper have full access to the model type and the model content, so you can still use a custom attribute, look for it on the html helper code, and use the content of the other property.
If it was possible with metadata provider
Your custom metadata provider should add all the neccesary metadata for the view model property. This metadata provider could be convention based or use custom attributes to add the additional info.
These blog entries explain perfecty how to implemente custom attribute and metadata provider.
Diving into ASP.NET MVC 3 Model Metadata Providers
Model Metadata and Validation Localization using Conventions

Validation approach on MVC3 CRUD application with EF4-based WCF as backend

I develop a simple MVC3 CRUD application - simple controllers / views, which uses WCF service for CRUD data access.
The WCF uses EF4.1 with DbContext, and simple CRUD-style methods: ListEntities, GetEntity(ID), AddEntity (entity), DeleteEntity(ID)
If I develop the MVC application directly with EF, code first, I can annotate properties in the entity classes with validation attributes, and the MVC application will automatically recognize validation errors and report them in the UI when I try to save and a validation error occurs (e.g. a required field is not set).
But in my application I don't use this approach and I face two problems:
My entities in the WCF are generated from the EDMX, which in turn was also generated from the database. So I cannot actually add to them any data validation annotation attributes, because they'll vanish as soon as the entities will be regenerated from the EDMX. Is there any solution to this?
Since my client (MVC app) does not share the data contract classes with WCF (for clear separation), but instead it is generated form service reference, even if I find a way to add data annotation attributes to server-side data contract classes, will they be recognized and recreated when the data contract proxy class is created on client side?
So how could I made the MVC application to use client side validation and error message reporting for validation failures when binding to entities exposed by WCF service as data contracts?
One idea I have is, on client side, to create derived classes for all entities exposed as data contracts, and apply annotation attributes to them to desired properties. But this doesn't looks like a good solution to me, because with this I create a logic "coupling" between UI client and the WCF service / data layer (forcing UI to know about data more than it should do - by putting BL logic in client).
Can anyone give me some suggestions on how to handle those this situation?
Thanks
1: Yes you can add validation using the System.ComponentModel.DataAnnotations.MetaDataType.
I answered this question at MVC Partial Model Updates
2a: What you can do is create a seperate Class Library Assembly that contains all the interfaces (with or without additional MetaDataTypes) and use that on both the WCF service and the MVC application. After you add the reference to your MVC application, when adding the WCF Service reference, you can match the WCF Service DataContacts directly to the interfaces in the Assembly. One Caveat is that both the WCF service and MVC application are dependant on the Assembly (some might consider this tightly coupled) but this should be ok because you are only tightly coupling at the interface level, and whether or not you choose to allow VS to recreate it's own interfaces/classes or reuse what you already created in the Assembly it boils down to the same thing in my opinion.
2b: If you decide not to use a Class Library, I'm pretty sure that the service reference classes are partial, and you can simply create another .cs file with partial classes and add the interfaces as I described in part 1 to the partial classes.
Update
I am currently using Entity Framework to access my database. Entity Framework, like WCF References, classes are Auto-Generated classes will look something similar to:
[EdmEntityTypeAttribute(NamespaceName="MyNameSpace", Name="Info ")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Info : EntityObject
{
public static Info CreateInfo (global::System.Int32 id)
{
Info info= new Info ();
info.Id = id;
return info;
}
public string Name { get; set; }
public string FavoriteColor { get; set; }
// etc etc
}
In a separate file with the same namespace as the previous partial class, I have created:
[SomeAttribute1]
[AnotherAttribute2]
public partial class Info: IInfo
{
}
So now my auto-generated class is not only based on an Interface I created IInfo so the actual methods are not exposed (because my datatier in MVC returns interfaces), but it also has Attributes (for Data Annotations or whatever).
What I would suggest is instead of putting your data annotations directly on your WCF Service reference class is to use the MetedataType DataAnnotations. This allows you to separate the actual data object with the data annotations validations. Especially helpful if you want to use the same data class with different validations based on whatever (maybe administrators don't have to have a valid favorite color).
For example:
public interface NormalUser
{
[Required]
string Name { get; set; }
[Required]
string FavoriteColor { get; set; }
}
public interface AdminUser
{
[Required]
string Name { get; set; }
string FavoriteColor { get; set; }
}
[MetadataType(typeof(INormalUser))
public class NormalUserInfo : Info { }
[MetadataType(typeof(IAdminUser))
public class AdminUserInfo : Info { }
In this example we have two different classes NormaUserInfo and AdminUserInfo which both have different validations. Each of them have inherited from Info so they are valid models that can be passed into the WCF Service.
Out of my mind, as I can't test it right now...
Let's say your autogenerated code is like this:
public partial class Employee
{
//some code here
}
You can add a new Employee class, also partial, and this one won't be autogenerated
[you can annotate here]
public partial class Employee
{
//somecode here
}
try it
As for the validation, you could use: http://fluentvalidation.codeplex.com/

Should I use entity-framework classes or model classes in the Controllers?

I am new to entity framework and mvc.
I am trying to understand what a Controller should pass to the view.
Should it be the class from Models (MySolution.Models.Story) or the class from the entity framework (MySolution.Story).
The problem is that if I pick the one from entity framework, then the DataTypes and html-helpers are not working correctly. If I pick the class from models, then I can't convert from the entity class to the model class, for example:
TrendEntities TrendDB = new TrendEntities();
public ActionResult Details(int id) {
var Country = TrendDB.Countries.FirstOrDefault(c => c.CountryId ==id);
return View(Country);
}
Just use the adp.net entity framework POCO templates to generate. download the template. right click in the entity designer and select "add code generation item" and choose the poco template. Now your objects dont have all of the 'entity framework baggage' with them. Proxies are automatically created behind the scenes and you don't need to do any object mapping.
You can find this template by adding a new item to visual studio 2010, and searching the online templates from within the add dialog for POCO. The template name is:
ADO.NET C# POCO Entity Generator
You are looking for either AutoMapper or ValueInjecter. These two libraries are "Object to Object" mappers, which are designed for mapping values from one object to another object. I have only used AutoMapper before. It is great and pretty easy to pick up. I've heard good things about ValueInjecter as well.
After some investigation, I figured out that I had a design problem.
Long story short, REMEMBER that in MVC 3 we need a to define the following class in the model
public class StoryDBContext : DbContext
{
public DbSet<Story> Stories {get; set;}
}
And then in the controller THAT's the one to use when accessing the Entity Framework.
In the previous version we were not defining the above class and were using the TrendEntities class (that was created by the framework) to access the DB.
That's a bit confusing...
So, in my example, TrendDB should be of type StoryDBContext instead of TrendEntities and things are working as expected.
Use a ViewModel. This is a class that you declare having the properties you want to display on your View.
For example:
var country = TrendDB.Countries.FirstOrDefault(c => c.CountryId == id);
CountryDetails details = new CountryDetails();
details.FirstValueToShow = country.Name;
return View(details);
Remember to strongly type your Details view to the ViewModel.

Resources