Сохранение состояния в Silverlight 3 - PullRequest
0 голосов
/ 25 октября 2009

Я разрабатываю приложение Silverlight 3, которое я хочу подключить к веб-сервису с помощью предоставленного .dll или с помощью SOAP. Но .dll не подходит для Silverlight, поэтому я не могу этого сделать. И я не могу получить доступ к службе SOAP из-за междоменных проблем (я не размещаю ее, поэтому clientpolicy xml не подойдет).

Таким образом, мое решение заключается в том, чтобы включить .dll в веб-службу с поддержкой WCF в моем собственном домене и позволить приложению Silverlight вызывать веб-службу. Это работает.

Теперь к моей проблеме: клиент, предоставленный из .dll, на которую ссылается мой веб-сервис, имеет метод .Connect (), поэтому я должен сохранить состояние объекта. Но я могу сделать это? Наверное, нет, потому что Silverlight не поддерживает wsHttpBinding. Я знаю, что могу получить доступ к переменным ASP Session, но могу ли я сделать это вне браузера? Я могу найти только одно решение моей проблемы: сохранить имя пользователя / пароль в сеансе ASP и вызвать метод .Connect () в каждом методе. Но это действительно плохое решение.

Лучшие идеи?


Я не думаю, что дал понять, и извиняюсь за это. Мой английский правильно является основной причиной для этого.

У меня есть:

Приложение My Silverlight, которое работает на веб-сайте и вне браузера

Моя служба WCF, размещенная в том же домене.

междоменная веб-служба (не удается получить доступ к хранилищу файла междоменной политики)

Мой веб-сервис WCF обеспечивает слой между моим приложением и междоменным веб-сервисом, поскольку вы не можете добавлять междоменные веб-службы без файла политики.

Мой веб-сервис выглядит так (абстрактно):

class MyWebService
{
   CrossDomainWebServiceClient client = new CrossDomainWebServiceClient();

   public void Connect(string username, string password)
   {
      client.Connect(username, password);
   }

   public object Foo()
   {
      //GetEmployees() do only work if I'm connected
      return client.GetEmployees(); 
   }
}

Метод Foo () не работает, потому что это сеанс на вызов, а не сеанс на экземпляр. Я хочу, чтобы это сработало. Таким образом, объект клиента должен быть сохранен для следующего вызова. Session.required не работают в Silverlight, потому что wsHttpBinding явно не поддерживается.

Ответы [ 3 ]

0 голосов
/ 27 октября 2009

Я не уверен на 100%, что понимаю вопрос, но у меня есть несколько схожая ситуация, с которой я работаю, и вот как мы справляемся с этим.

  1. Сторонний веб-сервис, который хранит все данные.
  2. Средний уровень WCF, созданный нами для обработки всех взаимодействие с веб-сервисом.
  3. Уровень клиента Silverlight, который подключается к нашему сервису WCF.

Для аутентификации у нас есть метод аутентификации в нашей службе WCF, который затем вызывает веб-сервис и передает учетные данные, которые мы передали из Silverlight. Затем веб-служба отвечает маркером аутентификации, который мы установили в качестве файла cookie в запросе Silverlight. Таким образом, все будущие вызовы от Silverlight будут включать этот токен, который мы передаем при каждом обращении к веб-службе.

Очевидно, что вы не захотите устанавливать имя пользователя и пароль в виде куки. Но, надеюсь, вы можете получить какой-нибудь cookie или токен обратно от веб-сервиса, который затем сможете использовать в будущих запросах.

Обновленный ответ

Судя по вашим обновленным спецификациям, вам нужно будет кэшировать клиентов службы. Вы могли бы попытаться придумать Пользовательские контексты экземпляра WCF , но здесь есть простой подход.

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ProxyService
{
    private static Dictionary<Guid, DateTime> clients = new Dictionary<Guid, DateTime>();

    public ProxyService()
    {

    }

    [OperationContract]
    public void Login()
    {
        Guid id = Guid.NewGuid();
        // perform your login here
        clients.Add(id, DateTime.Now); // store your client instead of a date
        SetCookie(id);
    }

    [OperationContract]
    public DateTime Foo()
    {
        var id = ReadCookie();
        if (clients.ContainsKey(id))
        {
            return clients[id];
        }
        return DateTime.MinValue;
    }

    private void SetCookie(Guid id)
    {
        var cookie = new HttpCookie("id", id.ToString());
        cookie.Expires = DateTime.Now.AddMinutes(10);
        HttpContext.Current.Response.AppendCookie(cookie);
    }

    private Guid ReadCookie()
    {
        var cookie = HttpContext.Current.Request.Cookies.Get("id");
        if (cookie != null)
        {
            cookie.Expires = DateTime.Now.AddMinutes(10);
            return new Guid(cookie.Value);
        }
        return Guid.Empty;
    }
}

Конечно, вместо DateTime вы будете хранить свою клиентскую службу. Теперь есть несколько проблем с этим подходом, которые вам все еще нужно решить.

  1. Тайм-ауты - вам нужен какой-то способ для тайм-аута сессий, которые не активны, и удаления их из списка клиентов.
  2. Я не уверен, что это супер безопасный способ сделать что-то. Если кто-то получит ваш гид, он сможет получить доступ к вашим сотрудникам. Однако я не понимаю, как это произойдет, но я не эксперт по безопасности.

Пока, если у вас есть вопросы, дайте мне знать.

0 голосов
/ 28 октября 2009

Обновление:

Вы можете пометить свой сервис, чтобы сохранить объект сервиса в памяти на время жизни сеанса.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyWebService{   
    CrossDomainWebServiceClient client = new CrossDomainWebServiceClient();   

Это должно поддерживать инициализацию вашего междоменного клиента между вызовами.

Оригинальный ответ:

Объект Silverlight остается активным между вызовами, чтобы вы могли поддерживать состояние в памяти.

Если вы хотите сохранить состояние между запусками приложения Silverlight, вы можете сериализовать состояние в изолированное хранилище на клиентском компьютере и прочитать его обратно при запуске приложения Silverlight.

0 голосов
/ 25 октября 2009

Если ваша dll не построена на время выполнения silverlight 3, вы не можете ссылаться на нее из своего проекта silverlight. Попросите вашего клиента перестроить dll в это время выполнения.

Silverlight строг, когда дело доходит до запуска кодов, которые требуют полного доверия. Если приложение silverlight не знает, в какое время находится dll, оно не примет его или вообще не вызовет.

...