“使用ASP.NET标识创建模型时不能使用上下文”

时间:2014-01-24 23:15:39

标签: c# asp.net multithreading entity-framework asp.net-identity

当我们调用AccountApiController.Register()方法时,为什么会发生这种情况?

  • 试图使用上下文的是什么?
  • 试图创建上下文的是什么?
  • 我们如何避免这种情况?
  • 我们如何调试?
  

“消息”:“发生了错误。”,

     

“ExceptionMessage”:“模型时不能使用上下文   被创造。如果使用上下文,则可能抛出此异常   在OnModelCreating方法内部或者相同的上下文实例   由多个线程同时访问。请注意实例成员   DbContext和相关类不保证是线程   安全“。,

     

“ExceptionType”: “System.InvalidOperationException”,

     

“StackTrace”:“

     

在System.Web.Http.ApiController.d__1.MoveNext()

     

---从抛出异常的先前位置开始的堆栈跟踪结束

     

在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)

     

在System.Runtime.CompilerServices.TaskAwaiter   .HandleNonSuccessAndDebuggerNotification(任务>任务)

     

at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext()“

6 个答案:

答案 0 :(得分:25)

如果connectionString不正确,也会发生此错误。检查connectionString是否有效(没有拼写错误等)。

答案 1 :(得分:23)

问题是我们没有使用MS recommends的工厂模式。

  

您可以使用Factory实现来获取UserManager的实例   来自OWIN的背景。 ...这是获取实例的推荐方法   每个应用程序请求的UserManager。

因此,“同时由多个线程访问相同的上下文实例”,因为多个请求和线程共享一个DbContext。

以下是正确的。它为每次调用UserManagerFactory函数创建一个新的MyDbContext实例。

UserManagerFactory 
= () => new UserManager<IdentityUser>(new UserStore<IdentityUser>(new MyDbContext()));

以下内容不正确。它看起来类似,但不会为每次调用UserManagerFactory创建新实例。这是我们正在使用的,因为我们的网站已经破坏了。

var userStore = new UserStore<IdentityUser>(new MyDbContext());                    
var userManager = new UserManager<IdentityUser>(userStore);
UserManagerFactory = () => userManager;

答案 2 :(得分:1)

您是否覆盖了OnModelCreating方法?如果是这样,你可以分享它或整个上下文类吗?

如果没有,您应该注意错误信息中的以下内容

  

或者同时由多个线程访问相同的上下文实例。请注意,DbContext和相关类的实例成员不保证是线程安全的。

如果这没有帮助,您是否使用由Visual Studio创建的未更改的Web API项目?

答案 3 :(得分:0)

我在使用MySQL的多层架构中使用EF Code First并且具有相同的异常,并且在DBContext类结构中使用以下行:

Database.SetInitializer<EntitiesName>(null);

答案 4 :(得分:0)

我同意 Shaun Luttin 的主要回答,但

在我的情况下:部署后出现此错误,我发现原因是在插入SSL证书后使用了Hsts预加载。取消注释此行即可解决重定向,并且可以彻底解决此错误

