I'm having a problem with a self-host WCF REST service.
When I try to issue a GET via browser or Fiddler, I get a 400 Bad Request. Tracing is reporting an inner exception of XmlException "The body of the message cannot be read because it is empty."
I don't have any configuration in app.config (do I need any?). I have tried changing WebServiceHost to ServiceHost, and WSDL is returned, but the operations still return 400.
What am I missing here?
// 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;
}
}
}
When you use the WebServiceHost
, you typically don't need to add a service endpoint - it will add one with all behaviors required to make it a "Web HTTP" (a.k.a. REST) endpoint (i.e., an endpoint which doesn't use SOAP and you can easily consume with a tool such as Fiddler, which seems to be what you want). Also, Web HTTP endpoints aren't exposed in the WSDL, so you don't need to add the ServiceMetadataBehavior
either.
Now for why it doesn't work - sending a GET request to http://localhost:8000/Test
should work - and in the code below it does. Try running this code, and sending the request you were sending before with Fiddler, to see the difference. That should point out what the issue you have.
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();
}
}
来源:https://stackoverflow.com/questions/15705744/wcf-rest-self-hosted-400-bad-request