Asp.net identity context is not mapping without custom classes - asp.net

So, I have changed my application so that I may use an integer primary key on my tables (a horrid process by the way). Everything works fine. Consider my ApplicationDbContext class:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>, IIDentityContext
{
public ApplicationDbContext()
: base("OwinTestDefault")
{
Database.SetInitializer<ApplicationDbContext>(null);
}
...
}
Now consider, for example, my user login class here, in its entirety:
public class CustomUserLogin : IdentityUserLogin<int>
{
}
It seemed silly to have to make a class just for this, and that I should be able to just replace any instance of this with IdentityuserLogin<int> in the code, resulting in this now:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, int, IdentityUserLogin<int>, CustomUserRole, CustomUserClaim>, IIDentityContext
{
public ApplicationDbContext()
: base("OwinTestDefault")
{
Database.SetInitializer<ApplicationDbContext>(null);
}
...
}
However, bafflingly, it now doesn't work and throws the error:
The type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin`1[System.Int32]' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive or generic, and does not inherit from EntityObject.`
Searching around, some people have run into this when they have changed their table names, but I have not done this, and regardless, overriding OnModelCreating and explicitly mapping everything I can (table name, keys, column names and properties) has no effect and it still complains it isn't mapped. Plus, looking at the source code of the base classes on GitHub, the mapping should be fine anyways.
Any ideas?

It seems that in Entity Framework, you cannot map multiple levels of generic types, as EF cannot create a proxy from this. Props to this answer: Are generic classes not supported as models in Entity Framework?
If you consider IdentityDbContext.cs in the source code, this line:
public virtual IDbSet<TRole> Roles { get; set; }
is really:
public virtual IDbSet<IdentityRole<int, IdentityUserRole<int>> Roles { get; set; }
It needs to be able to make a proxy out of this very type as a whole, thus why using a derived base class works.

Related

Ignore column but populate property through stored procedure EF code first

I have ignored a column through fluent API but want to populate that property while executing stored procedure using some logic. But it is not mapping the ignored column property. Please let me know if there is any way to do this in Entity framework code first.
I've faced with the same problem recently. The only solution I found is a class hierarchy:
public class MyEntityBase {
public int Id { get; set; }
}
public class MyEntity: MyEntityBase {
...
}//This class is mapped to DB with a fluent API and does not contain ignored property.
//Also it does not have derivative classes, so EF will not create class inheritance in DB.
public class DerivedEntity: MyEntityBase {
public int IgnoredProperty { get; set; }
}//Use this class while executing stored procedures
P.S. Do not mark class MyEntityBase as ABSTRACT - EF will map this relationship as database inheritance.

How to organize a project into three tiers?

I have an asp.net website and I would like to organize it into three layers
DataAccess
Domain
UI
What specifically goes in each of these layers?
e.g
Data
- Models
- Repositories? Would that be just interfaces
- IoC?
Domain
- Services?
UI
- javascript
- Area specific models?
- css
Could someone provide a simple guideline for organizing an asp.net website like this?
As other people have said each situation is different, but for a basic architecture, I would probably go along with something like this. It has gotten me out of a few jams and up and running quite quickly.
Infrastructure Layer
This is where all the data access is done. Database connection management, etc.
The Repositories include all queries to the database.
The Dependency Resolution sits here too. Use your DI Container of choice.
Domain Layer
This is where all you business logic sits.
The Domain Services Interfaces are what the UI layer call to use your business logic
UI
Pretty obvious this one....
Code Example
--UI
public class MyController
{
private readonly IMySerivce _myService;
public MyController(IMySerivce myService)
{
_mySerivce = myService;
}
public void MyAction()
{
_myService.DoSomeAction();
}
}
--Domain
public Interface IMyService()
{
void DoSomeAction();
}
public class MySerivce : IMyService()
{
private readonly IMyRepository _myRespository;
public MySerivce(IMyRepository myRepository)
{
_myRepository = myRepository;
}
public void DoSomeAction()
{
_myRepository.Save();
}
}
public interface IMyRepository
{
void Save();
}
--DataLayer
public MyRepository : IMyRepository
{
public void Save()
{
//Manage Save here
}
}
Additionally I usually have a separate area for unit/integration tests.
Update
This most definitely is dependent on your situation. It is very hard to say what method is best without fully understanding what you are ultimately trying to build.
From the list below you can see which method works well for you or fits well with your architecture.
Regardless of which one you choose, your Repository Implementation will have to have a dependency on your Domain Objects project.
Some techniques in doing it include:
No Mapping
Your Domain Objects really then become dummy mappings to your tables. i.e. have a table in your database call User. Then have a Domain Object called User. This is by far the simplest technique.
--Domain
public class User
{
public int Id {get; set;}
public string UserName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Password {get; set;}
}
--Infrastructure
public class UserRepository : IUserRepository
{
public Core.User GetById(int id)
{
return DBConnection.GetByIdQuery(id);
}
}
Mapping
Martin Fowler describes it here
It is possible in your infrastructure layer to have what are known as Domain Transfer Objects (DTO) that represent your database tables. Similar to above, a table called User, a DTO called User. Both having the same properties.
Your domain Entity then becomes a true representation of your domain and business logic.
The mapping of the DTO to your Domain Entity (search query) can be done in the Repository and the mapping of your Domain Entity to your DTO (save/update query) would also be done in your Repository.
To do your mapping you can either create custom mapping classes or use 3rd party tools like AutoMapper. I am a big fan of AutoMapper.
A sample code example would be along the lines of:
--Custom mapper
public class UserRepository : IUserRepository
{
private readonly IUserMapper _userMapper;
public UserRepository(IUserMapper userMapper)
{
_userMapper = userMapper;
}
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return _userMapper.MapUserDTOToDomainEntity(DtoUser);
}
}
public class UserMapper : IUserMapper
{
public Domain.User MapUserDTOToDomainEntity(DataEntity.User dtoUser)
{
//Manual property mapping
}
}
--AutoMapper Example
public class UserRepository : IUserRepository
{
public Domain.User GetUserById(int id)
{
var DtoUser = GetUserByIdQuery(int id);
return Mapper.Map<Domain.User>(DtoUser);
}
}
Other examples include:
https://stackoverflow.com/questions/14724612
There are many many debates out there in blogs and here on SO about the value of DTO's,
including MSDN, this blog and these https://stackoverflow.com/questions/11237946, https://stackoverflow.com/questions/15148866

