Какой правильный URI для отправки параметров через POST в WCF REST Services? - PullRequest
3 голосов
/ 30 июля 2010

Допустим, что я указал следующую REST-службу WCF по адресу "http://localhost/MyRESTService/MyRESTService.svc"

[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive")]
string Receive(string text);

. Теперь я могу вызвать свою службу REST в Fiddler по адресу" http://localhost/MyRESTService/MyRESTService.svc/receive" иэто работает (я получу возвращаемое значение).

Но что, если я хочу отправить параметры в мою службу REST?Должен ли я изменить определение моего интерфейса, чтобы оно выглядело так:

[ServiceContract]
public interface IMyRESTService
{
[OperationContract]
[WebInvoke(
  Method = "POST",
  UriTemplate = "/receive/{text}")]
string Receive(string text);

Теперь, если я вызову службу REST в Fiddler, используя адрес "http://localhost/MyRESTService/MyRESTService.svc/receive/mytext", он работает (отправляет параметр" mytext ""и я получу возвращаемое значение). Так это правильный URI для отправки параметров через POST?

Что меня смущает, так это то, что я не знаю, как именно использовать этот URI в кодев то же время, когда я отправляю параметры . У меня есть следующий код, который почти завершен для отправки POST-данных в службу REST WCF, но я не могу понять, как учитывать параметры с помощью URI.

Dictionary<string, string> postDataDictionary = new Dictionary<string, string>();
      postDataDictionary.Add("text", "mytext");

      string postData = "";
      foreach (KeyValuePair<string, string> kvp in postDataDictionary)
      {
        postData += string.Format("{0}={1}&", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value));
      }
      postData = postData.Remove(postData.Length - 1); 

      Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/receive");
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
      req.Method = "POST";
      byte[] postArray = Encoding.UTF8.GetBytes(postData);
      req.ContentType = "application/x-www-form-urlencoded";
      req.ContentLength = postArray.Length;

      Stream dataStream = req.GetRequestStream();
      dataStream.Write(postArray, 0, postArray.Length);
      dataStream.Close();

      HttpWebResponse response = (HttpWebResponse)req.GetResponse();
      Stream responseStream = response.GetResponseStream();
      StreamReader reader = new StreamReader(responseStream);

      string responseString = reader.ReadToEnd();

      reader.Close();
      responseStream.Close();
      response.Close();

Если я захочу отправить параметры (например, "mytext") в коде через POST, если код URI будет

,

Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/receive");

или этим (это работает, но это не имеет никакого смысла, так как параметры должны быть добавлены другим способом, а не напрямую к адресу URI)

Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/receive/mytext");

Я рад, что вы можете мне помочь, это не может быть таксложно с WCF REST Services.

Ответы [ 2 ]

4 голосов
/ 03 августа 2010

Итак, если вы хотите отправить необработанные данные, такие как XML, в службу WCF REST (а также вернуть), вот как это сделать. Но я должен сказать, что до того, как я нашел это решение, я потратил много времени на поиски в Google, потому что все примеры говорили только об отправке параметров в URI (давайте, общий сценарий - это отправка XML, а вы не можете сделать это должным образом в URI). И когда, наконец, я нашел правильные примеры кода, выяснилось, что этого недостаточно в WCF, когда я получил ошибку «400 Bad Request». Эта ошибка была вызвана тем фактом, что WCF не может использовать мой необработанный XML, если я не форсирую его, переопределив его с помощью некоторого пользовательского кода (давай, что ты думаешь, Microsoft ?, исправьте это в следующей версии .NET Фреймворк). Так что я совсем не удовлетворен, если делать такие простые вещи может быть так сложно и отнимает много времени).

** IMyRESTService.cs (код на стороне сервера) **

[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
Stream Receive(Stream text);

** код на стороне клиента **

XmlDocument MyXmlDocument = new XmlDocument();
MyXmlDocument.Load(FilePath);
byte[] RequestBytes = Encoding.GetEncoding("iso-8859-1").GetBytes(MyXmlDocument.OuterXml);

Uri uri = new Uri("http://localhost/MyRESTService/MyRESTService.svc/Receive");

Request.ContentLength = RequestBytes.Length;

Request.Method = "POST";

Request.ContentType = "text/xml";

Stream RequestStream = Request.GetRequestStream();
RequestStream.Write(RequestBytes, 0, RequestBytes.Length);
RequestStream.Close();

HttpWebResponse response = (HttpWebResponse)Request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string ResponseMessage = reader.ReadToEnd();
response.Close();

** XmlContentTypeMapper.cs (пользовательский код на стороне сервера, который заставляет WCF принимать необработанный XML) **

public class XmlContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
return WebContentFormat.Raw;
}
}

** Web.config (параметры конфигурации на стороне сервера для использования пользовательского кода)

<endpoint binding="customBinding" bindingConfiguration="XmlMapper" contract="MyRESTService.IMyRESTService"
           behaviorConfiguration="webHttp"    />

<bindings>
  <customBinding>
    <binding name="XmlMapper">
      <webMessageEncoding webContentTypeMapperType="MyRESTService.XmlContentTypeMapper, MyRESTService"/>
      <httpTransport manualAddressing="true"/>
    </binding>
  </customBinding>
</bindings>

Вызов веб-службы WCF с помощью HTTP POST http://social.msdn.microsoft.com/forums/en-us/wcf/thread/4074F4C5-16CC-470C-9546-A6FB79C998FC

2 голосов
/ 25 августа 2011

У меня была такая же проблема, и, используя Fiddler, я получал ошибку 403 (Bad Request) каждый раз, когда пытался опубликовать сообщение с помощью Body.Исправление, которое заняло у меня пару часов, - это изменить тип контента на application / xml и отправить тело в виде XML.

Это строка, которую я использовал в заголовке в Fiddler:

Content-Type: application/xml;charset=UTF-8 

Теперь я не использовал библиотеку Microsoft.Http, в моем клиенте я использовал WebRequest, чтобы сделать сообщение, и установив Content-Type на:

request.ContentType = "application/xml;charset=UTF-8";

Работал нормально дляme.

Теперь, если вы хотите использовать URI для отправки параметров, я рекомендую использовать WebGet вместо WebInvoke с POST.

...