Конфигурирование поведения XML-RPC для размещенного в IIS файла .SVC? - PullRequest
4 голосов
/ 23 июня 2010

Я использую реализацию XML-RPC Клеменса Вастерса для реализации конечной точки XML-RPC. Когда я размещаю службу в консольном приложении, она работает нормально.

Я бы хотел разместить его в приложении ASP.NET MVC, поэтому я использую файл .SVC. Это частично работает. Когда я просматриваю файл .SVC, я вижу обычные вещи "Вы создали службу".

Однако, когда я указываю свой XML-RPC-клиент (Windows Live Writer) в том же месте, я получаю «400 неверных запросов». Я предполагаю, что это потому, что мой сервис неправильно представлен как XML-RPC.

Я попытался настроить поведение конечной точки в Web.config следующим образом:

<system.serviceModel>
  <services>
    <service name="AnotherBlogEngine.Web.Api.BlogApi">
      <endpoint address=""
                binding="webHttpBinding"
                contract="AnotherBlogEngine.Web.Api.IBlogApi"
                behaviorConfiguration="xmlRpcBehavior" />
  </service>
  </services>
  <extensions>
    <behaviorExtensions>
      <add name="xmlRpc"
           type="AnotherBlogEngine.XmlRpc.XmlRpcEndpointBehaviorElement, \
                 AnotherBlogEngine.XmlRpc" />
    </behaviorExtensions>
  </extensions>
  <behaviors>
    <endpointBehaviors>
      <behavior name="xmlRpcBehavior">
        <xmlRpc/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

... но это не работает. Что я делаю неправильно? У меня правильный Web.config, или у меня все неправильно? Нужно ли мне указывать собственную фабрику в моем файле .SVC, чтобы разобраться в поведении?

Кстати, файл .SVC выглядит так:

<%@ ServiceHost Language="C#" Debug="true"
    Service="AnotherBlogEngine.Publishing.Service.BlogApi, \
             AnotherBlogEngine.Publishing.Service" %>

Примечание : Эти обратные слеши на самом деле отсутствуют; они просто для переноса строк.

Кроме того, в данный момент я просто тестирую это в Кассини (VS2010), а не в IIS, но я буду нацеливаться на IIS 7.x.

Обновление: Это определенно, по крайней мере, смотрит на мое расширение: оно вызывает XmlRpcEndpointBehaviorElement.get_BehaviorType, и если XmlRpcEndpointBehavior не реализует IEndpointBehavior, я получаю сообщение об ошибке (отображается на месте страницы «Вы создали сервис»).

Однако, точки останова на других методах в любом классе не достигаются.

Если я включаю трассировку WCF, в файле журнала отображается «неопознанная версия сообщения».

1 Ответ

2 голосов
/ 27 июня 2010

Вот шаги, чтобы заставить это работать:

  1. Загрузить образец XML-RPC для WCF
  2. Решение содержит 3 проекта: Microsoft.Samples.XmlRpc, TinyBlogEngine и TinyBlogEngineClient.
  3. Добавить 4-й проект к решению типа ASP.NET (я назвал его TinyBlogEngineWeb)

В новом проектессылка Microsoft.Samples.XmlRpc и TinyBlogEngine.

Добавьте в этот веб-приложение файл test.svc, который выглядит следующим образом:

<%@ ServiceHost Language="C#" Debug="true" Service="TinyBlogEngine.BloggerAPI, TinyBlogEngine" %>

Добавьте класс XmlRpcEndpointBehaviorExtension в новый проект:

namespace TinyBlogEngineWeb
{
    public class XmlRpcEndpointBehaviorExtension : BehaviorExtensionElement
    {
        protected override object CreateBehavior()
        {
            // this comes from Microsoft.Samples.XmlRpc
            return new XmlRpcEndpointBehavior();
        }

        public override Type BehaviorType
        {
            get { return typeof(XmlRpcEndpointBehavior); }
        }
    }
}

Наконец, system.serviceModel часть web.config должна выглядеть следующим образом:

<system.serviceModel>
  <services>
    <service name="TinyBlogEngine.BloggerAPI" behaviorConfiguration="returnFaults">
      <endpoint address="/blogger"
                binding="webHttpBinding"
                contract="TinyBlogEngine.IBloggerAPI"
                behaviorConfiguration="xmlRpcBehavior" />
    </service>
  </services>

  <behaviors>
    <serviceBehaviors>
      <behavior name="returnFaults">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>

    <endpointBehaviors>
      <behavior name="xmlRpcBehavior">
        <xmlRpc/>
      </behavior>
    </endpointBehaviors>
  </behaviors>

  <extensions>
    <behaviorExtensions>
      <add name="xmlRpc"
           type="TinyBlogEngineWeb.XmlRpcEndpointBehaviorExtension, TinyBlogEngineWeb" />
    </behaviorExtensions>
  </extensions>
</system.serviceModel>

Наконец, измените консольное клиентское приложение, чтобы использовать адрес веб-проекта, и протестируйте:

Uri blogAddress = new UriBuilder(
    Uri.UriSchemeHttp, 
    "localhost", 
    1260, // use the appropriate port here
    "/test.svc/blogger"
).Uri;

Протестировано с Windows Live Writer и консольным клиентским приложением.Вы можете скачать мое тестовое решение здесь .

...