コード例 #1
0
        public virtual async Task Invoke([NotNull] HttpContext context)
        {
            Check.NotNull(context, "context");

            try
            {
#if !DNXCORE50
                // TODO This probably isn't the correct place for this workaround, it
                //      needs to be called before anything is written to CallContext
                // http://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx
                System.Configuration.ConfigurationManager.GetSection("system.xml/xmlReader");
#endif
                _loggerProvider.Logger.StartLoggingForCurrentCallContext();

                await _next(context);
            }
            catch (Exception ex)
            {
                try
                {
                    if (ShouldDisplayErrorPage(_loggerProvider.Logger.LastError, ex, _logger))
                    {
                        var dbContextType = _loggerProvider.Logger.LastError.ContextType;
                        var dbContext = (DbContext)context.RequestServices.GetService(dbContextType);
                        if (dbContext == null)
                        {
                            _logger.LogError(Strings.FormatDatabaseErrorPageMiddleware_ContextNotRegistered(dbContextType.FullName));
                        }
                        else
                        {
                            var creator = dbContext.GetService<IDatabaseCreator>() as IRelationalDatabaseCreator;
                            if (creator == null)
                            {
                                _logger.LogVerbose(Strings.DatabaseErrorPage_NotRelationalDatabase);
                            }
                            else
                            {
                                var databaseExists = creator.Exists();

                                var historyRepository = dbContext.GetService<IHistoryRepository>();
                                var migrationsAssembly = dbContext.GetService<IMigrationsAssembly>();
                                var modelDiffer = dbContext.GetService<IMigrationsModelDiffer>();

                                var appliedMigrations = historyRepository.GetAppliedMigrations();
                                var pendingMigrations = (
                                        from m in migrationsAssembly.Migrations
                                        where !appliedMigrations.Any(
                                            r => string.Equals(r.MigrationId, m.Id, StringComparison.OrdinalIgnoreCase))
                                        select m.Id)
                                    .ToList();

                                var pendingModelChanges = modelDiffer.HasDifferences(migrationsAssembly.ModelSnapshot?.Model, dbContext.Model);

                                if ((!databaseExists && pendingMigrations.Any()) || pendingMigrations.Any() || pendingModelChanges)
                                {
                                    var page = new DatabaseErrorPage();
                                    page.Model = new DatabaseErrorPageModel(dbContextType, ex, databaseExists, pendingModelChanges, pendingMigrations, _options);
                                    await page.ExecuteAsync(context);
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError(Strings.DatabaseErrorPageMiddleware_Exception, e);
                }

                throw;
            }
        }
コード例 #2
0
        private static async Task<string> ExecutePage(DatabaseErrorPageOptions options, DatabaseErrorPageModel model)
        {
            var page = new DatabaseErrorPage();
            var context = new Mock<HttpContext>();
            var response = new Mock<HttpResponse>();
            var stream = new MemoryStream();

            response.Setup(r => r.Body).Returns(stream);
            context.Setup(c => c.Response).Returns(response.Object);

            page.Model = model;

            await page.ExecuteAsync(context.Object);
            var content = Encoding.ASCII.GetString(stream.ToArray());
            return content;
        }
コード例 #3
0
        public virtual async Task Invoke([NotNull] HttpContext context)
        {
            Check.NotNull(context, "context");

            try
            {
#if !DNXCORE50
                // TODO This probably isn't the correct place for this workaround, it
                //      needs to be called before anything is written to CallContext
                // http://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx
                System.Configuration.ConfigurationManager.GetSection("system.xml/xmlReader");
#endif
                _loggerProvider.Logger.StartLoggingForCurrentCallContext();

                await _next(context);
            }
            catch (Exception ex)
            {
                try
                {
                    if (ShouldDisplayErrorPage(_loggerProvider.Logger.LastError, ex, _logger))
                    {
                        var dbContextType = _loggerProvider.Logger.LastError.ContextType;
                        var dbContext = (DbContext)context.RequestServices.GetService(dbContextType);
                        if (dbContext == null)
                        {
                            _logger.LogError(Strings.FormatDatabaseErrorPageMiddleware_ContextNotRegistered(dbContextType.FullName));
                        }
                        else
                        {
                            if (!(dbContext.Database is RelationalDatabase))
                            {
                                _logger.LogVerbose(Strings.DatabaseErrorPage_NotRelationalDatabase);
                            }
                            else
                            {
                                var databaseExists = dbContext.Database.AsRelational().Exists();

                                var migrator = ((IAccessor<IMigrator>)dbContext.Database).Service;

                                var pendingMigrations = migrator.GetUnappliedMigrations().Select(m => m.Id);

                                var pendingModelChanges = migrator.HasPendingModelChanges();

                                if ((!databaseExists && pendingMigrations.Any()) || pendingMigrations.Any() || pendingModelChanges)
                                {
                                    var page = new DatabaseErrorPage();
                                    page.Model = new DatabaseErrorPageModel(dbContextType, ex, databaseExists, pendingModelChanges, pendingMigrations, _options);
                                    await page.ExecuteAsync(context);
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError(Strings.DatabaseErrorPageMiddleware_Exception, e);
                }

                throw;
            }
        }