Динамические конечные точки в ServiceReferences.ClientConfig - PullRequest
16 голосов
/ 09 сентября 2011

При создании приложения оно часто развертывается в разных средах (test, dev, prod), поэтому адреса конечных точек меняются. Поскольку ServiceReferences.ClientConfig создается как часть файла .xap Silverlight, трудно изменить конечные точки после построения решения, как это часто делается с помощью web.config.

Я довольно долго искал это, но я не могу понять, что является лучшей практикой здесь, поэтому мой вопрос:

Каков наилучший метод настройки динамического адреса конечной точки wcf в silverlight?

Чтобы уточнить, в зависимости от того, на каком сервере запущено приложение (test, dev, prod), конечные точки меняются:

  <endpoint
    name="MyService"
    address="http://testserv/MyService.svc"
    binding="basicHttpBinding"
    bindingConfiguration="MybasicHttpBinding"
    contract="MyApp.MyService"
             />

  <endpoint
    name="MyService"
    address="http://prodserv/MyService.svc"
    binding="basicHttpBinding"
    bindingConfiguration="MybasicHttpBinding"
    contract="MyApp.MyService"
             />

В каком-то смысле мне нужно, чтобы клиент silverlight знал, какой из них использовать, в зависимости от того, на каком сервере его / какая сборка компилируется.

Ответы [ 5 ]

26 голосов
/ 04 ноября 2011

Прочитав пост sLedgem и немного погуглив, я нашел идеальное решение, чтобы ServiceReferences работали как web.config.

Прежде всего: создайте разные файлы вручную;

ServiceReferences.Debug.ClientConfig
ServiceReferences.Release.ClientConfig

Вы также можете добавить свои собственные, если у вас больше двух конфигураций по умолчанию в Visual Studio.

Второе: добавьте зависимость файла в файл Project.csproj (откройте файл проекта в текстовом редакторе):

  <ItemGroup>
    <None Include="Properties\AppManifest.xml" />
    <Content Include="ServiceReferences.ClientConfig">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Include="ServiceReferences.Debug.ClientConfig">
      <DependentUpon>ServiceReferences.ClientConfig</DependentUpon>
    </Content >
    <Content Include="ServiceReferences.Release.ClientConfig">
      <DependentUpon>ServiceReferences.ClientConfig</DependentUpon>
    </Content >
  </ItemGroup>

Теперь, когда вы перезагрузите проект, вы увидите, что ServiceReferences.Release.ClientConfig можно развернуть в обозревателе решений, а при его развертывании вы увидите файл Release и Debug.

В-третьих: добавить правила преобразования в файл проекта непосредственно перед закрытием </Project>

(снова откройте его в текстовом редакторе)

<!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
  Other similar extension points exist, see Microsoft.Common.targets.   -->
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterCompile" Condition="exists('ServiceReferences.$(Configuration).ClientConfig')">
  <!-- Generate transformed ServiceReferences config in the intermediate directory -->
  <TransformXml Source="ServiceReferences.ClientConfig" Destination="$(IntermediateOutputPath)$(TargetFileName).ClientConfig" Transform="ServiceReferences.$(Configuration).ClientConfig" />
  <!-- Force build process to use the transformed configuration file from now on. -->
  <ItemGroup>
    <ServiceReferencesConfigWithTargetPath Remove="ServiceReferences.ClientConfig" />
    <ServiceReferencesConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).ClientConfig">
      <TargetPath>$(TargetFileName).ClientConfig</TargetPath>
    </ServiceReferencesConfigWithTargetPath>
  </ItemGroup>
</Target>

Что он делает, так этопосмотрите в соответствующем файле servicereferences, в зависимости от вашей конфигурации, и скопируйте / замените код, используя ту же библиотеку TransformXML, которую использует web.config.

Exдостаточно:

в моем ServiceReferences.ClientConfig у меня есть следующий код:

  <endpoint name="ICatalogueService" 
            address="address" 
            binding="basicHttpBinding"
            bindingConfiguration="My_basicHttpBinding" 
            contract="Services.ServiceInterfaces.ICatalogueService"/>

