由Windows服务托管的WCF服务上的crossdomain.xml

问题描述:

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

这是我的主要服务:

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:服务没有应用程序(非基础结构)端点。 这可能是因为没有为您的应用程序找到配置文件, 或因为在配置文件中找不到匹配服务名称的服务元素,或者因为在服务元素中没有定义端点。

我已经搜索和搜索,仍然不知道该怎么做,任何人都可以给我一些建议吗?

+0

有没有人可以帮忙? –

我有同样的问题,这里是我如何解决它。 首先,创建一个新的服务类当客户端请求它,将成为了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> 

...而且应该这样做!