Base solution for your next web application

Activities of "mightyit"

The "Default" connection string was set as a user secret. Once I updated it the issue was resolved.

I have downloaded a fresh Zero v6.7.0 base solution and am following the steps outlined in the getting started guide.

Once I have downloaded the project, ran yarn and npm run create-bundles, I update all my connectionstrings and run the migrator tool successfully, as can be seen from the below screenshot.

However, as soon as I run the *.Web.Mvc project, the following SqlException occurs:

System.Data.SqlClient.SqlException
  HResult=0x80131904
  Message=Invalid column name 'SubscriptionPaymentType'.
  Source=Core .Net SqlClient Data Provider
  StackTrace:
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ResultEnumerable`1.GetEnumerator()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__17`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.&lt;&gt;c__DisplayClass15_1`1.<CompileQueryCore>b__0(QueryContext qc)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at MyCompany.MySolution.Migrations.Seed.Tenants.DefaultTenantBuilder.CreateDefaultTenant() in D:\Projects\MySolution\src\MyCompany.MySolution.EntityFrameworkCore\Migrations\Seed\Tenants\DefaultTenantBuilder.cs:line 27
   at MyCompany.MySolution.Migrations.Seed.Tenants.DefaultTenantBuilder.Create() in D:\Projects\MySolution\src\MyCompany.MySolution.EntityFrameworkCore\Migrations\Seed\Tenants\DefaultTenantBuilder.cs:line 20
   at MyCompany.MySolution.Migrations.Seed.SeedHelper.SeedHostDb(MySolutionDbContext context) in D:\Projects\MySolution\src\MyCompany.MySolution.EntityFrameworkCore\Migrations\Seed\SeedHelper.cs:line 29
   at MyCompany.MySolution.Migrations.Seed.SeedHelper.WithDbContext[TDbContext](IIocResolver iocResolver, Action`1 contextAction) in D:\Projects\MySolution\src\MyCompany.MySolution.EntityFrameworkCore\Migrations\Seed\SeedHelper.cs:line 42
   at MyCompany.MySolution.Migrations.Seed.SeedHelper.SeedHostDb(IIocResolver iocResolver) in D:\Projects\MySolution\src\MyCompany.MySolution.EntityFrameworkCore\Migrations\Seed\SeedHelper.cs:line 18
   at MyCompany.MySolution.EntityFrameworkCore.MySolutionEntityFrameworkCoreModule.PostInitialize() in D:\Projects\MySolution\src\MyCompany.MySolution.EntityFrameworkCore\EntityFrameworkCore\MySolutionEntityFrameworkCoreModule.cs:line 61
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at Abp.AbpBootstrapper.Initialize()

Please advise...

Hi @ismcagdas

No, it was not marked as an embedded resource. Will give it a go to see if it fixes this issue.

Thanks for the feedback!

I have followed theGetting started guide to ensure that I install the following:

  • nodejs (v10.15.3) + npm (v6.4.1)
  • gulp - ensured I installed it globally (cli version 2.0.1 local version 3.9.1)
  • yarn (v1.13.0)
  • bundler & minifier Visual Studio extension (latest)

I then ran Yarn (twice - the first time around I received an error message), as per the guide, with the following results

Trying to run npm run create-bundles gives me the following error message

As per the following screenshots, it seems that none of my minified javascript files are generated:

Hi

I have created a solution which contains:

  • My generated base solution
  • Custom modules, on which the base solution is dependent.

My solution is organised in the following fashion:

  • Solution
    • Modules
      • MyCustomModule
        • MyCustomModule.Core.csproj
        • MyCustomModule.Core.Shared.csproj
        • MyCustomModule.EfCore.csproj
        • MyCustomModule.Application.csproj
        • MyCustomModule.Application.Shared.csproj
        • MyCustomModule.Web.csproj
          • Areas
            • App
              • Features
                • Feature K
                • Feature L
    • src (Generated base solution)
      • MyCompany.SystemName.Core.csproj
      • MyCompany.SystemName.Core.Shared.csproj
      • MyCompany.SystemName.EntityFrameworkCore.csproj
      • MyCompany.SystemName.Application.csproj
      • MyCompany.SystemName.Application.Shared.csproj
      • MyCompany.SystemName.Web.Core.csproj
      • MyCompany.SystemName.Web.Host.csproj
      • MyCompany.SystemName.Web.Mvc.csproj
        • Areas
          • App
            • Features
              • Feature X
              • Feature Y
        • Features
          • Feature A
          • Feature B
        • Some more stuff...