ServiceReferences.Release.ClientConfig:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <system.serviceModel>
    <client>
      <endpoint
        name="ICatalogueService"       
        address="http://server/Services/CatalogueService.svc"
        binding="basicHttpBinding"
        bindingConfiguration="My_basicHttpBinding"
        contract="Services.ServiceInterfaces.ICatalogueService"
        xdt:Transform="Replace" xdt:Locator="Match(name)" />
    </client>
    <extensions />
  </system.serviceModel>
</configuration>

Как видите, конечная точкабудет заменен, и сопоставление будет выполнено для атрибута name.

Если у вас есть какие-либо вопросы, дайте мне знать:)

6 голосов
/ 19 ноября 2012

Отличное решение проблемы
Мне не удалось заставить секцию <ItemGroup></ItemGroup> эффективно работать в моем решении.
Я удалил его и добавил следующий сценарий в событие Prebuild в проекте:

del $(ProjectDir)ServiceReferences.ClientConfig;
copy $(ProjectDir)ServiceReferences.$(ConfigurationName).ClientConfig $(ProjectDir)ServiceReferences.ClientConfig;
3 голосов
/ 13 сентября 2011

Вы можете сделать это во время выполнения, используя конструктор клиента WCF в SL, который принимает имя конфигурации конечной точки и адрес.Имя конфигурации конечной точки - просто «MyService» в вашем примере.Указанный вами аргумент адреса будет переопределять аргумент, включенный в ClientConfig.

Один из способов вычислить адрес вашей службы во время выполнения по SL - это (я не гарантирую, что она будет работать в любой конфигурации среды):

  1. Рассчитать кореньваш сайт, например, путем нахождения общей части Application.Current.Host.Source.AbsoluteUri и HtmlPage.Document.DocumentUri.AbsoluteUri.По сути, вы берете символы с начала более короткого пути, если они соответствуют символам без учета регистра в другом пути.
  2. Добавьте относительный путь к службам, если таковые имеются (здесь это не так).).
  3. Append MyService.svc

Дополнительная информация:

Это может показаться сложным, если у вас много служб, но все это может быть красиво переработано и сПомощь Unity довольно проста в использовании для любого сервиса.Например, я использую вспомогательную функцию, которая регистрирует клиент службы, и ее вызов выглядит следующим образом: ServicesHelper.RegisterService(«MyService»);Когда мне нужно создать экземпляр клиента службы, я просто разрешаю тип MyServiceContractClient с Unity, который использует конструктор инъекций для создания нового экземпляра моей службы, уже настроенного должным образом.Он также может справиться с ситуацией HTTPS.Дайте мне знать, если вам нужна дополнительная информация по этому поводу.

1 голос
/ 15 ноября 2012

randoms отвечает точно, кроме ОДНОЙ мелочи. Не отмечайте .Debug.ClientConfig и .Release.ClientConfig как «Содержимое». Пометить их как «Нет». Таким образом, ваши .Debug.ClientConfig и .Release.ClientConfig не будут помещены в ваш файл .xap. Вот что находится в моем файле проекта Silverilght (и он отлично работает):

<Content Include="ServiceReferences.ClientConfig">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="ServiceReferences.DEV.ClientConfig">
  <DependentUpon>ServiceReferences.ClientConfig</DependentUpon>
</None>
<None Include="ServiceReferences.TEST.ClientConfig">
  <DependentUpon>ServiceReferences.ClientConfig</DependentUpon>
</None>
<None Include="ServiceReferences.PROD.ClientConfig">
  <DependentUpon>ServiceReferences.ClientConfig</DependentUpon>
</None>
1 голос
/ 12 сентября 2011

Посмотрите здесь:

http://weblogs.asp.net/srkirkland/archive/2009/10/13/common-web-config-transformations-with-visual-studio-2010.aspx

, затем здесь

http://www.funkymule.com/post/2010/03/08/XML-Transform-on-Silverlight-ClientConfig-Files.aspx

Он использует тот же принцип, что и web.configпреобразования (т. е. web.config изменяется в зависимости от того, какую конфигурацию вы компилируете (т. е. release, debug), так что serviceref.config изменяется в соответствии с вашими прихотями во время компиляции. работает обаяние

...