Синхронизация корреляционного состояния между IClientMessageInspector и IParameterInspector
У меня есть wcf-клиент. В соответствии с требованиями мне необходимо записать некоторые метаданные в запросе (а также данные пользователя, которые не включены в запрос.) Затем, если запрос будет успешным, мне, возможно, придется записывать метаданные ответа и в зависимости от флагов полный запрос на мыло.
Я пытаюсь сделать это правильно (используя IParameterInspector для проверки метаданных и IClientMessageInspector для получения мыла), но у меня нет возможности сопоставить два запроса интерфейса. Я не уверен в безопасности потоков здесь. Это урезанная версия, где я нахожусь...
public class SoapRequestInfo
{
public string UserId { get; set; }
public Guid Key { get; set; }
//would contain a lot more info
}
public class OperationProfilerParameterInspector : IParameterInspector, IClientMessageInspector
{
//before serialization
public object BeforeCall(string operationName, object[] inputs) //IParameterInspector
{
//Add the operation, record some specific inputs to db
return new SoapRequestInfo
{
UserId = "1234",
Key = new Guid()
};
}
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) //IParameterInspector
{
var info = correlationState as SoapRequestInfo;
//Do some additional logging - easy enough
}
public object BeforeSendRequest(ref Message request, IClientChannel channel) //IClientMessageInspector
{
//want to correlate this with IParameterInspector
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState) //IClientMessageInspector
{
//May want to log full soap message depending on after call criteria
}
}
Я знаю, что я не могу использовать закрытую переменную, чтобы удерживать Guid. Я не могу использовать сеанс, потому что может быть несколько запросов в тесной последовательности и не может гарантировать, что ответ правильный. Итак, как я могу однозначно идентифицировать взаимосвязь между двумя интерфейсами?
Ответы
Ответ 1
Возможно, вы можете использовать HttpContext.Items для сохранения вашего объекта, если ваша служба работает в режиме совместимости ASPNET, иначе вы можете использовать TLS (Thread Local Storage), поместить данные в слот и получить/очистить позже.
Ответ 2
Возможно, вы можете сделать это немного:
Из этого сообщения передать токен корреляции в службу WCF?:
Если вы используете версию сообщения с WS-Addressing, вы должны иметь это автоматически, потому что каждое сообщение будет содержать его автогенерированный идентификатор (guid), и каждый ответ будет содержать идентификатор запроса. Вы можете получить доступ к этим заголовкам через OperationContext
Если использование сообщений не соответствует вашим требованиям, возможно, вы можете попытаться поместить свой собственный идентификатор в заголовок при отправке запроса и, возможно, обновить ответ с тем же идентификатором.