【问题标题】:crossdomain.xml on WCF Service hosted by Windows Service由 Windows 服务托管的 WCF 服务上的 crossdomain.xml
【发布时间】:2015-10-15 13:21:25
【问题描述】:

我正在尝试使托管 WCF 服务的 Windows 服务跨域兼容。 经过数小时的搜索,我被告知我需要创建另一个服务来加载 crossdomain.xml 和 clientaccesspolicy.xml 文件,以便 Windows 托管的 WCF 服务可以在任何域上运行。

这是我的主要服务:

Namespace UmbrellaMobileService


<RunInstaller(True)> _
Public Class ProjectInstaller
    Inherits Installer
    Private process As ServiceProcessInstaller
    Private service As ServiceInstaller
    Private components As System.ComponentModel.Container

    Public Sub New()
        process = New ServiceProcessInstaller()
        process.Account = ServiceAccount.LocalSystem
        service = New ServiceInstaller()
        service.ServiceName = "UmbrellaMobileService"
        service.DisplayName = "Umbrella Mobile Service"
        service.Description = "Handels Umbrella Mobile Requests."
        Installers.Add(process)
        Installers.Add(service)
    End Sub
End Class

<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession)> _
Public Class UmbrellaMobileService
    Inherits ServiceBase
    Public serviceHost As ServiceHost = Nothing
    Public CrossDomainServiceHost As ServiceHost = Nothing

    Public Shared Sub Main()
        ServiceBase.Run(New UmbrellaMobileService())
    End Sub

    Public Sub New()
        ServiceName = "UmbrellaMobileService"
    End Sub

    'Start the Windows service.
    Protected Overloads Overrides Sub OnStart(ByVal args As String())
        If serviceHost IsNot Nothing Then
            serviceHost.Close()
        End If
        serviceHost = New WebServiceHost(GetType(UmbrellaService), New Uri("http://localhost/UmbrellaMobileService"))
        serviceHost.AddServiceEndpoint(GetType(IUmbrellaMobileService), New WebHttpBinding(), "http://localhost/UmbrellaMobileService")
        CrossDomainServiceHost = New ServiceHost(GetType(CrossDomainService))

        Else
            System.Diagnostics.EventLog.WriteEntry("Umbrella Mobile Service", objIniFile.ErrorMessage, EventLogEntryType.Error)
            serviceHost.Close()
            CrossDomainServiceHost.Close()
        End If

        serviceHost.Open()
        CrossDomainServiceHost.Open()
    End Sub

    ' Stop the Windows service.
    Protected Overloads Overrides Sub OnStop()
        If serviceHost IsNot Nothing Then
            serviceHost.Close()
            CrossDomainServiceHost.Close()
            serviceHost = Nothing
        End If
    End Sub
End Class

<AspNetCompatibilityRequirements(Requirementsmode:=AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class UmbrellaService
    Inherits System.Web.Services.WebService
    Implements IUmbrellaMobileService

    Function GetCustomers() As Stream Implements IUmbrellaMobileService.GetCustomers
    'Function Logic
    End Function


End Class

结束命名空间

这是我的主要服务的实现:

Namespace UmbrellaMobileService
<ServiceContract()> _
Public Interface IUmbrellaMobileService


    <OperationContract()> _
       <WebInvoke(Method:="GET", BodyStyle:=WebMessageBodyStyle.Bare, ResponseFormat:=WebMessageFormat.Json, RequestFormat:=WebMessageFormat.Json)> _
    Function GetCustomers() As Stream


End Interface

结束命名空间

这是我被建议添加的“跨域服务”:

Namespace UmbrellaMobileService
Public Class CrossDomainService
    Implements ICrossDomainService
    Public Function ProvidePolicyFile() As System.ServiceModel.Channels.Message Implements ICrossDomainService.ProvidePolicyFile
        Dim filestream As FileStream = File.Open("ClientAccessPolicy.xml", FileMode.Open)
        ' Either specify ClientAccessPolicy.xml file path properly
        ' or put that in \Bin folder of the console application
        Dim reader As XmlReader = XmlReader.Create(filestream)
        Dim result As System.ServiceModel.Channels.Message = Message.CreateMessage(MessageVersion.None, "", reader)
        Return result
    End Function
End Class

结束命名空间

这是它的实现:

Namespace UmbrellaMobileService
<ServiceContract()> _
Public Interface ICrossDomainService
    <OperationContract(), WebGet(UriTemplate:="ClientAccessPolicy.xml")> _
    Function ProvidePolicyFile() As Message
End Interface

结束命名空间

我的配置文件如下所示:

<?xml version="1.0"?>
<configuration>
    <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
        <behaviors>
            <serviceBehaviors>
                <behavior name="MyServiceBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior name="CrossDomainServiceBehavior">
                    <webHttp/>
            </behavior>
            </endpointBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="MyServiceBehavior" name="UmbrellaMobileService.UmbrellaMobileService">
                <endpoint address="" binding="basicHttpBinding" contract="UmbrellaMobileService.IUmbrellaMobileService">
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8731/UmbrellaMobileService"/>
                    </baseAddresses>
                </host>
            </service>
            <service name="UmbrellaMobileService.CrossDomainService">
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8731/"/>
                    </baseAddresses>
                </host>
                <endpoint address="" binding="webHttpBinding" contract="UmbrellaMobileService.ICrossDomainService" behaviorConfiguration="CrossDomainServiceBehavior"/>
            </service>
        </services>
    </system.serviceModel>
    <system.web>
        <compilation debug="true"/></system.web></configuration>

现在,当我尝试运行此服务时出现此错误:

服务无法启动。 System.InvalidOperationException:服务有零个应用程序(非基础设施)端点。 这可能是因为没有为您的应用程序找到配置文件, 或者因为在配置文件中找不到与服务名称匹配的服务元素,或者因为在服务元素中没有定义端点。

找了又找,还是不知道怎么办,谁能给点建议?

【问题讨论】:

  • 有人可以帮忙吗?

标签: wcf service


【解决方案1】:

我遇到了同样的问题,这就是我解决它的方法。 首先,创建一个新的服务类,它会在客户端请求时为 clientaccesspolicy.xml 提供服务:

[ServiceContract]
public class CrossDomainPolicyService
{
    private Stream StringToStream(string result)
    {
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return new MemoryStream(Encoding.UTF8.GetBytes(result));
    }

    [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
    public Stream GetClientAccessPolicy()
    {
        string result = @"<?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(result);
    }
}

接下来,修改您的 app.config 文件以公开新服务:

      <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="policyBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service name="MyNamespace.MyService">
        <endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9876/MyService/" />
          </baseAddresses>
        </host>
      </service>
      <service name="MyNamespace.CrossDomainPolicyService">
        <endpoint address="" binding="webHttpBinding" contract="MyNamespace.CrossDomainPolicyService" behaviorConfiguration="policyBehavior">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <!-- Root Domain where the other service is hosted -->
            <add baseAddress="http://localhost:9876/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>

...应该这样做!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    • 2012-04-28
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    相关资源
    最近更新 更多