Попытка вызвать службу WCF с помощью WebRequest - PullRequest
1 голос
/ 04 марта 2010

У меня есть служба WCF, которая должна вызываться сторонним приложением, публикующим некоторый необработанный XML.

Я пытаюсь протестировать свой сервис, создав простой WebRequest и отправив запрос в сервис.

Вот мой сервисный код:

Интерфейс:

    [ServiceContract(Namespace = "http://test.mydomain.com")]
public interface ITest
{
    [WebInvoke(UriTemplate = "", BodyStyle = WebMessageBodyStyle.Bare, Method="POST")]
    [OperationContract]
    Stream SaveXML(Stream input);
}

Услуги:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(Namespace = "http://test.mydomain.com")]
public class Test : ITest
{
    public Stream SaveXML(Stream input)
    {
        StreamReader streamReader = new StreamReader(input);
        string rawString = streamReader.ReadToEnd();
        streamReader.Dispose();

        // here need to save the input stream to xml format file
        Encoding encoding = Encoding.GetEncoding("ISO-8859-1");
        WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
        byte[] returnBytes = encoding.GetBytes(rawString);
        return new MemoryStream(returnBytes);
    }
}

конфигурация:

    <services>
  <service behaviorConfiguration="Blah.TestBehavior" name="Blah.Test">
    <endpoint address="http://localhost:51494/Blah/Test.svc" binding="basicHttpBinding" contract="Blah.ITest">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>

код неисправного клиента:

            string postData = "<Message version=\"1.5\" xmlns=\"http://test.mydomain.com\" ><books>Blah</books></Message>";
        WebRequest request = WebRequest.Create("http://localhost:51494/Blah/Test.svc/SaveXML");
        request.Method = "POST";

        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        request.ContentType = "application/x-www-form-urlencoded";
        //request.ContentType = "text/xml; charset=utf-8";
        //request.ContentType = "text/xml;";
        //request.ContentType = "application/xml;";
        request.ContentLength = byteArray.Length;

        Stream dataStream = request.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();

        // Get the response.
        WebResponse response = request.GetResponse();

В этой последней строке я получаю сообщение об ошибке 400 (неверный запрос) или 415 (неподдерживаемый тип носителя), в зависимости от того, какой тип содержимого указывать.

Кроме того, если я добавлю ссылку на службу в моем клиентском приложении и вызову службу с помощью API, она будет работать нормально. Буду очень признателен за любые идеи, так как я новичок в WCF и полностью озадачен.

Ответы [ 2 ]

7 голосов
/ 05 марта 2010

Я думаю, что вы смешиваете две разные вещи:

  1. WebRequest и атрибут POST и [WebInvoke] предполагают, что вы пытаетесь сделать что-то вроде REST
  2. Однако в конфигурации вашей службы basicHttpBinding - протокол SOAP, который не будет работать с WebRequest

Итак - примите решение!

Хотите использовать SOAP? Тогда у вас все в порядке с BasicHttpBinding, как есть, но вы не можете получить доступ к SOAP-сервису, как это делается из WebRequest с POST - вам нужно использовать SOAP-клиент, сгенерированный Visual Studio или svcutil.exe в командной строке.

Вы хотите использовать WebRequest и простой POST-запрос? Затем вам нужно создать службу WCF на основе REST - используйте webHttpBinding и WebServiceHost (в отличие от простого ServiceHost).

Для служб WCF на основе SOAP посетите Центр разработчиков WCF на MSDN .

Для служб WCF на основе REST (к которым вы можете перейти в своем браузере и к которым можно обращаться из WebRequest), посетите Центр разработчиков REST WCF на MSDN и посмотрите на превосходные серия скринкастов от Pluralsight о разработке на основе REST в WCF - в частности:

1 голос
/ 17 июля 2012

basicHttpBinding также подходит!

Я провожу почти целый день, выясняя, что не так с WebRequest для службы WCF с basicHttpBinding, и оказалось, что я пропустил небольшую, но важную вещь: SOAPAction заголовок имеетустановить!

newRequest.Headers["SOAPAction"] = "http://tempuri.org/INotificationService/MyMethodName"
...