In our Mvc project we use Feature folders to organise our code, so that controllers, views and other portions of code that relates to a specific function is grouped together in one place.

The Razor view engine needs to know where to look for views, and as such I have reconfigured ViewLocationFormats and AreaViewLocationFormats as follows in Startup.cs of the MyCompany.SystemName.Web.Mvc.csproj project.

This has been done as follows:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    //MVC
    services.AddMvc(options =>
    {
        options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        options.Filters.Add<GlobalExceptionFilter>();
    })
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    .AddRazorOptions(options =>
    {
        // {0} - Action Name
        // {1} - Controller Name
        // {2} - Area Name
        // Replace normal view entirely
        options.ViewLocationFormats.Clear();
        options.ViewLocationFormats.Add("/Features/{1}/{0}.cshtml"); 
        options.ViewLocationFormats.Add("/Features/{1}/Views/{0}.cshtml"); 
        options.ViewLocationFormats.Add("/Features/Shared/{0}.cshtml"); 
        options.ViewLocationFormats.Add("/Features/Shared/Views/{0}.cshtml"); 
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/Areas/{2}/Features/{1}/{0}.cshtml"); 
        options.AreaViewLocationFormats.Add("/Areas/{2}/Features/{1}/Views/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Areas/{2}/Features/Shared/{0}.cshtml"); 
    });
...

This schema works correctly for views in MyCompany.SystemName.Web.Mvc.csproj. However, views contained in MyCustomModule.Web.csproj does not resolve correctly and I get the following internal server error:

Please advise....

Hi @aaron

Yes, I mean the scope of my migration.

The possible triggers for these migrations are (as far as I can see at the moment - I might be overlooking some):

  • Running the migration console app
  • Tenant creation

But I see what you are saying - I think your suggestion might work on tenant record creation.

Thanks for this!

Entity events are generic events that react to record create, update and delete events on entities. The scope of your event / UoW is thus limited.

The scope of our UoW is not limited to entity record create/update/delete for one entity at a time. The scope of our UoW is about performing schema updates and seeding across multiple entities, not a single record update.

@aaron As far as I can tell that convention is limited to entity changes (inserts, updates and deletes), not domain events.

It might also be useful, in future, to have the ability to register a MigrationProvider during the pre-initialize method of your module, which will then be invoked whenever your aplication needs to perform migrations.

For eaxample:

public class MyEfCoreModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.Migrations.Providers.Add<MyEfCoreModuleMigrationProvider>();
    }

    public override void Initialize()
    {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    }
}

This could work in a similar fashion than NavigationProviders currently does. This will remove the need for any directly-coupled code in dependent modules.

Thanks for the feedback, @ryancyq

I have considered domain events.

However, this will mean that each module migration will run asynchronously, which I think would create challenges in the following regards:

  1. Tenant database creation/migration should occur in a single transaction. I think, but am not sure, that should a portion of this happen in an event handler (asynchronously) it will not form part of the transaction / unit of work. In the event that this fails for one of the modules, it could create issues since a full rollback will not occur.
  2. User feedback - It will cause issues if the new tenant continues using the system if all module migrations has not yet completed successfully.
  3. Controlling whether all handlers and their contained migrations fired and executed successfully could become a complex affair.

But perhaps there is an easy way to address these issues that I am not seeing?

In the meantime, I have implemented it as I described above and it works for now (but suggestions for better / correct ways are always appreciated)

Showing 51 to 60 of 66 entries