#c# #wcf
#c# #wcf
Вопрос:
Я кодирую службу аутентификации, которая имеет несколько методов. одним из таких методов является ChangePassword. Я хочу, чтобы, когда какой-либо орган захочет изменить пароль, он входил в систему раньше.для этого я хочу иметь идентификатор сеанса и перед изменением передачи проверить его.
Как я могу это сделать и истекло ли время ожидания сеанса?
РЕДАКТИРОВАТЬ 1)
Я пишу этот код, но мой сеанс равен нулю каждый раз, когда я хочу получить его значение:
Класс:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class Service2 : IService2
{
string result
{ // Store result in AspNet session.
get
{
if (HttpContext.Current.Session["Result"] != null)
return HttpContext.Current.Session["Result"].ToString();
return "Session Is Null";
}
set
{
HttpContext.Current.Session["Result"] = value;
}
}
public void SetSession(string Val)
{
result = Val;
}
public string GetSession()
{
return resu<
}
интерфейс:
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IService2
{
[OperationContract]
void SetSession(string Val);
[OperationContract]
string GetSession();
}
web.config
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
РЕДАКТИРОВАТЬ 2)
Я написал этот код, но он не работает:
private void button1_Click(object sender, EventArgs e)
{
MyService2.Service2Client srv = new MyService2.Service2Client();
textBox1.Text = srv.GetSession();
}
private void button2_Click(object sender, EventArgs e)
{
MyService2.Service2Client srv = new MyService2.Service2Client();
srv.SetSession(textBox1.Text);
textBox1.Clear();
}
каждый раз, когда я хочу получить значение сеанса, я получаю «Сеанс равен нулю». Почему?
Комментарии:
1. Может быть, так: после проверки учетных данных во время входа в систему сервер генерирует, сохраняет в базе данных и возвращает клиенту идентификатор сеанса. После этого клиент всегда передает идентификатор сеанса на сервер, где вы можете его проверить?
2. @Reniuz: В таком случае, зачем вам конкретно нужен идентификатор сеанса? Простого старого GUID было бы более чем достаточно!
3. @LOSTCODER И где я написал, что идентификатор сеанса не является GUID?
Ответ №1:
Чтобы иметь идентификатор сеанса, у вас должна быть привязка с поддержкой сеанса. Например, wsHttpBinding
. В вашем конфигурационном файле у вас должно быть что-то вроде:
<services>
<service name="MyService">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_MyServiceConfig"
contract="IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
В IMyService
интерфейсе для SessionMode
атрибута должно быть установлено значение Required
, вот так:
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IMyService
{
[OperationContract]
AuthenticationData Authenticate(string username, string password);
}
Когда все это настроено, вы можете перейти к SessionId
вот так:
var sessionId = OperationContext.Current.SessionId;
Другим способом было бы включить AspNetCompatibilityRequirements, но это немного перебор, чтобы просто получить идентификатор сеанса.
Комментарии:
1. @veljkoz: спасибо, но этот идентификатор сеанса сбрасывается при каждом вызове. Я хочу сеанс, подобный session в asp.net . Я хочу, чтобы, когда пользователь создает экземпляр службы, сеанс создавался и оставался, например, 20 минут. как я могу этого добиться?
2. Вы можете получить это, не закрывая сеанс — пока он открыт, он сохранит сеанс (т. Е. не закрывайте канал обслуживания после каждого вызова, а создайте какой-нибудь одноэлементный класс, предоставляющий эту службу, и воссоздайте его, если канал по какой-либо причине отключен). У нас есть точно такой же сценарий, и он отлично работает для всех наших проектов.
3. если я не закрою службу, многие каналы могут быть открыты, и это может привести к тому, что IIS не будет обрабатывать новые requests.is это правда?
4. Ну, у нас было около 300 клиентов, работающих одновременно, и это работало довольно хорошо. Возможно, вам придется увеличить:
<serviceThrottling maxConcurrentCalls="30" maxConcurrentSessions="30" maxConcurrentInstances="30" />
но даже при 30 это работает для нас. С другой стороны, я не думаю, что вы сможете сохранить идентификатор сеанса, если закроете канал, даже в asp.net … итак, если вы полагаетесь на сеансы, вы должны держать их открытыми.5. Я не закрываю службу, но она не работает : (: ( Пожалуйста, смотрите правку 2
Ответ №2:
При использовании wsHttpBinding в WCF вы найдете значение OperationContext.Current.Идентификатор сеанса равен нулю. Решение заключается в следующем (требуется два шага):
-
Установите для ReliableSession значение true в файле конфигурации
<bindings> <wsHttpBinding> <binding name ="WSHttpBinding_MyService" sendTimeout="00:05:00" > <security mode="None"></security> <reliableSession enabled="true"/> </binding> </wsHttpBinding> </bindings>
-
В интерфейсе контракта для атрибута SessionMode установлено значение Required
[ServiceContract(SessionMode = SessionMode.Required)] public interface IMyService{...}
Следуйте инструкциям выше, проблема будет решена
Ответ №3:
Вы можете активировать ASP.NET режим совместимости в вашей службе WCF и все преимущества ASP.NET сеансы и контекст.
Добавьте этот атрибут в определение вашего класса WCF:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
и в вашем web.config:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
</configuration>