WCF REST 4.0 PUT / POST / DELETE не работает (неверный запрос 400) - PullRequest
2 голосов
/ 14 декабря 2011

Я работал над настройкой службы WCF REST в .NET 4.0. У меня работают запросы GET, но любой запрос, связанный с отправкой данных на сервер, завершается с ошибкой HTTP 400 Bad Request.

Это мой простой сервис:

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1
{
    [WebGet(UriTemplate = "")]
    public string HelloWorld()
    {
        return "hello world";
    }

    [WebInvoke(UriTemplate = "", Method = "POST")]
    public string HelloWorldPost(string name)
    {
        return "hello " + name;
    }
}

Мой Web.config:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <protocolMapping>
      <add scheme="http" binding="webHttpBinding" />      
    </protocolMapping>
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

</configuration>

И мой global.asax:

public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes();
    }

    private void RegisterRoutes()
    {
        RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));
    }
}

В принципе, все по умолчанию из шаблона, но я только упростил Service1. Я пробовал запустить его через отладчик и передать запрос через Fiddler, запустить его в IIS и сделать то же самое, а также использовать простое консольное приложение для подделки POST, но я всегда получаю ошибку 400 Bad Request, и у меня нет Идея почему. Я просмотрел весь интернет и ничего не могу понять.

Я пробовал оба следующих примера запроса (ни одна из них не работает):

XML:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">String content</string>

JSON:

"String content"

Ответы [ 2 ]

6 голосов
/ 18 декабря 2011

Правильно ли установлен заголовок Content-Type в вашем запросе? Для XML-запроса это должно быть text/xml, а для JSON - application/json. Ваш код работает для меня, когда я устанавливаю Content-Type в Fiddler.

Вы также должны установить заголовок Accept в вашем GET либо на text/xml, либо на application/json в зависимости от того, в каком формате вы хотите получить ответ. Это нормально для POST, так как сервер будет считать, что вы хотите ответ в том же формате, что и запрос, потому что вы установили automaticFormatSelectionEnabled="true" в своем файле web.config. Подробнее о выборе формата в WCF REST можно узнать здесь: http://blogs.msdn.com/b/endpoint/archive/2010/01/18/automatic-and-explicit-format-selection-in-wcf-webhttp-services.aspx

1 голос
/ 20 декабря 2011

Ваши атрибуты не должны быть в реализации, они должны быть в договоре на эксплуатацию. Вы также должны убедиться, что у вас есть любые именованные параметры, включенные в UriTemplate. Они чувствительны к регистру, поэтому должны точно соответствовать.

IService.cs

[ServiceContract]
public class IService1
{
    [WebGet(UriTemplate = "")]
    [OperationContract]
    public string HelloWorld();

    [WebInvoke(UriTemplate = "/{name}", Method = "POST")]
    [OperationContract]
    public string HelloWorldPost(string name);
}

Service.cs

public class Service1 : IService
{

    public string HelloWorld()
    {
        return "hello world";
    }

    public string HelloWorldPost(string name)
    {
        return "hello " + name;
    }
}

Вам также необходимо настроить службу в файле web.config в System.ServiceModel

<system.serviceModel>
    <services>
      <service name="Service1">
        <endpoint address="basic" binding="basicHttpBinding" contract="IService1" />
      </service>
    <services>
</system.serviceModel>

Это некоторые из основных концепций, которые должны помочь вам начать работу в правильном направлении. Если вы хотите начать хороший тестовый проект, просто используйте шаблон проекта "Приложение WCF" в VS2010. Он имеет большинство необходимых частей для вас. Надеюсь, это поможет!

...