【发布时间】:2009-08-25 17:33:54
【问题描述】:
* 读者注意:大量代码转储,胆小者不宜... *
你好,
我试图弄清楚如何使用 WCF 服务将 Silverlight 3 应用程序部署到 IIS7。我想我已经弄清楚了大部分但是由于某种原因我仍然遇到跨域错误。我倾向于认为该服务没有找到客户端访问策略,但我不确定如何确认这一点。我得到一个非常无用的异常(简单地说是 CrossDomainError)。内部异常不存在。以下是我部署应用程序所采取的步骤。如果有人看到任何不合时宜的东西,可以请他们指教吗?我现在想不出还有什么可戳的……
- 在 IIS 管理器中,我建立了一个新站点。我将它命名为 Silverlight,接受了一个同名的池,并接受了所有其余的默认值。我禁用了默认站点。我将 Web 根目录设置为 C:\WebApps
- 我将 Visual Studio Silverlight 客户端项目的发布版本中的所有文件都放入了 Web 根目录。
- 我将 Silverlight 客户端项目中的以下配置文件放在 Web 根目录中:ServiceReferences.ClientConfig、Silverlight.js。
- 我将 Silverlight.Web 项目的发布版本中的 /bin 目录放到了 Web 根目录中
- 我将 Silverlight.Web 版本构建中的以下文件放在 Web 根目录中:crossdomain.xml、clientaccesspolicy.xml、Service1.svc、Service1.svc.cs、Web.config。
- 我将 TestPage.html 文件重命名为 index.html。
我意识到其中许多都是多余的,但我已经没有东西可以尝试了,所以我开始添加任何看起来可能包含任何有用元数据的东西。
这是我的各种配置文件的代码:
clientaccesspolicy.xml:
<?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 include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
crossdomain.xml:
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
system.serviceModel配置,摘自Web.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SilverlightApplication2.Web.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="customBinding0">
<binaryMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="SilverlightApplication2.Web.Service1Behavior" name="SilverlightApplication2.Web.Service1">
<endpoint address="http://win-xqawq222tag:2721/Service1.svc" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
ServiceReferences.ClientConfig:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_Service1">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://win-xqawq222tag:2721/Service1.svc" binding="customBinding"
bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
name="CustomBinding_Service1" />
</client>
</system.serviceModel>
</configuration>
Service1.svc:
<%@ ServiceHost Language="C#" Debug="true" Service="SilverlightApplication2.Web.Service1" CodeBehind="Service1.svc.cs" %>
接下来是客户端代码的实现:
Service1.svc.cs:
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Text;
namespace SilverlightApplication2.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
[OperationContract]
public DoWorkResult DoWork()
{
// Add your operation implementation here
int i = new Random().Next();
string s = "test string";
DoWorkResult r = new DoWorkResult() { String = s, Integer = i };
return r;
}
// Add more operations here and mark them with [OperationContract]
}
[DataContract]
public class DoWorkResult
{
[DataMember]
public string String { get; set; }
[DataMember]
public int Integer { get; set; }
}
}
MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
ServiceReference1.Service1Client proxy = new SilverlightApplication2.ServiceReference1.Service1Client();
proxy.DoWorkCompleted += new EventHandler<SilverlightApplication2.ServiceReference1.DoWorkCompletedEventArgs>(proxy_DoWorkCompleted);
proxy.OpenAsync();
proxy.DoWorkAsync();
proxy.CloseAsync();
}
void proxy_DoWorkCompleted(object sender, SilverlightApplication2.ServiceReference1.DoWorkCompletedEventArgs e)
{
if (e.Error == null)
{
String.Text = "Test String is: " + e.Result.String;
Integer.Text = "Random Int is: " + e.Result.Integer;
}
else
{
String.Text = e.Error.Message + e.Error.InnerException.Message + e.Error.StackTrace;
Integer.Text = e.Error.Message + e.Error.InnerException.Message + e.Error.StackTrace;
}
}
}
}
所有这些都可以在 XP Pro 上的 VS 2008 中正常运行。在 Server2008 上的 IIS7 上,我可以在 http://localhost 或 http://[myComputerName] 处点击默认页面 index.html。
我也可以使用http://localhost/Service1.svc 的服务。我无法使用http://[compNameHere]/Service1.svc 访问该服务。它抱怨这个错误:
没有与给定的协议绑定匹配 地址 'http://win-xqawq222tag:2721/Service1.svc'。 协议绑定配置在 IIS 或 WAS 中的站点级别 配置。说明:一个 期间发生未处理的异常 当前网络的执行 要求。请查看堆栈跟踪 有关错误的更多信息 以及它起源于代码的位置。
异常详情: System.InvalidOperationException:否 协议绑定匹配给定的 地址 'http://win-xqawq222tag:2721/Service1.svc'。 协议绑定配置在 IIS 或 WAS 中的站点级别 配置。
来源错误:
产生了一个未处理的异常 在当前执行期间 网络请求。有关的信息 异常的起源和位置 可以使用异常识别 下面的堆栈跟踪。
堆栈跟踪:
[无效操作异常:否 协议绑定匹配给定的 地址 'http://win-xqawq222tag:2721/Service1.svc'。 协议绑定配置在 IIS 或 WAS 中的站点级别 配置。]
System.ServiceModel.Channels.TransportChannelListener.OnOpening() +11513378 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan 超时)+229
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(时间跨度 超时)+72[InvalidOperationException: ChannelDispatcher 在 'http://win-xqawq222tag:2721/Service1.svc' 合同“Service1”是 无法打开其 IChannelListener。] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(时间跨度 超时)+118
System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+261
System.ServiceModel.ServiceHostBase.OnOpen(时间跨度 超时)+107
System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)+261
System.ServiceModel.HostingManager.ActivateService(字符串 标准化虚拟路径)+121
System.ServiceModel.HostingManager.EnsureServiceAvailable(字符串 normalizedVirtualPath) +479[服务激活异常: 服务“/Service1.svc”不能 期间由于异常而激活 汇编。异常消息 是:ChannelDispatcher 在 'http://win-xqawq222tag:2721/Service1.svc' 合同“Service1”是 无法打开其 IChannelListener..] System.ServiceModel.AsyncResult.End(IAsyncResult 结果)+11531006
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult 结果)+194
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication 上下文,布尔流上下文)+176
System.ServiceModel.Activation.HttpHandler.ProcessRequest(HttpContext 上下文)+23
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean & completedSynchronously) +75没有与给定的协议绑定匹配 地址 'http://win-xqawq222tag:2721/Service1.svc'。 协议绑定配置在 IIS 或 WAS 中的站点级别 配置。
此外,我可以访问http://localhost/clientaccesspolicy.xml 和http://[computerNameHere]/clientaccesspolicy.xml 的策略文件。
还有什么需要看的吗?
【问题讨论】:
-
更新:从配置中删除端口:2721 允许我从 http://
/Service1.svc 访问服务,但是我仍然无法从 silverlight 应用程序访问服务。
标签: wcf iis-7 silverlight-3.0 windows-server-2008