AspnetBoilerplate modular: The entity type XXX is not part of the model for the current context - aspnetboilerplate

Sorry for my bad English, Could anyone help me with this error as below:
I have followed this tutorial to create a new module application (named Payment) on AspnetZero framework (named FastOne).
In the second DbContext, I change the default conn to my second database and add new entity name BankCode. After add-migration and update-database, everything works well. New database was created with 1 table name BankCode
I went to create a AppService in .Application module project as below:
public class BankCodeAppService : FastOneAppServiceBase, IBankCodeAppService
{
//from PaymentDbContext
private readonly IRepository<BankCode> _repository;
public BankCodeAppService(IRepository<BankCode> repository)
{
_repository = repository;
}
public ListResultDto<BankCodeDto> GetAllBankCodeDto()
{
try
{
var result = _repository.GetAll().ToList();
return new ListResultDto<BankCodeDto>(result.MapTo<List<BankCodeDto>>());
}
catch (Exception ex)
{
throw new NotImplementedException();
}
}
}
This is my PaymentDbContext
[DefaultDbContext]
[AutoRepositoryTypes(
typeof(IPaymentRepositoryBase<>),
typeof(IPaymentRepositoryBase<,>),
typeof(PaymentRepositoryBase<>),
typeof(PaymentRepositoryBase<,>)
)]
public class PaymentDbContext : FastOneDbContext
{
/* Define an IDbSet for each entity of the application */
public virtual IDbSet<BankCode.BankCode> BankCodes { get; set; }
//TODO: Define an IDbSet for your Entities...
public PaymentDbContext() : base("SecondConn") { }
public PaymentDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
public PaymentDbContext(DbConnection connection) : base(connection) { }
}
The api was created successfully, but when I called to it, it returned the error as below:
The entity type BankCode is not part of the model for the current
context.
I tried to debug and realize that the repository is FastOneDbContext instead of PaymentDbContext : [Wrong repository when debugging][2]
I'm totally new with AspNetBoilerplate and module Zero. So could anyone please to help me. Thank
Update: This is my PaymentRepositoryBase
namespace FastOne.EntityFramework.Repositories
{
public class PaymentRepositoryBase<TEntity, TPrimaryKey> : FastOneRepositoryBase<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
public PaymentRepositoryBase(IDbContextProvider<PaymentDbContext> dbContextProvider) : base(dbContextProvider) { }
//do not add any method here, add to the class above (since this inherits it)
}
public abstract class PaymentRepositoryBase<TEntity> : PaymentRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
public PaymentRepositoryBase(IDbContextProvider<PaymentDbContext> dbContextProvider) : base(dbContextProvider) { }
//do not add any method here, add to the class above (since this inherits it)
}
}
Update 3
Thank for your help Aaron, everything goes correctly, this is the newest error, I have searched some solutions but they didn't work. Please help
No component for supporting the service
FastOne.EntityFramework.PaymentDbContext was found
Update 4
I tried to add this method to PaymentDataModule:
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
It worked!, I can see _repository get correct context. but when i run, it raised this error:
System.Data.SqlClient.SqlException: Invalid object name
'dbo.BankCode'.
I realized that the connection was wrong. It was the connstring of the first context
Update 5: I found that I have 3 constructors in PaymentDbContext. So i removed these lines:
public PaymentDbContext() : base("LocalPaymentConn") { }
//public PaymentDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
//public PaymentDbContext(DbConnection connection) : base(connection) { }
-->It received the correct connection string. So awesome!! Thanks Aaron and Tien for all your help. Thank you

