Automatically execute migrations when publishing ASP.NET Core app - asp.net-core

Question
Is there any ways that I can automatically execute the migration code (EF 7) when publishing my ASP 5 application to IIS using Web Deploy?
I Tried
in the project.json, I added this code in the scripts:
"scripts" : {
"prepublish": ["dnx ef database update", "other commands..."],
"postpublish": ["dnx ef database update"]
}
none worked for me.
Additional Info
I followed the instructions on this link to deploy my ASP 5 RC-1 web application to IIS using web deploy.
After doing so in the publish settings I have:
Using web deploy in ASP 4 applications I have additional database options:

Use context.Database.Migrate()
You can call this from your Startup class:
using (var context = new MyContext(...))
{
context.Database.Migrate();
}
It will migrate your database to the latest version on application startup. But be careful doing it, maybe comment out this code and uncommend only when you want to run your migrations.

Apparently this process does not work now. https://github.com/aspnet/Home/issues/622 After you publish you should find the power shell script with the name of "profile name"-publish.ps1. Then add your commands below these three lines close to the end of this file. You might want to use powershell to make it easier to debug.
'Calling Publish-AspNet' | Write-Verbose
# call Publish-AspNet to perform the publish operation
Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput

So I added the option -environment to my ef database command. Now it works:
"postpublish": ["dnx ef database update -e Staging"]
I have four different appsettings.json which different connection string for each environment. Just needed to indicate the environment for the command to work.

In you Startup.cs class add this code
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<AppDBContext>();
context.Database.Migrate();
}
}

Related

ASP.NET Core Adding View Parameter Name Path Cannot Be Null Error

I'm trying add view to my ASP.NET Core MVC project and I'm getting an error.
The error message is
There was an error running the selected code generator:
'Value cannot be null.
Parameter name:path'
The view is going to use for ViewComponent.
My steps are
Right click ->
Add View ->
Type View Name ->
Uncheck 'Use a Layout Page' ->
Template : Empty ->
Click Add.
I searched about it but can't find any result.
EDIT :
Here is a Startup.cs
namespace Udemy.MvcWebUI
{
public class Startup
{
// This method gets called by the runtime. Use this method to add
//services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IUsersService, UsersManager>();
services.AddScoped<IUsersDAL, EFUsersDAL>();
services.AddScoped<IUsersInfoService, UsersInfoManager>();
services.AddScoped<IUsersInfoDAL, EFUsersInfoDAL>();
services.AddScoped<IEventTypesService, EventTypesManager>();
services.AddScoped<IEventTypesDAL, EFEventTypesDAL>();
services.AddScoped<IEventsService, EventsManager>();
services.AddScoped<IEventsDAL, EFEventsDAL>();
services.AddScoped<ICityService, CityManager>();
services.AddScoped<ICityDAL, EFCityDAL>();
services.AddScoped<IDistrictService, DistrcitManager>();
services.AddScoped<IDistrictDAL, EFDistrictDAL>();
services.AddDbContext<EventContext>(options => options.UseSqlServer(#"Server=localhost\SQLEXPRESS;Database=Events;
User Id=sa;Password=Omurcan.1994;"));
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseFileServer();
app.UseNodeModules(env.ContentRootPath);
app.UseMvcWithDefaultRoute();
// db tanimi icin
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<EventContext>();
context.Database.EnsureCreated();
}
}
}
}
How can I fix it ?
Thanks for your help.
May be Microsoft.VisualStudio.Web.CodeGeneration.Design package is missing in your project!
Install the correct version of Microsoft.VisualStudio.Web.CodeGeneration.Design nuget package according to your project .NET Core version.
Then if you recently updated your project to .NET Core 2.1 from any lower version then update your project's packages to latest version also.
Then don't forget to Download the latest stable version (2.1.500) of .NET Core SDK and install on your machine.
Hope your problem will be solved!
I had a similar issue. It is not working for you because your NuGet package manager is not able to download the Microsoft.VisualStudio.Web.CodeGeneration.Design package. This is happening because you are either not connected to the internet or your NuGet is not configured properly.
You have two options:
1. Configure NuGet:
Tools->NuGet Package Manager->Package Manager Settings
Under NuGet Package Manager dropdown, click Package Sources. Click the green plus to add another source. Name it nuget.org, and define the Source as https://api.nuget.org/v3/index.json
Hit Update and then click OK. Next time you try to add a Razor Page the way you were previously doing (by right clicking Pages->Add->Razor Page), it will automatically download the correct package.
2. Add a Razor Page the traditional way
Right click on Pages->Add->New Item->Razor Page
This way does not required the NuGet package specified above.

