Свойството HttpContext.Current е null в събитие на Sqldependency MVC

Работя по проект с множество наематели, в който всеки наемател има свои клиенти. В момента внедрявам неща в реално време, в които всеки път, когато някой клиент се регистрира или съществуващ клиент редактира информацията в своя профил, искам да уведомя наемателя за този клиент в реално време (използвайки signalR).

За откриване на промени в клиентската таблица използвам SqlDependency и SqlTrigger. Trigger ще направи записа в таблицата за уведомяване (която основно съдържа някои идентификатори (като TenantId, CustomerId), които се засягат и някаква друга информация) и в събитие, задействано от Sqldependency, аз извиквам метода, който допълнително ще извиква клиентския метод, използвайки signalR контекст.

Сега проблемът ми е, че не мога да осъществя достъп до нишката HttpContext.Current в събитието Sqldependency, тя е нула, защото не се случва заявка за нейното изпълнение. Проверете това изображение:

въведете описание на изображението тук

Моля, поправете ме, ако греша. Искам да получа достъп до този HttpContext.Current, защото искам да получа достъп до текущия клиент, за да уведомя. И моето изпълнение на TenantProvider получава клиента от Url хоста.

Така че първият ми въпрос е, има ли някакъв начин за достъп до контекста, в който се изпълнява кодът на функцията за събитие??

Ако не, тогава имам друг вариант с някои съмнения. Опцията е, че запазвам таблицата Промени в известията, която съдържа информация за TenantId, CustomerId и т.н. Мога да получа достъп до известието с най-новото времево клеймо и от този запис мога да получа tenantId за известяване.

Сега съмнението, ако 2 или повече клиенти се регистрират едновременно и преди достъп до най-новия запис за известие с времеви печат, задейства въвеждането на друго известие, отколкото в този случай сме пропуснали някои известия.

Така че вторият ми въпрос е дали прекалявам с това или това наистина е проблем. Ако това наистина е проблем, моля, уведомете ме за решението??


person Gaurav    schedule 17.04.2014    source източник
comment
За информация, регистрирам зависимостта на заявката в Application_Start, така че решението, предложено от отговора в stackoverflow.com/questions/8834677/ тази публикация няма да работи за мен.   -  person Gaurav    schedule 17.04.2014
comment
Ако всеки клиент е свързан с точно един наемател, не можете ли да стигнете от CustomerId до TenantId през една от вашите таблици?   -  person zimdanen    schedule 17.04.2014
comment
Добре.. Ами другата връзка? Може ли един клиент да бъде част от множество наематели? Или има директна връзка от клиент към един наемател?   -  person zimdanen    schedule 17.04.2014
comment
Точно. Така един клиент има един наемател. И така.. къде се поддържа тази връзка? В маса?   -  person zimdanen    schedule 17.04.2014
comment
И имате CustomerID по времето, когато се опитвате да регистрирате или редактирате клиента?   -  person zimdanen    schedule 17.04.2014
comment
нека продължим тази дискусия в чата   -  person zimdanen    schedule 17.04.2014


Отговори (2)


Единственото нещо, което ме притеснява относно начина, по който искате да го направите, е едновременността на вашите актуализации, точно поради причината, която описвате, решението е да се уверите, че използвате единичен екземпляр на вашия център за проследяване и паралелен речник за вашите данни, които променяте във вашия център. Използвате таблицата с известия, което всъщност не е необходимо.

ето няколко връзки за примери, които може да ви помогнат с това, което се опитвате да направите. http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20

първият е пример за зависимост от sqldependency, а вторият е приложение в стил център на централен сървър, което показва как да направите централизиран хъб, безопасен за нишки.

За проблема с Httpcontext използвам помощен клас, който пазя в моя слой от данни, използвам модел на хранилище за разработка за хъб с една нишка.

Ето го моят клас.

using System.Web;

namespace DataLayer.Common
{
    public class ConnectionHelper : IConnectionHelper
    {
        private ApplicationDbContext _context;

        public ApplicationDbContext Context
        {
            get
            {
                if (_context == null && HttpContext.Current.Items["DbActiveContext"] != null)
                {
                    _context = (ApplicationDbContext)HttpContext.Current.Items["DbActiveContext"];
                }
                else if (_context == null && HttpContext.Current.Items["DbActiveContext"] == null)
                {
                    _context = new ApplicationDbContext();
                    HttpContext.Current.Items.Add("DbActiveContext", _context);
                }

                return _context;
            }
            set { _context = value; }
        }
    }
}
person Kelso Sharp    schedule 29.05.2014
comment
Вашият кодов фрагмент предполага, че HttpContext.Current не е null. Това по принцип никога не е вярно при обратно извикване на известия. - person usr; 29.05.2014
comment
Е, мисля, че сте пропуснали нещо там, говоря за една нишка на хъб, единственият начин, по който httpcontext.current ще бъде нула, е ако го осъществявате от нишка, различна от заявката, и ако това е случаят, сте направили нещо нередно с вашия център за проследяване. - person Kelso Sharp; 29.05.2014
comment
Може би си прав. Все пак имам проблеми с разбирането как вашият отговор решава проблема, който има OP. (Не мога да върна -1, без да редактирате публикацията. Това е ТОЛКОВА наложено правило. Моля, направете фиктивна редакция.) - person usr; 29.05.2014
comment
Неговият проблем е, че той трябва да получи текущия контекст и ако има този клас, той може да създаде нов екземпляр, който ще картографира обратно към текущия контекст, ако съществува, и ще може да го използва в събитието. - person Kelso Sharp; 29.05.2014
comment
Едно последно нещо, разбрах по-късно... Ако работите във Visual Studio 2013, на Windows 8 или 8.1 HttpContext.Current винаги е нула. Не съм сигурен дали това е грешка в win 8 или е отхвърлена и вече не се използва. - person Kelso Sharp; 14.10.2014

Добавете тези две стъпки, за да имате достъп до HttpContext.Current.Session отвътре Customer_OnChange, което се надявам да ви доближи достатъчно до потребителския контекст, от който се нуждаете.

Първо, когато създавате този клас, запазете HttpContext.Current.Session в свойство. Това помага на вашето копие да запомни текущата сесия.

HttpSessionState session;
public EntityChangeNotifier()
{
    session = HttpContext.Current.Session;
}

Второ, след като създадете този клас, запазете новия си екземпляр като променлива на сесия. Това поддържа инстанцията жива през цялата потребителска сесия.

EntityChangeNotifier ecn = new EntityChangeNotifier();
HttpContext.Current.Session["ecn"] = ecn;

Сега можете да посочите свойството "сесия" от метода Customer_OnChange.

person Peder Benjamin Myhre    schedule 04.03.2016