2013-03-29 4 views
1

У меня возникла проблема с самообслуживанием службы WCF REST.WCF REST Self-Hosted 400 Bad Request

Когда я пытаюсь отправить GET через браузер или Fiddler, я получаю 400 Bad Request. Трассировка сообщает о внутреннем исключении XmlException. «Тело сообщения не может быть прочитано, потому что оно пусто».

У меня нет конфигурации в app.config (мне нужно что-нибудь?). Я попытался изменить WebServiceHost на ServiceHost, и WSDL возвращается, но операции все равно возвращаются 400.

Что мне здесь не хватает?

// Add Reference to System.ServiceModel and System.ServiceModel.Web 
using System; 
using System.Diagnostics; 
using System.ServiceModel; 
using System.ServiceModel.Description; 
using System.ServiceModel.Web; 

namespace WCFRESTTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var baseAddress = new Uri("http://localhost:8000/"); 
      var host = new WebServiceHost(typeof(RestService), baseAddress); 

      try 
      { 
       host.AddServiceEndpoint(typeof(IRestService), new WSHttpBinding(), "RestService"); 

       var smb = new ServiceMetadataBehavior(); 
       smb.HttpGetEnabled = true; 
       host.Description.Behaviors.Add(smb); 

       host.Open(); 
       Console.WriteLine("Service Running. Press any key to stop."); 
       Console.ReadKey(); 
      } 
      catch(CommunicationException ce) 
      { 
       host.Abort(); 
       throw; 
      } 
     } 
    } 

    [ServiceContract] 
    public interface IRestService 
    { 
     [OperationContract] 
     [WebGet(UriTemplate = "Test")] 
     bool Test(); 
    } 

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
    public class RestService : IRestService 
    { 
     public bool Test() 
     { 
      Debug.WriteLine("Test Called."); 
      return true; 
     } 
    } 
} 
+0

Какое определение «IRestService»? Какой URL вы отправляете в Fiddler? – carlosfigueira

+0

IRestService находится в указанном коде, и я пробовал все мыслимые комбинации URL. http: // localhost: 8000/RestService/Test http: // localhost: 8000/Test http: // localhost: 8000 /? WSDL и т. д. – Jay

ответ

2

При использовании WebServiceHost, как правило, не нужно, чтобы добавить конечную точку службы - это добавит один со всеми поведений, необходимых, чтобы сделать это «Web HTTP» (ака REST) ​​конечной точки (т.е. конечная точка, которая не использует SOAP, и вы можете легко потреблять такой инструмент, как Fiddler, который, кажется, вам нужен). Кроме того, Web HTTP endpoints aren't exposed in the WSDL, так что вам не нужно добавлять ServiceMetadataBehavior.

Теперь для почему это не сработает - отправка запроса GET на http://localhost:8000/Test должна работать - и в коде ниже. Попробуйте запустить этот код и отправив запрос, который вы отправляли ранее с помощью Fiddler, чтобы увидеть разницу. Это должно указывать на то, что у вас есть.

public class StackOverflow_15705744 
{ 
    [ServiceContract] 
    public interface IRestService 
    { 
     [OperationContract] 
     [WebGet(UriTemplate = "Test")] 
     bool Test(); 
    } 

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
    public class RestService : IRestService 
    { 
     public bool Test() 
     { 
      Debug.WriteLine("Test Called."); 
      return true; 
     } 
    } 

    public static void Test() 
    { 
     var baseAddress = new Uri("http://localhost:8000/"); 
     var host = new WebServiceHost(typeof(RestService), baseAddress); 

     // host.AddServiceEndpoint(typeof(IRestService), new WSHttpBinding(), "RestService"); 

     // var smb = new ServiceMetadataBehavior(); 
     // smb.HttpGetEnabled = true; 
     // host.Description.Behaviors.Add(smb); 

     host.Open(); 

     WebClient c = new WebClient(); 
     Console.WriteLine(c.DownloadString(baseAddress.ToString().TrimEnd('/') + "/Test")); 

     Console.WriteLine("Service Running. Press any key to stop."); 
     Console.ReadKey(); 
    } 
} 
+0

Я поклялся, что попробовал, но, видимо, нет. Итак, что же делает WebServiceHost по-другому? И какой рекомендуемый способ добавить «RestService» обратно в путь через базовый адрес? – Jay

+1

По умолчанию 'WebServiceHost' добавит конечную точку на базовый адрес. Поэтому, если вы хотите, чтобы ваша операция отвечала на 'http: // localhost: 8000/RestService/Test', вы можете добавить' RestService' в базовый адрес. – carlosfigueira