Migrations are not being applied

I am trying to apply migrations programmatically using Entity Framework Core 2.0, in a Code-First ASP.Net Core 2.0 project. If I run the migrations manually through a terminal, they're applied without issue. Applying the migrations in my Startup class though results in the database model never changing.
Am I doing this wrong?
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddEntityFrameworkSqlite();
services.AddDbContext<ApplicationContext>(options => options.UseSqlite("Data Source=blogging.db"));
services.AddDbContext<UserContext>(options => options.UseSqlite("Data Source=blogging.db"));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
var services = app.ApplicationServices.GetService<IServiceScopeFactory>();
var context = services.CreateScope().ServiceProvider.GetRequiredService<ApplicationContext>();
context.Database.Migrate();
}
I can run this from the terminal and it works fine:
dotnet ef migrations add FourthMigration --context EFCore_Test.DataAccess.ApplicationContext
I have multiple DataContext Types; only one represents the entire data model and the rest are used just to access the database in a more domain specific manor. The ApplicationContext represents my "everything + kitchen sink" data context. It's this context that I perform my migrations and updates with.
In preparation for deploying to Azure, I want to have the web-app migrate itself with each deployment, instead of having to wire up powershell scripts to run the dotnet core tooling commands.
The new Migration files aren't picked up and added to the solution explorer in Visual Studio for macOS. I originally didn't think anything of this because I assumed the IDE was using dotnet build under the hood, which would pick up the migration files. I'm not sure what the IDE does, but when I build with those migration files missing, they're not included in the compiled assembly. This would cause the app to never migrate on startup.
I manually added the migration classes in the Solution Explorer, then ran the app and the migration was applied. I repeated this several times with multiple migrations and never had another issue.

Migrations in separate assembly how to avoid hardcoded connection string?

I'm writing ASP.NET Core and Entity Framework Core application and I want to store my data access layer in separate assembly, so I followed this tutorial: http://www.michael-whelan.net/ef-core-101-migrations-in-separate-assembly/
But I would also like to avoid hardcoding connection string. I tried to store it in JSON config file or as environment variable and get it using ConfigurationBuilder but when using command line migration tool dotnet ef migrations none of these are available.
Is there any way to solve this problem? I'm using 1.0.1 versions of both .NET Core and EF Core.
To solve this issue I create a class library only for migration with a DbContext deriving from my DbContext but with hard connected connection string.
using Microsoft.EntityFrameworkCore;
namespace ChatLe.Repository.Identity.SqlServer
{
public class ChatLeIdentityDbContext: ChatLe.Models.ChatLeIdentityDbContext
{
public ChatLeIdentityDbContext()
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=chatle;Trusted_Connection=True;MultipleActiveResultSets=true");
base.OnConfiguring(optionsBuilder);
}
}
}
Then I launch ef tool command like this :
To add a migration run dotnet ef --startup-project {path to my startup project} migrations add login-activity --context ChatLe.Repository.Identity.SqlServer.ChatLeIdentityDbContext
To upgrade the database run dotnet ef --startup-project {path to my startup project} database update --context ChatLe.Repository.Identity.SqlServer.ChatLeIdentityDbContext
Read the full sample on my git hub project : https://github.com/aguacongas/chatle/tree/develop/src/ChatLe.Repository.Identity.SqlServer

Use web project config.json when doing integration testing

