0
votes

I moved from one PC to a new PC where I had to re-install every thing including VS2017. But when I run my same project from old PC to new PC (both Windows 10) app runs fine. I then added a new model and when I run the following Package Manager console command I get the following error.

PM> add-migration myMigration -context TestProjContext

Error:

An error occurred while calling method 'ConfigureServices' on startup class 'Startup'. Consider using IDbContextFactory to override the initialization of the DbContext at design-time. Error: Could not find 'UserSecretsIdAttribute' on assembly 'ef, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. No parameterless constructor was found on 'MyProjContext'. Either add a parameterless constructor to 'MyProjContext' or add an implementation of 'IDbContextFactory' in the same assembly as 'MyProjContext'.

UPDATE

  1. This project was upgraded from VS2015 to VS2017 and hence the project.json was gone (replaced by .csproj. And if I recall correctly this is the first time since moving to VS2017 that I've run the add-migration command

Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TestProj.Data;
using TestProj.Models;
using TestProj.Services;

namespace TestProj
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

            if (env.IsDevelopment())
            {
                // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
                builder.AddUserSecrets();
            }

            builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var connection = @"Server=MyWin10Desktop;Database=MySQL2012Db;Trusted_Connection=True;";
            services.AddDbContext<TestProjContext>(options => options.UseSqlServer(connection));

            // Add framework services.
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddMvc();
            services.AddDistributedMemoryCache();
            services.AddSession();

            // Add application services.
            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseIdentity();
            app.UseSession(); //me: must come before app.UseMvc()

            // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

UPDATE 2:

TestProj.csproj file: [Note: Since app was upgraded from VS2015 to VS2017 the upgrade wizard removed the project.json and added this .csproj file instead

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <AssemblyName>ABCTest</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageId>ABCTest</PackageId>
    <UserSecretsId>aspnet-ABCTest-6af8ade3-87ff-4468-a9ce-8bb69c696ab8</UserSecretsId>
    <RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
    <PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="Properties\PublishProfiles\ABCTestP.pubxml" />
    <None Remove="Properties\PublishProfiles\FolderProfile.pubxml" />
    <None Remove="Properties\PublishProfiles\FolderProfile1.pubxml" />
  </ItemGroup>

  <ItemGroup>
    <None Update="wwwroot\**\*;Views\**\*;Areas\**\Views">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="bootstrap" Version="2.3.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration.Tools" Version="1.1.0-preview4-final" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.0">
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.AspNetCore.Session" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.1" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
    <PackageReference Include="BundlerMinifier.Core" Version="2.3.327" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="1.1.2" />
    <PackageReference Include="EPPlus.Core" Version="1.4.0" />
  </ItemGroup>

 <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
  </ItemGroup>

</Project>
1
You may be hitting this github.com/aspnet/Announcements/issues/209Smit
@Smit I think you've put me on the right track. I've just added item 1 in my UPDATE section above. The error started after I moved my web project from VS2015 to VS2017. Since I don't have project.json anymore, which section of the link - that you've provided - should I follow?nam
Which version of packages you are using? Share your csproj file.Smit
@Smit I just added the file you requested in UPDATE 2 of my post.nam
That csproj does not contain any references. Are you able to build successfully? Where are you referencing EF Core packages?Smit

1 Answers

0
votes

The relevant part is this:

No parameterless constructor was found on MyProjContext. Either add a parameterless constructor to MyProjContext or add an implementation of IDbContextFactory in the same assembly as MyProjContext

The IDbContextFactory way is the prefered way of achieving this in Entity Framework Core, because you can use the same tooling as in Startup.cs. From the EF Core documentation:

You may also provide an implementation of IDbContextFactory<TContext>. EF tools can use this factory to create an instance of your DbContext. This may be required in order to enable specific design-time experiences such as migrations. Implement this interface to enable design-time services for context types that do not have a public default constructor. Design-time services will automatically discover implementations of this interface that are in the same assembly as the derived context.

For example:

public class DbContextFactory : IDbContextFactory<MyProjContext>
{
    public MyProjContext Create()
    {
        var environmentName = Environment.GetEnvironmentVariable("Hosting:Environment");
        return Create(Directory.GetCurrentDirectory(), environmentName);
    }

    public MyProjContext Create(DbContextFactoryOptions options)
    {
        return Create(
            options.ContentRootPath,
            options.EnvironmentName);
    }

    public MyProjContext Create(string basePath, string environmentName)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(basePath)
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{environmentName}.json", true)
            .AddEnvironmentVariables();

        var Configuration = builder.Build();

        var connectionName = nameof(MyProjContext);
        var connectionString = Configuration.GetConnectionString(connectionName);
        if (String.IsNullOrWhiteSpace(connectionString) == true)
            throw new InvalidOperationException($"Could not find a connection string named '{connectionName}'.");

        // init SQL server
        var optionsBuilder = new DbContextOptionsBuilder<MyProjContext>();
        optionsBuilder.UseSqlServer(connectionString);

        return new MyProjContext(optionsBuilder.Options);
    }
}