Silverlight 调用自托管的wcf 报跨域异常的处理
2016-01-24 15:27
302 查看
Sileverlight很多时候需要通过wcf和后台,程序进行交互。如果 iis was托管还好,极端的遇到自托管的程序,console,windowsservice,winform,wpf等,就会出现跨域问题。网上很多解决方式。俺在以下博文基础上又总结了点。
以下博文可以先学习下:
/article/11687540.html
http://blog.sina.com.cn/s/blog_74066ace0100vhs5.html
/article/5139625.html
2.可以跨进程托管Domain
3.可以不写配置文件托管Domain和Service
4.可以用 Stream和Message当Domain返回值
5.不通过配置实现的自托管代码如下:
1.在项目中加入clientaccesspolicy.xml,编译生成内容,复制=true
2. 加入域提供类
3.自托管 启动跨域访问
注:
优点:跨域访问的返回文件类型是:Content-Type: application/xml 。IE,Chrome都测试过,都可以使用。
缺点:客户端过多可能对造成过多的IO请求,需要做多客户端压力测试。
方案2:
1.在项目中加入clientaccesspolicy.xml,编译生成嵌入资源
2.[b]加入域提供类[/b]
3.自托管 启动跨域访问
注:
优点:没有过多的IO请求。
缺点:[b]跨域访问的返回文件类型是:Content-Type: application/octet-stream 。IE可用,Chrome不可用。[/b]
[b] [b] 方案3:
[/b][/b]
1.[b]加入域提供类[/b]
3.自托管 启动跨域访问
注:
优点:没有过多的IO请求。[b][b]跨域访问的返回文件类型是Content-Type: application/xml[/b]。IE,Chrome可用[/b]
缺点:指定了编码方式,可能带来局限性。
--Domain--
ServiceHost crossDomainserviceHost = new ServiceHost(typeof(DomainService));
crossDomainserviceHost.AddServiceEndpoint(typeof(IDomainService), new WebHttpBinding()
, "http://localhost:9090/");
crossDomainserviceHost.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior());
crossDomainserviceHost.Open();
--Service--
ServiceHost testHost = new ServiceHost(typeof(WCFService), new Uri("http://localhost:9090/WCFService/"));
testHost.AddServiceEndpoint(typeof(IWCFService), new BasicHttpBinding()
, "");
ServiceMetadataBehavior bb = new ServiceMetadataBehavior();
bb.HttpGetEnabled = true;
bb.HttpGetUrl = new Uri("http://localhost:9090/WCFService/mex");
testHost.Description.Behaviors.Add(bb);
ServiceCredentials credential = new ServiceCredentials();
testHost.Description.Behaviors.Add(credential);
testHost.Open();
注意:请用“http://localhost:9090/WCFService/mex”来寻找服务,目前水平有限,还不能直接通过代码实现和配置一样通过http://localhost:9090/WCFService/"来寻找服务。望大家知道的能回复答案。
以下博文可以先学习下:
/article/11687540.html
http://blog.sina.com.cn/s/blog_74066ace0100vhs5.html
/article/5139625.html
以下是个人总结
1.此解决方案与Silverlight版本无关。2.可以跨进程托管Domain
3.可以不写配置文件托管Domain和Service
4.可以用 Stream和Message当Domain返回值
5.不通过配置实现的自托管代码如下:
跨域解决方案
方案1:1.在项目中加入clientaccesspolicy.xml,编译生成内容,复制=true
<?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="*"> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
2. 加入域提供类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using System.ServiceModel.Channels; using System.Xml; namespace TEST { public class DomainService : IDomainService { public System.ServiceModel.Channels.Message ProvidePolicyFile() { XmlReader reader = XmlReader.Create("clientaccesspolicy.xml"); System.ServiceModel.Channels.Message result = Message.CreateMessage(MessageVersion.None, "", reader); return result; } } [ServiceContract] public interface IDomainService { [OperationContract] [WebGet(UriTemplate = "/clientaccesspolicy.xml")] System.ServiceModel.Channels.Message ProvidePolicyFile(); } }
3.自托管 启动跨域访问
//启动跨域访问 ServiceHost crossDomainserviceHost = new ServiceHost(typeof(DomainService)); crossDomainserviceHost.AddServiceEndpoint(typeof(IDomainService), new WebHttpBinding() , "http://127.0.0.1:4514/"); crossDomainserviceHost.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior()); crossDomainserviceHost.Open();
注:
优点:跨域访问的返回文件类型是:Content-Type: application/xml 。IE,Chrome都测试过,都可以使用。
缺点:客户端过多可能对造成过多的IO请求,需要做多客户端压力测试。
方案2:
1.在项目中加入clientaccesspolicy.xml,编译生成嵌入资源
2.[b]加入域提供类[/b]
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using System.ServiceModel.Channels; using System.Xml; namespace Test { public class DomainService : IDomainService { public Stream ProvidePolicyFile() { var policyfile = "Test.clientaccesspolicy.xml"; Stream result= Assembly.GetExecutingAssembly().GetManifestResourceStream(policyfile); return result; } } [ServiceContract] public interface IDomainService { [OperationContract] [WebGet(UriTemplate = "/clientaccesspolicy.xml")] Stream ProvidePolicyFile(); } }
3.自托管 启动跨域访问
注:
优点:没有过多的IO请求。
缺点:[b]跨域访问的返回文件类型是:Content-Type: application/octet-stream 。IE可用,Chrome不可用。[/b]
[b] [b] 方案3:
[/b][/b]
1.[b]加入域提供类[/b]
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using System.ServiceModel.Channels; using System.Xml; namespace TEST { public class DomainService : IDomainService { public Stream ProvidePolicyFile() { string clientAccessPolicy = "<?xml version=\"1.0\" encoding=\"utf-8\"?> <access-policy><cross-domain-access><policy><allow-from http-request-headers=\"*\"><domain uri=\"*\"/></allow-from><grant-to><resource path=\"/\" include-subpaths=\"true\"/></grant-to> </policy></cross-domain-access></access-policy>"; return StringToStream(clientAccessPolicy); } private Stream StringToStream(string result) { WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; return new MemoryStream(Encoding.UTF8.GetBytes(result)); } } [ServiceContract] public interface IDomainService { [OperationContract] [WebGet(UriTemplate = "/clientaccesspolicy.xml")] Stream ProvidePolicyFile(); } }
3.自托管 启动跨域访问
注:
优点:没有过多的IO请求。[b][b]跨域访问的返回文件类型是Content-Type: application/xml[/b]。IE,Chrome可用[/b]
缺点:指定了编码方式,可能带来局限性。
总结:
方案3,1一般情况均较好。个人喜欢第3种。--Domain--
ServiceHost crossDomainserviceHost = new ServiceHost(typeof(DomainService));
crossDomainserviceHost.AddServiceEndpoint(typeof(IDomainService), new WebHttpBinding()
, "http://localhost:9090/");
crossDomainserviceHost.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior());
crossDomainserviceHost.Open();
--Service--
ServiceHost testHost = new ServiceHost(typeof(WCFService), new Uri("http://localhost:9090/WCFService/"));
testHost.AddServiceEndpoint(typeof(IWCFService), new BasicHttpBinding()
, "");
ServiceMetadataBehavior bb = new ServiceMetadataBehavior();
bb.HttpGetEnabled = true;
bb.HttpGetUrl = new Uri("http://localhost:9090/WCFService/mex");
testHost.Description.Behaviors.Add(bb);
ServiceCredentials credential = new ServiceCredentials();
testHost.Description.Behaviors.Add(credential);
testHost.Open();
注意:请用“http://localhost:9090/WCFService/mex”来寻找服务,目前水平有限,还不能直接通过代码实现和配置一样通过http://localhost:9090/WCFService/"来寻找服务。望大家知道的能回复答案。
相关文章推荐
- IP地址(IPv4)/IPv6地址的正则表达式
- Oracle Data Provider for .NET
- 含有SilverLight项目的代码重用
- Managed DirectX中的DirectShow应用(简单Demo及源码)
- XAML中的特殊符号几空白字符处理
- .NET序列化的一点技巧(附Demo)
- 用批处理来自动化项目编译及部署(附Demo)
- WCF绑定和行为在普通应用和SilverLight应用一些对比
- Windows服务调试小结(附Demo)
- 我是怎么处理其他网站恶意爬虫博客园的,希望大家喜欢
- 不同Framework下StringBuilder和String的性能对比,及不同Framework性能比(附Demo)
- Project Euler 110:Diophantine reciprocals II 丢番图倒数II
- HDU1022 Train Problem I 数据结构
- 贪心&Muddy roads
- ZYKeyboardUtil 两个Block搞定键盘遮盖输入控件
- Swift 航歌-做最好的开发者知识平台
- 2014年第五届蓝桥杯C/C++程序设计本科B组省赛 李白打酒(结果填空)
- 代码:用二分法求2x^3-4x^2+3x-6=0在-10~10之间的根(函数)
- ASP.NET 2.0构建动态导航的Web应用程序(TreeView和Menu ) (海东的技术资料)
- 接口略解