EF Core Migration error: "Unable to create an object of type 'ApplicationContext'" - asp.net-core

I'm trying to do the migration with EF Core but I get an error - how can I fix this error?
PM> add-migration ini
Unable to create an object of type 'ApplicationContext'. Add an
implementation of 'IDesignTimeDbContextFactory' to
the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for
additional patterns supported at design time.

This will also happen if you have multiple start-up projects - when migrating, just select one (in VS right click Solution and Set StartUp Projects...)

I had the same issue with asp.net core 3.1.
For me, it was pretty straight forward, adding an implementation of IDesignTimeDbContextFactory to the main web project fixed the issue.
A basic implementation looks something like this:
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<YourDbContext>
{
public YourDbContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var builder = new DbContextOptionsBuilder<YourDbContext >();
var connectionString = configuration.GetConnectionString("DefaultConnection");
builder.UseSqlServer(connectionString);
return new YourDbContext(builder.Options);
}
}
Please refer to this blog post on the subject.

It is highly probably because of your default startup project:
Open Package manager console and write this command:
PM> Add-Migration -StartupProject[YourProjectPath(just press a tab all the.csproj paths will come up, and then choose your DataBaseLayer project to execute a migration for)] migrationName
In this way you don't need to again go to solution and set startup
project with your webProject whenever you finished adding a new migration.

1.Modify your code in ConfigureService with :
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
x => x.MigrationsAssembly("WebApplication")));
In command line which includes WebApplication.csproj:
dotnet ef migrations add Init

I got this error when creating a migration. In my code in the ApplicationContext constructor, I used the Database.EnsureCreated() method. Typically this method is used for small applications where you need to check for the existence of a database and create it once. When creating an application with a database that will change with new versions and using migrations, you should not use this method.

