WCF REST 自托管 400 错误请求 [英] WCF REST Self-Hosted 400 Bad Request

查看:53
本文介绍了WCF REST 自托管 400 错误请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用自托管 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