You should inject IPaymentRepositoryBase as you have specified in AutoRepositoryTypes.
public class BankCodeAppService : FastOneAppServiceBase, IBankCodeAppService
{
private readonly IPaymentRepositoryBase<BankCode> _repository;
public BankCodeAppService(IPaymentRepositoryBase<BankCode> repository)
{
_repository = repository;
}
}
Update 1
ComponentActivator: could not instantiate FastOne.EntityFramework.Repositories.PaymentRepositoryBase`1‌​[[FastOne.BankCode.B‌​ankCode, FastOne.Payment.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
Remove abstract keyword from the class declaration for PaymentRepositoryBase<TEntity>.
Update 2
Target does not implement interface FastOne.Domain.Repositories.IPaymentRepositoryBase`1[[FastOn‌​e.BankCode.BankCode, FastOne.Payment.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]\r\nParameter name: target
Make PaymentRepositoryBase implement IPaymentRepositoryBase.
public class PaymentRepositoryBase<TEntity> : PaymentRepositoryBase<TEntity, int>, IPaymentRepositoryBase<TEntity>
where TEntity : class, IEntity<int>
{
public PaymentRepositoryBase(IDbContextProvider<PaymentDbContext> dbContextProvider) : base(dbContextProvider) { }
}

You are using mutilple dbcontext in the app. So the second context must be inherit from AbpDbContext to ABP inject this correctly. See MultipleDbContextDemo example on https://github.com/aspnetboilerplate/aspnetboilerplate-samples.
Hope this will help you.

Related

Entity Framework Core - EF Core 2.2 - 'Point.Boundary' is of an interface type ('IGeometry')

I am trying the new functionality with EF Core 2.2. It is based on the following article. "Announcing Entity Framework Core 2.2"
https://blogs.msdn.microsoft.com/dotnet/2018/12/04/announcing-entity-framework-core-2-2/
I installed the following Nuget package.
I added the following to my model.
using NetTopologySuite.Geometries;
//New as of EF.Core 2.2
//[Required]
//[NotMapped]
public Point Location { get; set; }
During my application startup I get the following error in my Database Context on the following line:
Database.EnsureCreated();
System.InvalidOperationException
HResult=0x80131509
Message=The property 'Point.Boundary' is of an interface type ('IGeometry'). If it is a navigation property manually configure the relationship for this property by casting it to a mapped entity type, otherwise ignore the property using the NotMappedAttribute or 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
Source=Microsoft.EntityFrameworkCore
You need to call UseNetTopologySuite(). Example here:
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var connectionString = configuration.GetConnectionString("DefaultConnection");
optionsBuilder.UseSqlServer(connectionString, opts => opts.UseNetTopologySuite());
}
public DbSet<Test> Tests { get; set; }
}
public class Test
{
public int Id { get; set; }
public Point Location { get; set; }
}
I ran into this problem because I had a
if (!optionsBuilder.IsConfigured) around everything in my OnConfiguring. I had to remove this in order to get add-migrations to work.
As Kyle pointed out you need to call UseNetTopologySuite(), but I would call it during ConfigureServices like this:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddEntityFrameworkNpgsql()
.AddDbContext<MyDBContext>(opt =>
opt.UseNpgsql(Configuration.GetConnectionString("MyDBConnection"),
o=>o.UseNetTopologySuite()))
.BuildServiceProvider();
...
}
...
}

Unity not registering

I'm using unity in my MVC app
I have the following RegisterTypes method within my Bootstapper.cs file:
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<AccountController>(new InjectionConstructor());
container.RegisterType<IModelContext, ModelContext>();
container.RegisterType<IModelRepository, ModelRepository>();
}
I have the following controller:
public class APIScoresController : ApiController
{
private IModelRepository _repo;
public APIScoresController(IModelRepository repo)
{
_repo = repo;
}
public IEnumerable<Result> Get()
{
return _repo.GetResults();
}
}
I have the following Model Repo:
public class ModelRepository : IModelRepository
{
ModelContext _ctx;
public ModelRepository(ModelContext ctx)
{
_ctx = ctx;
}
public IQueryable<DomainClasses.Result> GetResults()
{
return _ctx.Results;
}
}
When I try to execute the GET on the APIScoresController I get the following exception:
An error occurred when trying to create a controller of type 'APIScoresController'. Make sure that the controller has a parameterless public constructor
I would have expected unity to create the required ModelContext and ModelRepository objects. Any ideas why it's not doing this?
Problem caused by web api registration needing a different version of system.web.http. I was trying to add web api to an existing mvc5 app - bad idea! I entered a form of dll hell that I hadn't experienced since days of VB6 COM. In the end my solution was to create a new solution with a web api project then retro fit the mvc project.

Dependencies waiting to be satisifed

