Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity Framework Migrations issue #15

Closed
RobertTheGrey opened this issue Apr 2, 2018 · 5 comments
Closed

Entity Framework Migrations issue #15

RobertTheGrey opened this issue Apr 2, 2018 · 5 comments

Comments

@RobertTheGrey
Copy link

RobertTheGrey commented Apr 2, 2018

A bit of a strange one, but it seems that when you call:

app.UseDotNetify(config =>
            {
                // Doesn't matter what you config in here
                ...
            });

inside the Startup.cs Configure() method, it runs fine when you dotnet run it, but as soon as you call dotnet ef migrations add InitialDb then EF naturally calls the static IWebHost BuildWebHost() method and errors out on the above call with the following stack trace:

Application startup exception: System.Exception: ERROR: Assembly 'ef' does not define any view model!
   at DotNetify.VMController.RegisterAssembly[T](Assembly vmAssembly)
   at DotNetify.AppBuilderExtensions.UseDotNetify(IApplicationBuilder appBuilder, Action`1 config)
   at Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration) in C:\Dev\Projects\server\Startup.cs:line 50
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6]
      Application startup exception
System.Exception: ERROR: Assembly 'ef' does not define any view model!
   at DotNetify.VMController.RegisterAssembly[T](Assembly vmAssembly)
   at DotNetify.AppBuilderExtensions.UseDotNetify(IApplicationBuilder appBuilder, Action`1 config)
   at Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration) in C:\Dev\Projects\server\Startup.cs:line 50
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: ERROR: Assembly 'ef' does not define any view model!

The only 2 ways to get around this are to

  • comment out the app.UseDotNetify(config => part and run your migrations command and then uncomment it each time you want to add or run a migration
  • Implement an instance of IDesignTimeDbContextFactory<TContext> which basically repeats the same code as you would have in ConfigureServices() for adding SQL Server config - and if you do this, you still see the stack trace in the migration above, but it just keeps going and creates the migration anyway.

I'm guessing that DotNetify is doing some sort of assembly scanning on startup and finding an assembly called 'ef' which for some reason it expects to have a view model?

This issue is not stopping progress, but though some others might like to know the workaround. It would probably be even better if it didn't throw an exception at this stage because of the inner workings of DotNetify, but maybe I just missed something on the config?

@dsuryd
Copy link
Owner

dsuryd commented Apr 2, 2018

The app.useDotNetify automatically assumes to look for the view models in the entry assembly if none is explicitly registered. Apparently for 'dotnet migration' commands, 'ef' is the entry assembly, so in this case, the view model assembly must be explicitly registered:

app.useDotNetify(config => {
config.RegisterAssembly(...)
});

@RobertTheGrey
Copy link
Author

Thanks for the info! I'm assuming that there will be quite a lot of folks using EF with this template and DotNetify for that matter, so maybe this is something worth documenting as a known issue rather than fixing it?

I only mention it because it took me quite a while before I started looking in the right place - at first I was looking for the issue within EF itself which is quite a deep rabbit hole :-D. It was only the fact that the error message said something about the view model that led me to believe it must have something to do with DotNetify autodiscovery.

So I guess anyone using this in conjunction with EF will need to use either of the two workarounds I put in my first comment and ignore the stack trace on running migrations, or they will need to explicitly register all assemblies that contain view models then?

@dsuryd
Copy link
Owner

dsuryd commented Apr 2, 2018

This can be properly fixed by deferring the exception-throwing check until the first client-side request is received. I will put this in the next version release. Thanks!

@dsuryd
Copy link
Owner

dsuryd commented Apr 16, 2018

Fixed in the latest dotNetify release.

@dsuryd dsuryd closed this as completed Apr 16, 2018
@sachin27sharma
Copy link

i had a view model derived from BaseVM which is working fine (without adding any additional RegisterAssembly), Now when i added another viewmodel derived from BaseVM, am getting below error -
"ERROR: 'UserVm' is not a known view model! Its assembly must be registered through VMController.RegisterAssembly."

I tried with registering assembly using both by config and RegisterAssembly still same error.
NOTE - was using 2.3.0-pre version, even after upgrading to 3.0.0-pre (for both nuget and client library).

app.UseDotNetify(config =>
{
config.RegisterAssembly(GetType().Assembly);
// Middleware to do authenticate token in incoming request headers.
config.UseJwtBearerAuthentication(new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(AuthServer.SecretKey)),
ValidateIssuerSigningKey = true,
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(0)
});

        // Filter to check whether user has permission to access view models with [Authorize] attribute.
        config.UseFilter<AuthorizeFilter>();
     });

    VMController.RegisterAssembly(GetType().Assembly);

Please clarify.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants