Междоменное исключение с WcfSvcHost - PullRequest
4 голосов
/ 24 февраля 2010

и извините за еще один кросс-домен.

Я боролся с этим весь день и сейчас на грани кипения.

У меня есть проект приложения Silverlight (SLApp1), веб-проект для размещения Silverlight (SLApp1.Web) и проекта WCF (SLWcfService).

Сейчас я строю все вместе, и все проекты в одном решении. Веб-проект размещается в Visual Studio, а служба WCF - в WcfSvcHost.

Проблема в том, что из-за того, что web и wcf размещаются отдельно, возникает проблема с несколькими доменами, поэтому каждый раз, когда мое приложение Silverlight пытается выполнить вызов WCF, выдается исключение между доменами.

Я пытался:

  1. Добавление clientaccesspolicy.xml в C: \ inetpud \ wwwroot
  2. Использование webHttpBinding и использование метода ReadPolicy в службе

Проблема в том, что я все еще разрабатываю решение, поэтому публикация службы и размещение в IIS просто неосуществимо.

Почему это так невероятно сложно?

Пожалуйста, помогите!

Справочный материал:

My App.config:

     <system.serviceModel>
    <services>
      <service name="Test.Service1" behaviorConfiguration="Test.Service1Behavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8055" />
          </baseAddresses>
        </host>
        <endpoint address="Service1" binding="basicHttpBinding" contract="Test.IService1"/>
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior" contract="Test.WCFService.IClientAccessPolicy" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Test.WCFService.Service1Behavior">
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

Ответы [ 4 ]

1 голос
/ 24 февраля 2010

Хотя я не уверен, что это решит вашу проблему, я покажу вам, как мне удалось исправить подобный макет решения, и, возможно, некоторые шаги помогут вам.

Я создал решение с помощью проекта silverlight (domainexception), веб-проекта (domainexception.Web) и службы wcf (WcfServiceLibrary1). Я сделал конечную точку Service1 базовой HttpBinding, как в вашем App.config.

Затем я добавил сервисную ссылку в проект silverlight, и он создал его по следующему адресу:

"http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/"

Пытаясь запустить его таким образом, я также столкнулся с проблемой междоменной политики.

Затем я добавил к нему метод webHttpBinding и все еще обнаружил, что он не работает.

Итак, наконец я изменил базовый адрес с указанного выше на

http://localhost:8731

и это сработало.

В конце концов это сработало. Так вот как это выглядело в конце.

App.config

 <system.serviceModel>
<services>
  <service name="WcfServiceLibrary1.Service1" behaviorConfiguration="WcfServiceLibrary1.Service1Behavior">
    <host>
      <baseAddresses>
        <add baseAddress = "http://localhost:8731/" />
      </baseAddresses>
    </host>
    <endpoint address ="Service" binding="basicHttpBinding" contract="WcfServiceLibrary1.IService1">
      <identity>
        <dns value="localhost"/>
      </identity>
    </endpoint>
    <endpoint address="" binding="webHttpBinding" behaviorConfiguration="policyBehavior" contract="WcfServiceLibrary1.IService1"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="policyBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="WcfServiceLibrary1.Service1Behavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>

ServiceReferences.ClientConfig

<configuration>
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
                maxReceivedMessageSize="2147483647">
                <security mode="None" />
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:8731/Service" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
            name="BasicHttpBinding_IService1" />
    </client>
</system.serviceModel>

и мой веб-вызов для политики:

Интерфейс

[OperationContract, WebGet(UriTemplate="clientaccesspolicy.xml")]
    Stream ReturnPolicy();

Код

public System.IO.Stream ReturnPolicy()
    {
        string file = @"<?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 new MemoryStream(Encoding.UTF8.GetBytes(file));
    }
0 голосов
/ 25 февраля 2010

PolicyService (REST) ​​в проекте WCFService может решить эту проблему. Этот вид услуг позволяет отправить xml (clientAccessPolicy) в ответ. например, если ваш сервисный URL похож на: http://localhost:[port]/Design_Time_Addresses/MyService.svc

Тогда URL PolicyService будет: http://localhost:[port]/clientaccesspolicy.xml (этот тип запроса REST отправит клиентскую политику доступа в ответ на SilverlightClient).

Вот ссылка о том, как создать такой PolicyService: http://social.msdn.microsoft.com/Forums/en/wcf/thread/d145a38f-b9bb-4c8e-9eab-b728dacc19df

0 голосов
/ 24 февраля 2010

Хорошо, как-то у меня получилось, используя трюк REST и webHttpBinding. Я изменил способ чтения клиентской политики из файла для чтения, используя только строку с консом.

Вот как я решил проблему:

App.config:

 <system.serviceModel>
<services>
  <service name="Symphony.Server.WCFService.Service1" behaviorConfiguration="Symphony.Server.WCFService.Service1Behavior">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8055" />
      </baseAddresses>
    </host>
    <endpoint address="Service1" binding="basicHttpBinding" contract="Symphony.Server.WCFService.IService1"/>
    <endpoint address="" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior" contract="Symphony.Server.WCFService.IClientAccessPolicy" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="Symphony.Server.WCFService.Service1Behavior">
      <serviceMetadata httpGetEnabled="True" />
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="webHttpBehavior">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

IClientAccessPolicy.cs

[ServiceContract]
public interface IClientAccessPolicy
{
    [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
    Stream GetPolicy();
}

Service1.cs

public class Service1 : IService1, IClientAccessPolicy
{
    public IList<string> GetData(string value)
    {
        //Some logic
    }

    [OperationBehavior]
    public Stream GetPolicy()
    {
        const 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>";

        if (WebOperationContext.Current != null)
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return new MemoryStream(Encoding.UTF8.GetBytes(result));
    }

Примечание: Вы должны включить System.ServiceModel.Web в качестве ссылки

Спасибо

0 голосов
/ 24 февраля 2010

Я также столкнулся с такой же проблемой некоторое время назад. Я пришел к выводу, что пора ссылаться на dll проекта WCFService в WebProject (хостинг Silverlight Control) и изменить его файл web.config в соответствии с WCFService. Затем вместо использования WcfSvcHost Reference я использовал Reference из WebProject. Это был обходной путь, который я использовал.

Но вкратце немного сложнее применить политику клиентского доступа к службе, размещенной в WCFSvcHost.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...