I am using ASP.NET 5 RC1 and I need to write integration tests ...
So on the Test project, ASPNET5_WEB_TEST, I have the following:
public class IntegrationTests {
private readonly TestServer _server;
private readonly HttpClient _client;
public IntegrationTests() {
_server = new TestServer(TestServer.CreateBuilder().UseStartup<Startup>());
_client = _server.CreateClient();
}
// Test methods ...
}
The Startup class is from the ASP.NET 5 project I am testing: ASPNET5_WEB
When I run the test I get the following error:
The configuration file 'C:\Projects\ASPNET5_TEST\config.json' was not found and is not optional.
I know I get this error because on Startup I have:
builder
.AddJsonFile("config.json", false)
.AddJsonFile($"config.{environment.EnvironmentName}.json", true);
To fix this error I need to copy, at least, config.json from my web project, ASPNET5_WEB, to my test project, ASPNET5_WEB_TEST. But this means I will need to maintain duplicate config.json or at least copy it every time I make a change.
Can't I tell TestServer to use Startup of the web project and also its config.*.json files?
And can I have a config.testing.json and set on the TestServer the environment to Testing so the Startup code uses config.json and config.testing.json?
I assume you're using the TestServer from aspnet, if so, it wasn't built to support the way you're config files are read. The TestServer is used to run simple integration tests for their "hosting engine" but not for integrations tests for a website.
Their ApplicationDeployerFactory class is what you can use however. Refer to this as an example of how to run an "integration" server. I've used selenium in conjunction with that to run integration tests against the project I'm working on atm.
Yes, you can.
Take a look at this issue https://github.com/aspnet/Mvc/issues/3410 and The mentioned package.
Basically you need to implement your own IApplicationEnvironment

VS2012 Entity Framework Error

I have a MCV 4.5 solution with 3 projects. Site, Testing and Model. Site and Model are referencing EF 5.0. I have searched all solution files for a reference to 4.3.1 and have come up empty. I have deleted and recreated all references to EF 5.0
I have a HomeControllerTest.cs that runs just fine.
using this as a test
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.AreEqual("Modify this template to jump-start your ASP.NET MVC application.", result.ViewBag.Message);
}
I Created a new LOBControllerTest.cs to support the LOBController.cs in the Site Project. This test class fails with the error 'Could not load file or assembly 'EntityFramework, Version=4.3.1.0' using the following test
[TestMethod]
public void Index()
{
// Arrange
LOBController controller = new LOBController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
If I change the above test to execute the HomeController as in the following, it runs just fine.
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
This is a brand new clean install of VS2012 on a clean install of Windows Server 2012.
Any Thoughts?
Update, I forgot to mention I am also using ReSharper 7.1. I'm wondering if that has a setting that I was missing.
I found that there is a documented bug with RS7 stackoverflow.com/questions/12357696/… so I disabled the RS7 testing suite and tried running it directly from VS2012 interface with the same result. So it's not isolated to RS7.
Update:
here's a link https://www.dropbox.com/sh/740w2jsp8i1mslg/pWiwnSewHQ to access this project for anyone who want's to take a look at it. It's nothing special it's just a Template project. We are starting on a new project at work and I'm new to MVC and Test Driven Development so I'm trying to get a head start.
Update 9/21/2012
I believe I've found it. After talking to the Dev who put the original Wholesale template solution together I found that the Repositories folder in the Wholesale.Admin is references a NUGet code package. I checked the package site and found that the latest release is dependent on EF 4.3.1
Update:
This is confirmed. I no longer get the error after downloading and upgrading the solution from the site. I get another error but the 4.3.1 is no longer an issue. Hope the dev will update his NuGet solution, he hasn't updated it in 7 months.
Obviously your LOBController references EF 4.3 somehow, somewhere. Check your references in the class library containing this controller, or maybe a dll that's still in the bin folder or in the GAC...
Hope this helps
After talking to the Dev who put the original Wholesale template solution together I found that the Repositories folder in the Wholesale.Admin references a NUGet code package. I checked the package site and found that the latest release is dependent on EF 4.3.1. I downloaded the source and recompiled referencing EF 5.0 and that cleared the 4.3.1 error