我有一个通过 WebServiceHost 托管的服务,我需要将一些调用委托给网络上的其他 REST 服务。
我构建了一个 ClientBase 具体类来处理这个问题。流程如下所示:
http://localhost:8000/users/my@email.com -> 我的 WebServiceHost 实例 -> ClientBase -> REST 服务
一切都运行良好,直到我意识到来自 ClientBase 的所有调用都使用 POST 作为动词。为了确保我没有对 ClientBase 做任何愚蠢的事情,我手动构建了一个 ChannelFactory 并使用它。不走运,无论 ClientBase、ChannelFactory 甚至 ServiceContract 装饰如何,每个调用仍然使用 POST。
然后我开始隔离代码,并意识到当原始调用不是来自我的 WebServiceHost 正在处理的请求中时,我的简单 ChannelFactory 工作。
这是一个蒸馏的 Program.cs,它展示了确切的问题,来自 Program.Main 的 MakeGetCall() 按预期工作,但来自 MyService.GetUser 的调用将始终 POST:
class Program
{
static void Main(string[] args)
{
//Program.MakeGetCall(); //This works as intended even when changing the WebInvoke attribute parameters
WebServiceHost webServiceHost = new WebServiceHost(typeof(MyService), new Uri("http://localhost:8000/"));
ServiceEndpoint serviceEndpoint = webServiceHost.AddServiceEndpoint(typeof(IMyServiceContract), new WebHttpBinding(), "");
webServiceHost.Open();
Console.ReadLine();
}
public static void MakeGetCall()
{
ServiceEndpoint endpoint = new ServiceEndpoint(
ContractDescription.GetContract(typeof(IMyServiceContract)),
new WebHttpBinding(),
new EndpointAddress("http://posttestserver.com/post.php"));
endpoint.Behaviors.Add(new WebHttpBehavior());
ChannelFactory<IMyServiceContract> cf = new ChannelFactory<IMyServiceContract>(endpoint);
IMyServiceContract test = cf.CreateChannel();
test.GetUser("test");
}
}
[ServiceContract]
public interface IMyServiceContract
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/users/{emailAddress}")]
string GetUser(string emailAddress);
}
public class MyService : IMyServiceContract
{
public string GetUser(string emailAddress)
{
Program.MakeGetCall(); //This will ALWAYS POST no matter if you are using [WebInvoke(Method="GET")] or even [WebGet]
return "foo";
}
}