在Silverlight 3中保持状态

在Silverlight 3中保持状态,silverlight,session,silverlight-3.0,web-services,state,Silverlight,Session,Silverlight 3.0,Web Services,State,我正在开发一个Silverlight 3应用程序,我想用提供的.dll或SOAP连接到Web服务。但是.dll不适合Silverlight,所以我不能这样做。由于跨域问题,我无法访问SOAP服务(我不托管它,因此clientpolicy xml不起作用) 因此,我的解决方案是在我自己的域中将.dll包含在支持WCF的Web服务中,并让Silverlight应用程序调用该Web服务。这很有效 现在我的问题是:由我的webservice引用的.dll提供的客户端有一个.Connect()方法,所以我

我正在开发一个Silverlight 3应用程序,我想用提供的.dll或SOAP连接到Web服务。但是.dll不适合Silverlight,所以我不能这样做。由于跨域问题,我无法访问SOAP服务(我不托管它,因此clientpolicy xml不起作用)

因此,我的解决方案是在我自己的域中将.dll包含在支持WCF的Web服务中,并让Silverlight应用程序调用该Web服务。这很有效

现在我的问题是:由我的webservice引用的.dll提供的客户端有一个.Connect()方法,所以我必须保存对象的状态。但我能做到吗?可能不是因为Silverlight不支持wsHttpBinding。我知道我可以访问ASP会话变量,但我也可以在浏览器外访问吗?对于我的问题,我只能找到一个解决方案,那就是在ASP会话中保存用户名/密码,并在每个方法中调用.Connect()方法。但这确实是一个糟糕的解决方案

更好的主意


我想我没有说清楚,我为此道歉。我的英语是主要原因

我有:

我的Silverlight应用程序在网站上运行,不在浏览器中运行

托管在同一域中的我的WCF服务

跨域Web服务(我无法访问存储跨域策略文件)

我的WCF Web服务在我的应用程序和跨域Web服务之间提供了一个层,因为没有策略文件,您无法添加跨域Web服务

我的Web服务看起来像这样(以抽象的方式):


Foo()方法不起作用,因为它是每次调用的会话,而不是每次实例的会话。我希望这能奏效。因此,需要为下一次调用保留客户机对象。Session.required无法在Silverlight中工作,因为wsHttpBinding显然不受支持。

如果您的dll不是针对Silverlight 3运行时构建的,则无法从Silverlight项目中引用它。要求客户机在该运行时重建dll


Silverlight在运行需要完全信任的代码时非常严格。如果silverlight应用程序不知道dll在什么运行时,它将根本不接受它或对它进行任何调用。

我不能100%确定我是否理解这个问题,但我确实遇到过类似的情况,下面是我们如何处理它

  • 第三方Web服务 存储所有数据
  • WCF中间层由我们创建,用于处理所有 与webservice的交互
  • Silverlight客户端层 连接到我们的WCF服务
  • 对于身份验证,我们在WCF服务上有一个身份验证方法,该方法随后调用webservice并传递我们从Silverlight提交的凭据。然后,Web服务使用身份验证令牌进行响应,我们在Silverlight请求中将该令牌设置为cookie。因此,将来所有来自Silverlight的调用都将包含这个令牌,我们将它与每个调用一起传递给Web服务

    显然,您不希望将用户名和密码设置为cookie。但希望您可以从Web服务中获得某种cookie或令牌,然后在将来的请求中使用它们

    更新的答案

    根据您更新的规格,听起来您需要缓存服务客户端。你可以试着想象一下,但这里有一个简单的方法

    [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;
        }
    }
    
    [ServiceContract(Namespace=”“)]
    [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
    公共类代理服务
    {
    私有静态字典客户端=新字典();
    公共代理服务()
    {
    }
    [经营合同]
    公共无效登录()
    {
    Guid id=Guid.NewGuid();
    //在此处执行登录
    clients.Add(id,DateTime.Now);//存储客户端而不是日期
    SetCookie(id);
    }
    [经营合同]
    公共日期时间Foo()
    {
    var id=ReadCookie();
    if(clients.ContainsKey(id))
    {
    返回客户端[id];
    }
    return DateTime.MinValue;
    }
    私有void SetCookie(Guid id)
    {
    var cookie=newhttpcookie(“id”,id.ToString());
    cookie.Expires=DateTime.Now.AddMinutes(10);
    HttpContext.Current.Response.AppendCookie(cookie);
    }
    私有Guid ReadCookie()
    {
    var cookie=HttpContext.Current.Request.Cookies.Get(“id”);
    if(cookie!=null)
    {
    cookie.Expires=DateTime.Now.AddMinutes(10);
    返回新的Guid(cookie.Value);
    }
    返回Guid.Empty;
    }
    }
    
    当然,您可以存储客户端服务,而不是日期时间。现在,这种方法仍有一些问题需要解决

  • 超时-您需要某种方法来超时不活动的会话,并将其从客户端列表中清除
  • 我不确定这是否是一种超级安全的做事方式。如果有人获得了您的guid,那么他们可以访问您的员工。然而,我不知道这将如何发生,但我不是一个安全专家
  • 现在到此为止,如果您有任何问题,请告诉我。

    更新:

    您可以标记您的服务,以便在会话期间将服务对象保留在内存中

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    class MyWebService{   
        CrossDomainWebServiceClient client = new CrossDomainWebServiceClient();   
    
    这将使跨域客户端在调用之间保持初始化状态

    原始答复:

    Silverlight对象在调用之间保持活动状态,因此可以在内存中维护状态


    如果要在Silverlight应用程序的两次运行之间存储状态,可以将状态序列化到客户端计算机上的独立存储,并在Silverlight应用程序启动时将其读回。

    我知道,我不能问他们:/因此,我在自己的域中创建了一个Web服务,它引用了.dll:)该.dll也在调用一个Web服务,所以这将给我带来与我现在猜想的相同的问题。嗯,很好的解决方案。我的silverlight和
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    class MyWebService{   
        CrossDomainWebServiceClient client = new CrossDomainWebServiceClient();