Overriding validation attribute from a base Model

i have a MVC controller called MyController with an action called MyAction. For other hand i have a Model called MyModel, and all this classes are in a project called Portal.Website (Asp.net MVC3 Application) that i use as a generic website and that store common functionalities for custom websites that i will add in the future.
For other hand i have another website project with a reference to Portal.Website project called Portal.Website.MyCustomWebsite.
This is the viewmodel MyModel.cs in the generic website part:
namespace Portal.Website
{
public class MyModel
{
[Required(ErrorMessage="The field Name is required.")]
[Display("MyPropertyOriginal")]
public virtual string Name{get;set;}
}
}
This is the controller and action in the generic website part:
namespace Portal.Website
{
public class MyController: Controller
{
[HttpPost]
public ActionResult MyAction(MyModel model)
{
if(Model.IsValid)
....
//My issue: Im getting the error message in english, not the overridden one.
}
}
}
This is the viewmodel that i created in the custom part:
namespace Portal.Website.MyCustomWebsite
{
public class MyModel: MyModel
{
[Required(ErrorMessage="My error message in other language.")]
[Display("MyPropertyOverriden")]
public override string Name{get;set;}
}
}
My problem:
I would like to override the ErrorMessage of the Required attribute. For this reason i created a new Model in my custom project. For other hand i would like to use the Controller/Action (MyController/MyAction) that is already defined in my common part.
Do you know if this is possible? Im only getting the issue with the Required attribute, but with the Display one its working perfect.
Thanks in advance.
Greets.
Jose.
You may want to check out this article that suggests two possible solutions :
http://www.codeproject.com/Articles/130586/Simplified-localization-for-DataAnnotations
I've found it was making more sense to re-create some DataAnnotation classes with my custom logic.
MVC3 comes with better support for I18N (internationalisation) than it's predecessors - you can pass the RequiredAttribute the type of your resource class and the resource key and the error message will be displayed in whichever language is most appropriate:
[Required(ErrorMessageResourceType = typeof(MyResources), ErrorMessageResourceName = "ResourceKey")]
public override string Name { get; set; }

ASP.NET MVC3 Metadata problem on class named as .NET keyword

I've a problem when adding metadata to a class named as a reserved keyword. During the generation of the data model (the DBML file), an # has been added to the class name to have it working.
When I apply metadata to the class, it is not working (metadata info is not taken in consideration - the DisplayName and other validation stuff). For all other classes of my project (that do not have a class name as a reserved keyword, it is working). It is currently not possible to rename that class.
Generated class definition:
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.operators")]
public partial class #operator : INotifyPropertyChanging, INotifyPropertyChanged
{...}
MetaData class definition:
[MetadataType(typeof(OperatorMetaData))]
public partial class #operator
{
}
public class OperatorMetaData
{
[DisplayName("Operator Type")]
[Required(ErrorMessage = "Operator type is required.")]
public int operator_type_id { get; set; }
...
}
Anyone any idea how to work around this? Or what did I do wrong ?

ASP.NET MVC, Linq to SQL Data Annotation Validation

I'm trying implement Data Annotation to my Linq to SQL objects. The .dbml file is generated and I'm not sure how to add data annotation to the objects without touching the generated source code.
I tried to add data annotations to the a separate partial class of the object, but its not recognizing it, no Intelli sense either.
As I said in my original answer to this question, you should use an interface. The answer posted after mine (which was marked as Accepted) said to use a class. This is not as good. An interface is a better option for the following reasons:
If there is a mismatch between the name in your LINQ class and the name in your interface, the compiler will flag it for you
An interface can not be instantiated, so this protects class users from accidentally instatntiating the metadata type
If you use Resharper (or similar), the interface can be automatically extracted from the LINQ class
An interface is less verbose than an empty class
If you program against interfaces rather than classes (which is a good practice), then you've already got an interface you can use as your metadata type
For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:
[MetadataType(typeof(IUser))]
public class User : IUser
Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:
[Required]
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:
[MetadataType(typeof(IUser))]
public class User : IUser
Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:
[Required]
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
Linq to SQL generates object classes as partial. An easy way to implement data annotations is to create your own partial class of the object, place the [MetadataType(typeof(YourDataAnnotationClass))] on the partial class you created.
Example:
// Linq to SQL Class
public partial class Article
{
public string Title { get; set; }
...... etc
}
Create your own MetaData class with Metadata for each field you want to validate
public class MyMetaDataClass
{
[Required]
[Range(5,20)]
public string Title { get; set; }
}
Create a Partial Class for the Object class you want to add metadata to, in this case Articles class:
[MetadataType(typeof(MyMetaDataClass))]
public partial class Article { }
Note: you don't need to specify anything in the class, just the metadata type.
Thanks,but the problem is MS define the prototype of MetadataTypeAttrubute as
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class MetadataTypeAttribute : Attribute
So, you had to use class but not interface
From China
Forest Lee: 李晓强
xiaoqianglinsen#163.com (MSN)
lixiaoqiang#webservice.com.cn

Resources