Повідомлення PageLoadComplete

Для того, щоб зафіксувати користувача, що відкриває карточку звернення, вношу зміни в скрипт ChildPageLoadCompleteScriptExecute (повідомлення PageLoadComplete).

var selectSR = new Select(UserConnection)
        .Column("LockedById")
        .From("ServiceRequest")
        .Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue,"Guid"))
                as Select;

using (var dbExecutor = UserConnection.EnsureDBConnection()) {
        var needToCapture = false;
        var contact = new Terrasoft.Configuration.Contact(Page.UserConnection);
        var lockedByName = "Unknown";
        var lockedById = selectSR.ExecuteScalarGuid>();
        if (lockedById == Guid.Empty) {
                lockedById = UserConnection.CurrentUser.ContactId;
                needToCapture = true;
        }
        if (contact.FetchFromDB(lockedById)) {
            lockedByName = contact.Name;
        }
        if (needToCapture) {
                var update = new
                        Update(UserConnection, "ServiceRequest").
                                Set("LockedById", Column.Parameter(lockedById)).
                                Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
                        update.Execute();
        } else
        if (lockedById != UserConnection.CurrentUser.ContactId) {
                Page.BaseMessagePanel.AddMessage(Warning, "Обращение заблокировано пользователем ["+lockedByName+"] [ "+lockedById.ToString()+" ] [ "+(UserConnection.CurrentUser.ContactId).ToString()+" ]", MessageType.Warning);
        }
}

При натисненні плашки OK скрипт OKButtonClickScriptExecute відпрацьовує повідомлення OKButtonClick, при цьому очищається поле LockedById, в яком фіксується користувач, що тримає карточку:

var selectSR = new Select(UserConnection)
        .Column("LockedById")
        .From("ServiceRequest")
        .Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue,"Guid"))
                as Select;

using (var dbExecutor = UserConnection.EnsureDBConnection()) {
        dbExecutor.StartTransaction();
        var lockedById = selectSR.ExecuteScalarGuid>();

        if (UserConnection.CurrentUser.ContactId == lockedById) {
                try {
                        var update = new
                                Update(UserConnection, "ServiceRequest").
                                        Set("LockedById", Column.Parameter(null, "Guid")).
                                        Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
                                update.Execute();
                } catch (Exception e) {
                        System.IO.File.AppendAllText("C:\\inetpub\\wwwroot\\BPMOnline\\ServiceRequestCardOpenLog\\Log.txt", (char)13 + (char)10 + e.Message + (char)13 + (char)10);
                }
                lockedById = selectSR.ExecuteScalarGuid>();
        }
        dbExecutor.CommitTransaction();
        lockedById = selectSR.ExecuteScalarGuid>();
}

Все добре, окрім одного моменту - інколи повідомлення PageLoadComplete повторно генерується після того, як вже була натиснута плашка OK. Відповідно ChildPageLoadCompleteScriptExecute відпрацьовує заново і в поле LockedById знову прописується поточний користувач.

Запитання: чому повідомлення PageLoadComplete генерується повторно ?

Нравится

12 комментариев

Добрый день, Игорь!
Так как в bpm'online модель событий преимущественно заимствована из ASP.NET, то и ведет она себя аналогичным образом.
Цитирую:
"
В серверных элементах управления некоторые события (обычно событие нажатия) вызывают немедленную отправку страницы назад на сервер. События изменения в серверных элементах управления HTML и в серверных веб-элементах управления, например, элемент управления TextBox, захватываются, но не вызывают отправки. Вместо этого они создаются при следующем выполнении отправки.
...
После отправки страницы создаются события инициализации страницы (Page_Init и Page_Load), а затем обрабатываются события элементов управления. При отсутствии подробных сведений об обработке событий на странице не следует создавать логику приложения, которая опирается на события изменения, вызываемые в определенном порядке. Дополнительные сведения см. в разделе Общие сведения о жизненном цикле веб-страниц ASP.NET.

" (тыц)

Соответсвенно, PageLoadComplete вызывается каждый раз при нажатии на кнопку. Вам необходимо учесть данный аспект. Можно добавить параметр на страницу, который проверять и заполнять при первом вызове PageLoadComplete. Например:

