Silverlight 2 跨域访问控件与WebService的资料整理

2016-08-20 10:51:43来源:作者:dotfun人点击

In other words, a page retrieved from somehost containing a Silverlight object tag with source attribute equal to http://someotherhost/somesite/silverlightcontrol.xap.Note the following points applicable to cross domain access:
Unlike the case where your xap file is served up from the same host, the Silverlight runtime checks the MIME type in the HTTP header of your xap content when it has been served up from a different host. So make sure that it is correctly set to application/x-silverlight-app (not application/x-silverlight-2 - which wasted a good couple of hours of my time). If you don't set it correctly you'll see the Silverlight runtime fetch the file (if you're spying in Fiddler or suchlike), then a great big nothing will happen. If you want to access the DOM on the page containing the control from within your control's code you'll need to set the enableHtmlAccess attribute to true in the object tag. If you want to access scriptable types in your control's code from JavaScript you will need to add the ExternalCallersFromCrossDomain attribute to the control's manifest and set it to ScriptableOnly. Note, however that you won't be able to subscribe to control events such as onload. 三个地方需要配置:
1、客户端Object代码里面添加属性: <param name="EnableHtmlAccess" value="true"> 客户端代码:
<object data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="http://servername/sitename/ClientBin/RESAPeopleEntity.xap" > <param name="onerror" value="onSilverlightError" > <param name="background" value="Red" > //Transparent <param name="InitParams" value="" + InitParams + "" > <param name="Windowless" value="True" > <param name="EnableHtmlAccess" value="true"> <a href=""> <img src="" > </a> </object>
<?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>
3、Sivlerlight工程项目中,Propertites文件夹下AppManifest.xml中添加 ExternalCallersFromCrossDomain="ScriptableOnly",AppManifest.xml内容如下所示:
<Deployment xmlns="" xmlns:x=""ExternalCallersFromCrossDomain="ScriptableOnly"> <Deployment.Parts> </Deployment.Parts></Deployment>
在 Silverlight 2 应用程序清单中移除了针对 ExternalCallersFromCrossDomain 属性的 FullAccess 选项
影响的对象:仅限使用此功能组合的 Silverlight 2 应用程序:
在与宿主 HTML 页不同的域中部署 XAP,并且
在根元素上指定 ExternalCallersFromCrossDomain=”FullAccess” 的应用程序清单 (AppManifest.xaml) 受影响。
在跨域应用程序部署方案中省略了任意脚本的以下功能:沿元素树传递、注册事件并获取事件通知以及从脚本使用 Silverlight 1.0 Downloader。应用程序清单以前支持应用程序作者指定值为 NoAccess(跨域中的默认值)、ScriptableOnly 和 FullAccess 的 ExternalCallersFromCrossDomain 属性。已移除对 FullAccess 选项的支持。
以前依赖于 FullAccess 选项的很多功能现在可以通过可编写脚本的对象功能实现,并且不会给您增加多少工作量。
In order for a Silverlight (or Flash) app coming from one domain to be able to consume data from services in a different domain, the service must "allow" the app to do so by providing a policy file which grants access (to prevent all sorts of cross-site scripting attacks). This policy file must be located in the root of the "domain" (hostname + port), so if your service is located at, the policy file must be located at (or in case of the Flash format). That's fairly easy to do on a IIS-hosted service (simply put the static policy file in the root of the web), but for self-hosted apps it isn't as simple (there's no "root" of the web).
To solve this problem for self-hosted WCF services, you can use the web programming model support fairly easily. Basically, you'd define the base address at the root of the domain, and have a web endpoint at the "" address. All the "real" service endpoints would then be in different addresses. The example below shows it in action:
public class SelfHostedServiceWithSilverlightPolicy{ [ServiceContract]public interface ITest { [OperationContract]string Echo(string text); } [ServiceContract]public interface IPolicyRetriever { [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]Stream GetSilverlightPolicy(); [OperationContract, WebGet(UriTemplate = "/crossdomain.xml")]Stream GetFlashPolicy(); }public class Service : ITest, IPolicyRetriever {public string Echo(string text) { return text; }Stream StringToStream(string result) {WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";return new MemoryStream(Encoding.UTF8.GetBytes(result)); }public Stream GetSilverlightPolicy() {string result = @"<?xml version=""1.0"" encoding=""utf-8""?><access-policy><cross-domain-access><policy><allow-from><domain uri=""*""/></allow-from><grant-to><resource path=""/"" include-subpaths=""true""/></grant-to></policy></cross-domain-access></access-policy>";return StringToStream(result); }public Stream GetFlashPolicy() {string result = @"<?xml version=""1.0""?><!DOCTYPE cross-domain-policy SYSTEM """"><cross-domain-policy><allow-access-from domain=""*"" /></cross-domain-policy>";return StringToStream(result); } }public static void Test() {string baseAddress = "http://" + Environment.MachineName + ":8000";ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic"); host.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; host.Description.Behaviors.Add(smb); host.Open();Console.WriteLine("Host opened");Console.Write("Press ENTER to close");Console.ReadLine(); host.Close(); }