2015-10-20 69 views
0

我正在使用ASP.Net身份登录的MVC网站。MVC Asp.NET身份未知错误发生

有一个用户表,其中pk是另一个表(表2)的FK。因此,用户不能被删除。同样,还有从表2生成的报告。此报告显示来自表2的数据,只要生成数据的用户名即可。不应该删除用户信息的另一个原因。

因此,而不是删除用户,我想我会添加一列到名为“已删除”的用户表。它使用了一点数据类型。

使用代码优先迁移将列添加到我的本地数据库副本。当用户登录时,在此列中检查此值被选中(0 =未删除; 1 =已删除)。

一切工作在我的本地机器很好。我没有错误,代码运行良好。我能够与任何用户登录。然后,我部署到我们的测试服务器,并使用脚本将“已删除”列添加到测试SQL服务器上的表中。

当我去用任何用户登录时,我无法登录。我不断收到“错误登录,请重新输入凭据并再次尝试”,即使我的凭据是正确的。

我删除了服务器上的文件并再次部署。一样。

我退出了我所有的变化和再部署,并能够登录 于是,我开始一次添加的东西一件:

  • 我跑的脚本添加删除柱一个位数据类型,并设置 为NOT NULL我们的测试SQL服务器
  • 测试记录上,并能
  • 增加公共BOOL删除{获得;设置;}我的BL实体并将其部署到 测试
  • 尝试登录和失败

  • 删除了已删除的布尔和重新部署

  • 能够登录在

我不明白为什么这个增加导致问题。 “已删除”列在应用程序的其他表中使用,并没有引起任何问题。而且因为当我在本地运行它时工作正常,所以我很难确定问题所在。

这里是我的BL实体:

using Microsoft.AspNet.Identity.EntityFramework; 
    using System; 
using System.Collections.Generic; 
namespace BlahBlah.BusinessLogic.Entities 
{ 
public class User : IdentityUser 
{ 
    public User() : base() { } 

    public User(string username) : base(username) { } 

    public Guid CompanyId { get; set; } 

    public Company Company { get; set; } 

    public bool PrimaryAccount { get; set; } 

    public Guid DefaultCompanyId { get; set; } 

    public ICollection<Transaction> Transactions { get; set; } 

    // public bool Deleted { get; set; } 

} 
} 

下面是一段我user.js的代码:

... 
$http(call) 
      .success(function (data) { 
       userData.isAuthenticated = true; 
       userData.username = data.userName; 
       userData.role = data.role; 
       userData.bearerToken = data.access_token; 
       userData.expirationDate = new Date(data['.expires']); 

       setHttpAuthHeader(); 

       if (typeof successCallback === 'function') { 
        successCallback(); 
       } 
      }) 
      .error(function (data) { 

       if (typeof errorCallback === 'function') { 
        if (data.error_description) { 
         errorCallback(data.error_description); 
        } 
        else { 

         errorCallback('Unable to contact server; please, try again later.'); 
        } 
       } 
      }); 
    }; 
... 

下面是一段我login.js代码:

... 
function login(common, $location, config) { 
    var getLogFn = common.logger.getLogFn; 
    var log = getLogFn(controllerId); 

    var vm = this; 

    vm.title = 'Login'; 
    vm.credentials = { 
     username: '', 
     password: '' 
    }; 
    vm.hideError = true; 
    vm.errorMessage = 'xx.'; 

    vm.login = function login() { 
     vm.hideError = true; 
     common.$broadcast(config.events.spinnerToggle, { show: true }); 
     common.user.authenticate(vm.credentials.username, vm.credentials.password, onSuccessfullLogin, onFailedLogin); 
    }; 
... 
function onFailedLogin(error) { 
     common.$broadcast(config.events.spinnerToggle, { show: false }); 
     console.log('error ' + error); 
     vm.hideError = false; 
    } 
... 

任何关于正在发生的事情或我如何能够找出发生的事情的想法?谢谢你的时间!

UPDATE 我不应该太激动。在应用程序中执行了一些测试后,我想我会测试这些报告。到目前为止,一切都很好。当我查看报告时,我收到以下错误:

The model backing the 'BabDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database

报告使用的是SSRS。如果我运行脚本来创建列并更新_Migrations表,我不明白为什么我得到这个错误。堆栈跟踪指向最后一行。我已经阅读了建议,但是我需要在OnModelCreating方法中添加一些代码,但我不确定这是否可行。在我之前还有其他人做过其他部署,所以我错过了一些东西。

public class AbaDbContext : IdentityDbContext<User>, IDbContext 
{ 
    public const int UnknownCTId = 1; 
    private IEncryptionService _encryptionService; 
    private static Dictionary<Guid, string> _cipherCache = new Dictionary<Guid,string>(); 

    public BabDbContext() 
     : base("BabDbContext") 
    { 
     ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += new ObjectMaterializedEventHandler(ObjectMaterialized); 

回答

1

它看起来像你的情况下试图运行在生产服务器上迁移,并未能对任何一方没有足够的权限或者该Deleted列已经存在。您的选项有:

  1. 通过创建脚本来运行您的生产迁移。

    Update-Database -Script 
    

    这将创建一个宥可以运行你的数据库创建列,并严格SQL脚本,插入一行到__MigrationHistory表,告诉EF它:您可以通过运行以下命令来执行此不需要再次运行迁移。

  2. 创建有效禁用迁移的上下文初始化程序。从NullDatabaseInitializer<T>添加继承一个类:

    public class DisableMigrations : NullDatabaseInitializer<YourContext> 
    { 
    } 
    

    而且在生产web.config

    <entityFramework> 
        <contexts> 
        <context type="YourNamespace.Domain.YourContext, YourNamespace.Domain"> 
         <databaseInitializer 
           type="YourNamespace.Domain.DisableMigrations, YourNamespace.Domain"/> 
        </context> 
        </contexts> 
    </entityFramework> 
    
+0

THAT做到了!我确实使用该命令来生成脚本,但我只抓取添加了“已删除”列的部分。我恢复了数据库的备份副本,并且这次使用了整个生成的脚本,并且它工作正常。非常感谢! – rsford31

+0

很高兴工作。大多数人并没有意识到迁移表实际上保存了整个EDMX模型,并且如果它与EF内部不匹配,它将再次运行迁移。 – DavidG

+0

虽然我不应该激动。我更新了我原来的问题。我最终将其添加到Reportviewer项目中的gobal.asax.cs文件中:'Database.SetInitializer (null);'。我不明白为什么我不得不这样做,因为以前的开发人员不需要做任何更改就可以做到这一点。 – rsford31