I'm trying to abstract some simple tasks for some very simple objects.
In my domain model, there are a number of different objects which basically serve as a way to tag (classify) a "Program." The Business Logic says a program can have as many of these as its wants, but no tags of the same type (e.g., "County") can have the same name, and you can't delete a tag while it has programs linked to it.
This is built on MVC3 with S#arp 2.0.
The domain model has an abstract base class NamedEntity : Entity which defines
public string Name { get; set; }
among other properties.
Specific types extend this class to add whatever makes them unique (if anything), such as Topic, which is a heirarchical structure and so has additional properties for that.
I wanted to create INamedEntityTasks<T> where T: NamedEntity and then have a base version of this for handling routine tasks like bool CheckForDuplicateName(string Name) which would run access its INamedEntityQueries<T> object and call T FindByName(string Name)
If a subclass needed to add more rules prior to delete (e.g. a topic with children can't be deleted), then it just overrides the virtual method from the base class.
Structure:
MyProject.Infrastructure has INamedEntityQueries<T> and NamedEntityQueries<T> as well as ITopicQueries : INamedEntityQueries<Topic> and TopicQueries: NamedEntityQueries<T>, ITopicQueries
MyProject.Domain.Contracts.Tasks has INamedEntityTasks<T> and ITopicTasks : INamedEntityTasks<Topic>
MyProject.Tasks has NamedEntityTasks<T> and TopicTasks: NamedEntityTasks<Topic>, ITopicTasks
My TopicsController won't run because of a missing dependency that I can't figure out.
The exact exception is
Can't create component
'MyProject.web.mvc.controllers.topicscontroller'
as it has dependencies to be
satisfied.
MyProject.web.mvc.controllers.topicscontroller
is waiting for the following
dependencies:
Services:
- MyProject.Infrastructure.Queries.ITopicQueries
which was not registered.
- MyProject.Domain.Contracts.Tasks.ITopicTasks
which was registered but is also
waiting for dependencies.
MyProject.Tasks.TopicTasks is waiting
for the following dependencies:
Services:
- MyProject.Infrastructure.Queries.INamedEntityQueries`1[[MyProject.Domain.Topic,
MyProject.Domain, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null]]
which was not registered.
I checked the container in ComponentRegistrar with a breakpoint and it shows 3 potentially misconfigured:
"MyProject.Tasks.NamedEntityTasks`1" NamedEntityTasks`1
"MyProject.Tasks.TopicTasks" ITopicTasks / TopicTasks
"MyProject.web.mvc.controllers.topicscontroller" TopicsController`TopicsController`
Any help would be appreciated.
You don't need the IFooTasks interface, just use an abstract base class, then IFooBarTasks and IFooBazTasks will be registered with Castle Windsor by the standard ComponentRegistrar in S#arp Architecture:
public abstract class Foo
{
public void Foo1();
public void Foo2();
}
public class FooBar : Foo
{
public void FooBar1();
}
public class FooBaz : Foo
{
public void FooBaz1();
}
public interface IFooTasks
{
void Foo1();
void Foo2();
}
public interface IFooBarTasks : IFooTasks
{
void FooBar1();
}
public interface IFooBazTasks : IFooTasks
{
void FooBaz1();
}
public abstract class FooTasks : IFooTasks
{
public void Foo1()
{
// Foo1 implementation
}
public void Foo2()
{
// Foo2 implementation
}
}
public class FooBarTasks : FooTasks, IFooBarTasks
{
public void FooBar1()
{
// FooBar1 implementation
}
}
public class FooBazTasks : FooTasks, IFooBazTasks
{
public void FooBaz1()
{
// FooBaz1 implementation
}
}

Nested Server Controls

I've got a server control that contains nested server controls,
<uc1:ArticleControl runat="server">
<HeadLine></HeadLine>
<Blurb></Blurb>
<Body></Body>
</uc1:ArticleControl>
Code:
[ToolboxData("<{0}:ArticleControl runat=server></{0}:ArticleControl>")]
[ParseChildren(ChildrenAsProperties = true)]
public class ArticleControl : WebControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
public HeadLineControl HeadLine
{
get;
set;
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public BlurbControl Blurb
{
get;
set;
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public BodyControl Body
{
get;
set;
}
}
Nested control definition (applies to all nested controls):
public class HeadLineControl : ControlBase
{
public HeadLineControl() : base() { }
public HeadLineControl(Article article) : base(article) { }
Base class definition
public abstract class ControlBase : Control
{
protected Article article;
protected ControlBase() { }
protected ControlBase(Article article)
{
this.article = article;
}
The ArticleControl is responsible for writing for the individual parts of the article specified by the nested controls,
My problem is that when the Articlecontrol is created, instances of the nested server controls are created by the .NET framework using the default constructor defined for the System.Web.Ui.Control class eg:
namespace System.Web.UI
{
public class Control : IComponent, IDisposable, IParserAccessor, IUrlResolutionService, IDataBindingsAccessor, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
{
// Summary:
// Initializes a new instance of the System.Web.UI.Control class.
public Control();
I need to call or override the default behaviour of .Net to call my Control base class constructor in stead of the default .Net defined contructor. So in short, if a new instance of HeadLineControl is created, it needs to created by the ControlBase(Article article) constuctor.
Is this possible and if possible, how do I accomplish this?
I've done this in the meanwhile as a workaround, but there must be a better way?
[PersistenceMode(PersistenceMode.InnerProperty)]
public HeadLineControl HeadLine
{
get { return null; }
set
{
this.Controls.Add(new HeadLineControl(articlePage.Article)();
}
}

Issues with my MVC repository pattern and StructureMap

I have a repository pattern i created on top of the ado.net entity framework. When i tried to implement StructureMap to decouple my objects, i kept getting StackOverflowException (infinite loop?). Here is what the pattern looks like:
IEntityRepository where TEntity : class
Defines basic CRUD members
MyEntityRepository : IEntityRepository
Implements CRUD members
IEntityService where TEntity : class
Defines CRUD members which return common types for each member.
MyEntityService : IEntityService
Uses the repository to retrieve data and return a common type as a result (IList, bool and etc)
The problem appears to be with my Service layer. More specifically with the constructors.
public PostService(IValidationDictionary validationDictionary)
: this(validationDictionary, new PostRepository())
{ }
public PostService(IValidationDictionary validationDictionary, IEntityRepository<Post> repository)
{
_validationDictionary = validationDictionary;
_repository = repository;
}
From the controller, i pass an object that implements IValidationDictionary. And i am explicitly calling the second constructor to initialize the repository.
This is what the controller constructors look like (the first one creates an instance of the validation object):
public PostController()
{
_service = new PostService(new ModelStateWrapper(this.ModelState));
}
public PostController(IEntityService<Post> service)
{
_service = service;
}
Everything works if i don't pass my IValidationDictionary object reference, in which case the first controller constructor would be removed and the service object would only have one constructor which accepts the repository interface as the parameter.
I appreciate any help with this :) Thanks.
It looks like the circular reference had to do with the fact that the service layer was dependent on the Controller's ModelState and the Controller dependent on the Service layer.
I had to rewrite my validation layer to get this to work. Here is what i did.
Define generic validator interface like below:
public interface IValidator<TEntity>
{
ValidationState Validate(TEntity entity);
}
We want to be able to return an instance of ValidationState which, obviously, defines the state of validation.
public class ValidationState
{
private readonly ValidationErrorCollection _errors;
public ValidationErrorCollection Errors
{
get
{
return _errors;
}
}
public bool IsValid
{
get
{
return Errors.Count == 0;
}
}
public ValidationState()
{
_errors = new ValidationErrorCollection();
}
}
Notice that we have an strongly typed error collection which we need to define as well. The collection is going to consist of ValidationError objects containing the property name of the entity we're validating and the error message associated with it. This just follows the standard ModelState interface.
public class ValidationErrorCollection : Collection<ValidationError>
{
public void Add(string property, string message)
{
Add(new ValidationError(property, message));
}
}
And here is what the ValidationError looks like:
public class ValidationError
{
private string _property;
private string _message;
public string Property
{
get
{
return _property;
}
private set
{
_property = value;
}
}
public string Message
{
get
{
return _message;
}
private set
{
_message = value;
}
}
public ValidationError(string property, string message)
{
Property = property;
Message = message;
}
}
The rest of this is StructureMap magic. We need to create validation service layer which will locate validation objects and validate our entity. I'd like to define an interface for this, since i want anyone using validation service to be completely unaware of the StructureMap presence. Besides, i think sprinkling ObjectFactory.GetInstance() anywhere besides the bootstrapper logic a bad idea. Keeping it centralized is a good way to insure good maintainability. Anyway, i use the decorator pattern here:
public interface IValidationService
{
ValidationState Validate<TEntity>(TEntity entity);
}
And we finally implement it:
public class ValidationService : IValidationService
{
#region IValidationService Members
public IValidator<TEntity> GetValidatorFor<TEntity>(TEntity entity)
{
return ObjectFactory.GetInstance<IValidator<TEntity>>();
}
public ValidationState Validate<TEntity>(TEntity entity)
{
IValidator<TEntity> validator = GetValidatorFor(entity);
if (validator == null)
{
throw new Exception("Cannot locate validator");
}
return validator.Validate(entity);
}
#endregion
}
I'm going to be using validation service in my controller. We could move it to the service layer and have StructureMap use property injection to inject an instance of controller's ModelState to the service layer, but i don't want the service layer to be coupled with ModelState. What if we decide to use another validation technique? This is why i'd rather put it in the controller. Here is what my controller looks like:
public class PostController : Controller
{
private IEntityService<Post> _service = null;
private IValidationService _validationService = null;
public PostController(IEntityService<Post> service, IValidationService validationService)
{
_service = service;
_validationService = validationService;
}
}
Here i am injecting my service layer and validaton service instances using StructureMap. So, we need to register both in StructureMap registry:
ForRequestedType<IValidationService>()
.TheDefaultIsConcreteType<ValidationService>();
ForRequestedType<IValidator<Post>>()
.TheDefaultIsConcreteType<PostValidator>();
That's it. I don't show how i implement my PostValidator, but it's simply implementing IValidator interface and defining validation logic in the Validate() method. All that's left to do is call your validation service instance to retrieve the validator, call the validate method on your entity and write any errors to ModelState.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "PostId")] Post post)
{
ValidationState vst = _validationService.Validate<Post>(post);
if (!vst.IsValid)
{
foreach (ValidationError error in vst.Errors)
{
this.ModelState.AddModelError(error.Property, error.Message);
}
return View(post);
}
...
}
Hope i helped somebody out with this :)
I used a similar solution involving a generic implementor of IValidationDictionary uses a StringDictionary and then copied the errors from this back into the model state in the controller.
Interface for validationdictionary
public interface IValidationDictionary
{
bool IsValid{get;}
void AddError(string Key, string errorMessage);
StringDictionary errors { get; }
}
Implementation of validation dictionary with no reference to model state or anything else so structuremap can create it easily
public class ValidationDictionary : IValidationDictionary
{
private StringDictionary _errors = new StringDictionary();
#region IValidationDictionary Members
public void AddError(string key, string errorMessage)
{
_errors.Add(key, errorMessage);
}
public bool IsValid
{
get { return (_errors.Count == 0); }
}
public StringDictionary errors
{
get { return _errors; }
}
#endregion
}
Code in the controller to copy the errors from the dictionary into the model state. This would probably be best as an extension function of Controller.
protected void copyValidationDictionaryToModelState()
{
// this copies the errors into viewstate
foreach (DictionaryEntry error in _service.validationdictionary.errors)
{
ModelState.AddModelError((string)error.Key, (string)error.Value);
}
}
thus bootstrapping code is like this
public static void BootstrapStructureMap()
{
// Initialize the static ObjectFactory container
ObjectFactory.Initialize(x =>
{
x.For<IContactRepository>().Use<EntityContactManagerRepository>();
x.For<IValidationDictionary>().Use<ValidationDictionary>();
x.For<IContactManagerService>().Use<ContactManagerService>();
});
}
and code to create controllers is like this
public class IocControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (Controller)ObjectFactory.GetInstance(controllerType);
}
}
Just a quick query on this. It's helped me out quite a lot so thanks for putting the answer up, but I wondered which namespace TEntity exists in? I see Colletion(TEntity) needs System.Collections.ObjectModel. My file compiles without anything further but I see your TEntity reference highlighted in Blue which suggests it has a class type, mine is Black in Visual Studio. Hope you can help. I'm pretty keen to get this working.
Have you found any way to seperate validation into the service layer at all? My gut tells me that validating in the Controller is a bit smelly but I've looked high and low to find a way to pass validation error messages back to the controller without tightly coupling the service layer to the controller and can't find anything. :(
Again, thanks for the great post!
Lloyd

Resources