WCF REST 自托管 400 错误请求 [英] WCF REST Self-Hosted 400 Bad Request
问题描述
我在使用自托管 WCF REST 服务时遇到问题.
I'm having a problem with a self-host WCF REST service.
当我尝试通过浏览器或 Fiddler 发出 GET 请求时,我收到 400 错误请求.跟踪正在报告 XmlException 的内部异常无法读取消息正文,因为它为空."
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."
我在 app.config 中没有任何配置(我需要任何配置吗?).我试过把WebServiceHost改成ServiceHost,返回WSDL,但是操作还是返回400.
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.
我在这里遗漏了什么?
// 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;
}
}
}
推荐答案
当您使用 WebServiceHost
时,您通常不需要添加服务端点 - 它会添加一个具有所有所需行为的端点使其成为Web HTTP"(又名 REST)端点(即,不使用 SOAP 的端点,您可以使用 Fiddler 之类的工具轻松使用,这似乎正是您想要的).另外,Web HTTP 端点未在 WSDL 中公开,因此您也不需要添加 ServiceMetadataBehavior
.
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.
现在为什么它不起作用 - 向 http://localhost:8000/Test
发送 GET 请求应该可以 - 在下面的代码中它可以.尝试运行此代码,并发送您之前使用 Fiddler 发送的请求,以查看不同之处.这应该指出您的问题所在.
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();
}
}
这篇关于WCF REST 自托管 400 错误请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!