if (!NeedLockaPage) {
//установка блокировки
}
NeedLockPage = true;

Здесь NeedLockPage - это параметр страницы логического типа.

Мова про параметр в структурі IncidentEditPageEventsProcess ?
Чи в IncidentEditPage ?

Про параметр процесса страницы, то есть IncidentEditPageEventsProcess (первый вариант).

Я спробував так зробити, але при повторній обробці PageLoadComplete NeedLockPage виявляється знову false, хоча мав би бути true.

Ігор, а спробуйте в ChildPageLoadCompleteScriptExecute зробити перевірку на існування сессії. Якщо сессія відкрита, значить відразу вийти і нічого не робити і навпаки

Чудеса не припиняються.
На [OK] створив обробника:

var selectSR = new Select(UserConnection)
        .Column("LockedById")
        .From("ServiceRequest")
        .Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue,"Guid"))
		as Select;
 
using (var dbExecutor = UserConnection.EnsureDBConnection()) {
	dbExecutor.StartTransaction();
	var lockedById = selectSR.ExecuteScalar<Guid>();
 
	if (UserConnection.CurrentUser.ContactId == lockedById) {
		var update = new
		Update(UserConnection, "ServiceRequest").
			Set("LockedById", Column.Parameter(null, "Guid")).
			Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
		update.Execute();
	}
	lockedById = selectSR.ExecuteScalar<Guid>();
	UserConnection.SessionData["NeedLockPage_"+EntityPrimaryColumnValue.ToString()] = 0;
}
return true;

На вході чітко виконується умова:

(UserConnection.CurrentUser.ContactId == lockedById)

Після UPDATE

lockedById = selectSR.ExecuteScalar<Guid>();

значення lockedById стає Guid.Empty (як і належить).
В профайлері знаходжу відповідний запит

exec sp_executesql N'
UPDATE [dbo].[ServiceRequest]
SET
	[LockedById] = @P2
WHERE
	[Id] = @P1',N'@P1 uniqueidentifier,@P2 uniqueidentifier',@P1='19717479-93BF-4AC9-9095-36D6A8F32583',@P2=NULL

Але після того, як закривається сторінка, значення поля [LockedById] у відповідному записі таблиці [ServiceRequest] залишається без змін.

Щось я явно випускаю з виду. Що саме ?

Наскільки я зрозумів, Значення [LockedById] змінюється на не NULL після того як сторінка закрилась? Якщо так то потрібно дивитися далі в профайлері, який запрос його змінює

Схоже, що проблема була в організації транзакцій. Наступний код вирішив проблему:

dbExecutor.StartTransaction();
 
try {
	var update = new
	Update(UserConnection, "ServiceRequest").
		Set("LockedById", Column.Parameter(null, "Guid")).
		Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
	update.Execute();
}
catch (Exception e) {
	dbExecutor.RollbackTransaction();
	System.IO.File.AppendAllText("C:\\inetpub\\wwwroot\\BPMOnline\\ServiceRequestCardOpenLog\\Log.txt", (char)13 + (char)10 + e.Message + (char)13 + (char)10);
}
 
dbExecutor.CommitTransaction();

Одна задача вирішилась, натомість виникла інша: при натисненні плашки [OK] в реєстрі звернень запис конкретного звернення оновлюється, - видно зміну по полю [LockedById], все добре. А от коли UPDATE виконується в рамках [ChildPageLoadCompleteScriptExecute], то в реєстрі запис цього звернення не оновлюється, а потрібно, щоб оновлювався.

Як це зробити ?

А ви пробували в дебагі дивитися що виконується в ChildPageLoadCompleteScriptExecute?

В дебагі не дивився, але чисто за логікою розумію, що обробка [OK] передбачає завершувальні операції щодо карточки. Саме завдяки цим операціям і здійснюється оновлення реєстру.

Питання якраз і полягає в тому, щоб заставити реєстр оновитись до натиснення [OK]

Це правильно, але натискання плашки ОК, як я розумію, визиває перезагрузку сторінки і тим самим визиває ChildPageLoadCompleteScriptExecute. Якщо я правильно розумію

Показать все комментарии