public MainDialog(ILogger<MainDialog> logger, IBotServices botServices, UserState userState) : 
     base(nameof(MainDialog))
{ _botServices = botServices;// ?? throw new System.ArgumentNullException(nameof(botServices));
   _logger = logger;
        _userState = userState;
        AddDialog(new ProductIssue($"{nameof(MainDialog)}.fromMain", _botServices, _userState));
        AddDialog(new ProductIssue($"{nameof(Confirm)}.fromConfirm", _botServices, _userState));
        AddDialog(new ProductIssue($"{ nameof(Resolution)}.resolution", _botServices, _userState));
        AddDialog(new PurchaseFlow(_userState));
        AddDialog(new Resolution( _userState));
        AddDialog(new Confirm(_botServices,_userState));
        AddDialog(new ChoicePrompt($"{nameof(MainDialog)}.issue"));
        AddDialog(new TextPrompt($"{nameof(MainDialog)}.callDialog"));
        AddDialog(new TextPrompt($"{nameof(MainDialog)}.number", ValidationAsync));


        AddDialog(new WaterfallDialog($"{nameof(MainDialog)}.mainFlow", new WaterfallStep[]
        {
            MoblieNumberAsync,
            ChoiceCardStepAsync,
            ShowCardStepAsync,
            CallingDialogsAsync
      }));
        AddDialog(new TextPrompt(nameof(TextPrompt)));

        InitialDialogId = $"{nameof(MainDialog)}.mainFlow";

    }

    private async Task<DialogTurnResult> MoblieNumberAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        stepContext.Values[UserInfo] = new UserInput();
        var options = new PromptOptions()
        {
            Prompt = MessageFactory.Text("Kindly enter your 10 digit mobile number without any spaces, dashes and country code. We will be sending an OTP later to this number "),
            RetryPrompt = MessageFactory.Text("Incorrect mobile number entered. Please only enter the 10 digits of your mobile without any spaces, dashes and country code.")
        };     

        return await stepContext.PromptAsync($"{nameof(MainDialog)}.number", options, cancellationToken);
    }

    private async Task<DialogTurnResult> ChoiceCardStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {

        var userStateAccessors = _userState.CreateProperty<UserInput>(nameof(UserInput));
        var userinfo = await userStateAccessors.GetAsync(stepContext.Context, () => new UserInput());
        userinfo.phone_no = (string)stepContext.Result;
        CustomerDetails customerDetails = new CustomerDetails();

        //API-Get Customer Details from CRM
        try
        {
            BotAPIBLL botApiBLL = new BotAPIBLL();
            var response = botApiBLL.GetCustomerDetail(stepContext.Context.Activity.Text); 
            customerDetails = JsonConvert.DeserializeObject<CustomerDetails>(response);               
        }
        catch(Exception ex)
        {

        }
        await stepContext.Context.SendActivityAsync(MessageFactory.Text("Fetching your details from our systems. This may take a moment"), cancellationToken);

        if (customerDetails.D != null && !string.IsNullOrEmpty(customerDetails.D.TelNumber) && !string.IsNullOrEmpty(customerDetails.D.NameFirst))
        {
            DbConnection dbConnection = new DbConnection();
            dbConnection.SaveCutomerInfo(customerDetails);

            userinfo.Name = customerDetails.D.NameFirst;
            var options = new PromptOptions()
            {

                Prompt = MessageFactory.Text("Welcome " + customerDetails.D.NameFirst + ", How can we serve you ? "),
                RetryPrompt = MessageFactory.Text("That was not a valid choice, please select a option between 1 to 5."),
                Choices = GetChoices(),
                Style = ListStyle.HeroCard
            };
            return await stepContext.PromptAsync($"{nameof(MainDialog)}.issue", options, cancellationToken);
        }
        else
        {
            var options = new PromptOptions()
            {
                Prompt = MessageFactory.Text("Welcome Guest_" + userinfo.phone_no + ", How can we serve you ? "),
                RetryPrompt = MessageFactory.Text("That was not a valid choice, please select a option between 1 to 5."),
                Choices = GetChoices(),
                Style = ListStyle.HeroCard
            };
            return await stepContext.PromptAsync($"{nameof(MainDialog)}.issue", options, cancellationToken);
        }
    }

    private async Task<DialogTurnResult> ShowCardStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        var userinfo = (UserInput)stepContext.Values[UserInfo];
        userinfo.choiceselected = ((FoundChoice)stepContext.Result).Value;
        var attachments = new List<Attachment>();
        var reply = MessageFactory.Text("");
        var user_choice = ((FoundChoice)stepContext.Result).Value;

        switch (user_choice)
        {
            case "Product issue":
                reply.Attachments.Add(Cards.CreateAdaptiveCardAttachment3());
                break;
            case "Register Product":
                reply.Attachments.Add(Cards.GetHeroCard1().ToAttachment());
                break;
            case "Online Purchase":
                return await stepContext.BeginDialogAsync(nameof(PurchaseFlow), null, cancellationToken);
            case "Customer Grivance":
                reply.Attachments.Add(Cards.GetHeroCard3().ToAttachment());
                break;
            case "Order Status":
                reply.Attachments.Add(Cards.GetHeroCard6().ToAttachment());
                break;
            default:
                reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
                reply.Attachments.Add(Cards.CreateAdaptiveCardAttachment3());
                reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
                reply.Attachments.Add(Cards.GetHeroCard1().ToAttachment());
                break;
        }
        if (user_choice == "Register Product" || user_choice == "Online Purchase" || user_choice == "Customer Grivance")
        {
            await stepContext.Context.SendActivityAsync(reply, cancellationToken);
            Random r = new Random();
            var validationcard = Cards.CreateAdaptiveCardAttachment2(_cards[r.Next(_cards.Length)]);
            //var feedbackcard = Cards.CustomerFeedback();
            await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(validationcard), cancellationToken);
            //await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(feedbackcard), cancellationToken);
            var accessor = _userState.CreateProperty<UserInput>(nameof(UserInput));
            await accessor.SetAsync(stepContext.Context, userinfo, cancellationToken);
            return await stepContext.EndDialogAsync(null, cancellationToken);
        }
        else
        {
            var options2 = new PromptOptions() { Prompt = reply, RetryPrompt = MessageFactory.Text("Retry") };                
            return await stepContext.PromptAsync($"{nameof(MainDialog)}.callDialog", options2, cancellationToken);
        }
    }

    private async Task<DialogTurnResult> CallingDialogsAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {                      
        // First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
        var recognizerResult = await _botServices.Dispatch.RecognizeAsync(stepContext.Context, cancellationToken);

        // Top intent tell us which cognitive service to use.
        var topIntent = recognizerResult.GetTopScoringIntent();

        switch (topIntent.intent)
        {

            case "Mainissue":
                 return await stepContext.BeginDialogAsync($"{nameof(MainDialog)}.fromMain", stepContext.Values[UserInfo], cancellationToken);

            case "ConfirmIntent":
                return await stepContext.BeginDialogAsync(nameof(Confirm), null, cancellationToken);

            case "EndBotIntent":
                return await stepContext.CancelAllDialogsAsync(true, null, null, cancellationToken);

            case "InverterData":
                await ProcessSampleQnAAsync(stepContext, cancellationToken);
                break;
            default:
                await stepContext.Context.SendActivityAsync(MessageFactory.Text($"I'm sorry I don't know what you mean."), cancellationToken);
                break;
         }
        return await stepContext.EndDialogAsync(null, cancellationToken);
    }

    private IList<Choice> GetChoices()
    {
        var cardOptions = new List<Choice>()
            {

                new Choice() { Value = "Product issue", Synonyms = new List<string>() { "adaptive" } },
                new Choice() { Value = "Register Product", Synonyms = new List<string>() { "hero" } },
                new Choice() { Value = "Online Purchase", Synonyms = new List<string>() { "hero" } },
                new Choice() { Value = "Customer Grivance", Synonyms = new List<string>() { "hero" } },
                new Choice() { Value = "Order Status", Synonyms = new List<string>() { "hero" } }
            };

        return cardOptions;
    }

    private Task<bool> ValidationAsync(PromptValidatorContext<string> promptContext, CancellationToken cancellationToken)
    {
        string value = (string)promptContext.Context.Activity.Text;
        if (Regex.IsMatch(value, "^[0-9]{10}$"))
        {
            return Task.FromResult(true);
        }
        else
        {
            return Task.FromResult(false);
        }
    }

    private async Task ProcessSampleQnAAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        _logger.LogInformation("ProcessSampleQnAAsync");

        var results = await _botServices.SampleQnA.GetAnswersAsync(stepContext.Context);
        if (results.Any())
        {
            await stepContext.Context.SendActivityAsync(MessageFactory.Text(results.First().Answer), cancellationToken);
        }
        else
        {
            await stepContext.Context.SendActivityAsync(MessageFactory.Text("Sorry, could not find an answer in the Q and A system."), cancellationToken);
        }
    }
}

答案 5 :(得分:0)

就我而言,当我运行多线程任务并遵循解决方案表格EL Vany时,会收到此消息。他的解决方案非常好。现在,我可以毫无例外地同时运行100个线程。

http://elvanydev.com/EF-DbContextFactory/#comments-1