In my case, this error existed because I was applying migrations at runtime. After removing Database.Migrate(); in my code, I was able to add the new migration without errors.
By the way, I used EF Core .NET command-line interface (CLI) tools, not the Package Manager Console (I run into problems I couldn't solve when I was using the Package Manager Console, so I went for the CLI alternative, and it was worth the change).
Also, make sure you use the appropriate options to select your startup project and your target project.

I got this error when the Primary Key for the table was not set manually (with attributes or with FluentAPI) and was not determined automatically (not "Id" kayword and not "TableName" + "Id")
Stack: ASP.NET Core EF + Postgres (Npgsql)

Related

RDLC with .NET Core 5.0 throws error in production if I use expressions inside report creation, works fine in development

I'm using RDLC to create reports with my .NET Core Web API. I spent an entire week creating 3 reports using lots of expressions. Now after publishing the application on IIS every report fails with error
An error occurred during local report processing.;An unexpected error
occurred in Report Processing.Object reference not set to an instance
of an object
The report works fine in development. After lots of research I found the issue is with expressions. I have been struggling to find a solution for almost a day searching the entire web. Many people suggested that this is the limitation of RDLC and we can't use expressions. Without expressions there is no use of this tool for me. I can't afford to spend another week to re-create those reports using another tool. In fact I don't even know what else can I use instead of RDLC to create reports.
Any suggestion to fix these issues or an alternative to RDLC will be life saving for me....
It's been a pain to use this unstable tool, but unfortunately I'm stuck in this.
Thanks
Having .NET Core work with library from .NET framework is painful to say the least.
Thanks for the recompiled WinForms library provided by lkosson.
I managed to make this work but it looks like bandage fix more then anything.
Very Important Note!! This solution make use of WPF, WinForms version of RDLC. This limit the .NET 5 solution to Windows build only. (I can't make Web version to work, maybe someone else can)
1. Update .NET 5 project settings
Unload the .NET 5 project
Right click and Edit .csproj
Update/Add 3 lines in property group as following:
<PropertyGroup>
--><TargetFramework>net5.0-windows</TargetFramework>
<RootNamespace>Net_Core_5._0</RootNamespace>
--><UseWindowsForms>true</UseWindowsForms>
--><EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
Reload the project
2. Add NuGet Packages
Add and install the following packages:
Microsoft.ReportViewer.Common
Microsoft.ReportViewer.WinForms
ReportViewerCore.WinForms
3. Use .NET version's function to generate Report
This is an example for your reference,
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Data;
namespace NET_4._8_RDLC_Lib
{
public class ReportGenerator
{
/// <summary>
/// .NET Core use this function to render reports
/// </summary>
public static byte[] RenderReport(String reportPath, Dictionary<string, DataTable> data, string format)
{
Microsoft.Reporting.WinForms.ReportViewer v1 = new Microsoft.Reporting.WinForms.ReportViewer();
v1.LocalReport.DataSources.Clear();
//Add all datasource to the Report
foreach (KeyValuePair<string, DataTable> pair in data)
{
Microsoft.Reporting.WinForms.ReportDataSource ds = new ReportDataSource(pair.Key, pair.Value);
v1.LocalReport.DataSources.Add(ds);
}
v1.LocalReport.EnableExternalImages = true;
v1.LocalReport.ReportPath = reportPath;
return v1.LocalReport.Render(format: format, deviceInfo: "");
}
}
}
The file is just inside the bytes array.

Is there an option in Serilog to change log file parameters in runtime, the same way LogLevel can be changed?

With Serilog in asp.net core you can change the log level in runtine by using
MinimumLevel.ControlledBy(SeriLogLevelSwitch).
Is there a similar way to do this with LoggerConfiguration().WriteTo.File(...)
For instance i need to change the configuration for log fileSizeLimitBytes, or rollingInterval withour restaring the service. Can this be achieved with Serilog?
By pulling in the latest Serilog.AspNetCore you'll find a class called ReloadableLogger, constructed through the CreateBootstrapLogger() extension method:
// using Serilog;
var logger = new LoggerConfiguration()
.WriteTo.File(...)
.CreateBootstrapLogger();
// Optional but suggested:
Log.Logger = logger;
// Use the logger...
// Change parameters later on:
logger.Reload(lc => lc
.WriteTo.File(...));
You might find that some interactions between CreateBootstrapLogger() and UseSerilog(callback) in ASP.NET Core trip things up a bit; if you use this technique, try the parameterless version of UseSerilog().
ReloadableLogger has only just appeared and is focusing on a slightly different scenario, so you may still need to work through some awkwardness setting this up - YMMV.

System.NotSupportedException: Ambiguous HTTP method for action

I downloaded one abp .net core2.x angular solution and try to implement report using Devexpress reporting control. So I added the corresponding packages to the project. While running the projects its show that internal server error, I checked the log and found that System.NotSupportedException: Ambiguous HTTP method for action - DevExpress.AspNetCore.Reporting.QueryBuilder.QueryBuilderController.Invoke (DevExpress.AspNetCore.Reporting.v19.1). Actions require an explicit HttpMethod binding for Swagger 2.0
I tried to modify the DocInclusionPredicate. but it will not solve the issue.
I tried to modify like below,
options.DocInclusionPredicate((docName, description) =>
{
var assemblyName = ((ControllerActionDescriptor)description.ActionDescriptor).ControllerTypeInfo.Assembly.GetName().Name;
var currentAssemblyName = GetType().Assembly.GetName().Name;
return currentAssemblyName == assemblyName;
});
To reproduce the issue, Add DevExpress.AspNetCore.Reporting package to the Web.Host project and run that.
Can anyone help me out to solve this issue?

Conversion of V2 Ninject Binding to V3

I've been banging my head at this for about 8 hours now, and I just can't seem to find a simple explanation on how to change my custom bootstrapper for ninject (Last worked on the code back in v2.x.x.x) to the new v3.0.0.0 syntax.
I currently have the following:
public class NinjectCustomBootStrapper : NinjectNancyBootstrapper
{
protected override Ninject.IKernel GetApplicationContainer()
{
return Program.MyContainer;
}
}
in a septate class, and :
public static IKernel MyContainer
{
get { return _myContainer ?? (_myContainer = CreateKernel()); }
set { _myContainer = value; }
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<CardMonitorService>().ToSelf().InSingletonScope();
return kernel;
}
in my main program 'Program.c' in a command line app.
Iv'e since updated ninject to V3.0.0.0 only to find that there's been some breaking changes. I'll admit I don't use ninject very often (I usually use structuremap), and the only reason this project does is I didn't write it originally.
Since I've upgraded Ninject, now when the app is started up I get the following exception:
Method not found: 'Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax`1<!0>
Ninject.Syntax.IBindingToSyntax`1.ToConstant(!0)'.
After a ton of searching and researching, the closest I've been able to find is this:
http://sharpfellows.com/post/Ninject-Auto-registration-is-changing-in-version-3.aspx
Which while it points me in the right direction, still isn't quite a solution as I'm not using a custom binding generator.
So my question is this.
How do I rewrite the above so that my project once again works and the WCF service when called gets the correct singleton binding handed to it when a request comes in. Going back to ninject 2 is not an option, as other dependencies in the project that have been added have forced the v3 upgrade and these add new functionality that's been requested hence why I'm working on it.
For reference this is a .NET4 build, running on NancyFX with a self hosting WCF setup as a windows service using Topshelf to provide the SCM interface.
Cheers
Shawty
Addendum to clear things up a little
This is an existing project that was originally written sometime back, I've been asked to add some new features to the project.
As part of adding these new features I have been required to upgrade the version of Ninject being used from an earlier version to V3.0.0.0 as newer dependencies added to the project require the newer version of Ninject.
Under the previous V2 of Ninject the code I have given above worked fine, with no issues, since the project has had Ninject V3 added I now get the exception as described above.
I cannot go back to the earlier version of Ninject as that will mean not being able to add the new functionality that I'm adding.
From the research I've done so far the sharpfellows link above is the closest explanation of my issue that I've managed to find so far on the internet.
I don't use Ninject very often, so I've not got the background to know what's changed between V2 & V3 that (based on my research) is the cause of my issue.
I need to know how to change my code written under V2 (and shown above) so that it works under V3.
MissingMethodException is usually a deployment problem. You compile against a different assembly than you deploy. Check that you deployed the same version and same build.
So after a week or so it turns out that the problem was that the Nancy dev team broke binary comparability with the latest version of ninject (or vice versa) :-)
There is a GitHub pull request to fix this available at :
https://github.com/NancyFx/Nancy.Bootstrappers.Ninject/pull/6
However the next version 'Nancy.Bootstrapper.Ninject' 0.12 will be out on NuGet soon which will have the fix implemented.

Triggering EF migration at application startup by code

Using Entity Framework Migrations (Beta1), using Update-Database command is all good during development.
But when the application is running on some customer's server somewhere, I really want my application to automatically update it's database schema to the latest version when it's started.
Is this possible? Documentation is scarce.
They aren't providing a way to do this until RTM, at which point they have promised a command line app and a msdeploy provider.
Source: http://blogs.msdn.com/b/adonet/archive/2011/11/29/code-first-migrations-beta-1-released.aspx
Of course not being satisfied with that, the powershell command is stored in the packages directory and is plain text, it appears to just load up an assembly called EntityFramework.Migrations.Commands stored in the same directory.
Tracing through that assembly I came up with the following
public class MyContext : DbContext
{
static MyContext()
{
DbMigrationsConfiguration configuration = new DbMigrationsConfiguration() {
MigrationsAssembly = typeof(MyContext).Assembly,
ContextType = typeof(MyContext),
AutomaticMigrationsEnabled = true,
};
DbMigrator dbMigrator = new DbMigrator(configuration);
dbMigrator.Update(null);
}
}
UPDATE: after a bit of experimentation I figured out a few more things
Performing an update in the static constructor for your context is bad as it breaks the powershell commands, much better off adding the code to application startup another way (Global.asax, WebActivator or Main method)
The above code only works when using AutomaticMigrations, you need to set the MigrationsNamespace for it to pickup on manually created migrations
The configuration class I was creating should already exist in your project (added when you install the migration nuget package), so just instantiate that instead.
Which means the code is simplified to
DbMigrator dbMigrator = new DbMigrator(new NAMESPACE.TO.MIGRATIONS.Configuration());
dbMigrator.Update(null);
Another options for this issue is to add
Database.SetInitializer<MyContext>(new MigrateDatabaseToLatestVersion<MyContext, NAMESPACE.TO.MIGRATIONS.Configuration>());
line to your Global.asax Application_Start method.