我正在开发一个Silverlight 3应用程序,我希望通过提供的.dll或SOAP连接到Web服务。但.dll不适合Silverlight,所以我不能这样做。由于跨域问题,我无法访问SOAP服务(我不托管它,因此clientpolicy xml不会这样做。)
所以我的解决方案是在我自己的域中的WCF启用的webservice中包含.dll,并让Silverlight应用程序调用webservice。这很有效。
现在我的问题:我的webservice引用的.dll提供的客户端有一个.Connect()方法,所以我必须保存对象的状态。但我能这样做吗? Proberly并不是因为Silverlight不支持wsHttpBinding。我知道我可以访问ASP Session变量,但是我也可以在浏览器外执行此操作吗?我只能找出问题的一个解决方案,即在ASP Session中保存用户名/密码,并在每个方法中调用.Connect()方法。但这确实是一个糟糕的解决方案。
更好的想法?
我认为我没有说清楚,我为此道歉。我的英语是正确的原因。
我有:
我的Silverlight应用程序在网站和浏览器外运行
我的WCF服务托管在同一个域中。
跨域web服务(我无法访问存储跨域策略文件)
我的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。
答案 0 :(得分:0)
如果您的dll不是针对silverlight 3运行时构建的,那么您无法从silverlight项目中引用它。请求您的客户在该运行时重建dll。
Silverlight在运行需要完全信任的代码时非常严格。如果silverlight应用程序不知道dll所处的运行时间,它将不会接受它或对它进行任何调用。
答案 1 :(得分:0)
我不是百分百肯定我理解这个问题,但我确实有一些类似的情况与我合作,这就是我们如何处理它。
对于身份验证,我们在WCF服务上有一个身份验证方法,然后调用Web服务并传递我们从Silverlight传递的凭据。然后,Web服务使用我们在Silverlight请求上设置为cookie的身份验证令牌进行响应。因此,Silverlight未来的所有调用都将包含我们在每次调用Web服务时传递的令牌。
显然,您不希望将用户名和密码设置为cookie。但希望您可以从Web服务中获取某种cookie或令牌,然后您可以在将来的请求中使用它们。
更新了答案
根据您更新的规格,听起来您需要缓存服务客户端。您可以尝试使用Custom WCF Instance Contexts,但这是一个简单的方法。
[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。现在,这种方法存在一些问题,您仍需要解决这些问题。
现在就是这样,如果您有任何疑问,请告诉我。
答案 2 :(得分:0)
更新
您可以将服务标记为在会话期间将服务对象保留在内存中。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyWebService{
CrossDomainWebServiceClient client = new CrossDomainWebServiceClient();
这应该使您的跨域客户端在调用之间保持初始化。
原始答案:
Silverlight对象在调用之间保持活动状态,因此您可以在内存中维护状态。
如果要在Silverlight应用程序的运行之间存储状态,可以在客户端计算机上将状态序列化为独立存储,并在Silverlight应用程序启动时将其读回。