获取 POST 端点以在自托管 (WebServiceHost) C# web 服务中工作?

Ted*_*Ted 1 c# wcf web-services http-post webservicehost

所以,我一直在搞 webservices 一段时间,我一直回到一些基础知识,我似乎永远不会正确。

问题 1:

在 .NET/C# 中使用 WebServiceHost 时,您可以使用 GET/POST/etc 定义方法/端点。设置一个 GET 方法很容易,而且它的工作方式非常直接,而且很容易理解它是如何工作的。例如:

[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/PutMessage/{jsonString}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string PutMessage(string jsonString);
Run Code Online (Sandbox Code Playgroud)

如果我调用 http:///MyWebService/PutMessage/{MyJsonString} 我会通过该方法,并且一切都很好(或多或少)。

但是,当我将其定义为POST时,这意味着什么?

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/PutMessage/{jsonString}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
string PutMessage(string jsonString);
Run Code Online (Sandbox Code Playgroud)

UriTemplate 在这里做什么?如果我执行 POST,我希望数据不包含在 URI 中,而是包含在帖子的“数据部分”中。但是我是否在数据部分定义了变量名?WebServiceHost/.NET 如何知道帖子的“数据部分”中包含的内容要放入变量 jsonString 中?我如何从客户端(不是 C#,我们说 JQuery)发布数据,以便在服务器端正确解释它?

(WebMessageFormat 是如何影响事物的?我到处都读过这方面的内容(MSDN、Stackoverflow 等),但还没有找到明确而好的答案。)

问题2:

在我试图理解这一点时,我想我会制作一个非常简单的 POST 方法,如下所示:

[OperationContract]
[WebInvoke]
string PutJSONRequest(string pc);
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用 Fiddler 调用此方法,但这根本不起作用。我刚刚收到一个 400 错误,说“HTTP/1.1 400 错误请求”。我在方法代码的第一行有一个断点,方法本身不包含任何内容:

public string PutJSONRequest(string pc)
{
    return null;
}
Run Code Online (Sandbox Code Playgroud)

同样,.NET 如何知道我使用 Fiddler 发布的内容应该包含在“string pc”中?它如何将其解释为字符串,以及什么类型的字符串(UT8、ASCII 等)?

这是从 Fiddler 发送的 RAW HTTP 请求:

POST http://<myip>:8093/AlfaCustomerApp/PutJSONRequest HTTP/1.1
User-Agent: Fiddler
Host: <myip>:8093
Content-Length: 3
Content-type: application/x-www-form-urlencoded; charset=UTF-8

asd
Run Code Online (Sandbox Code Playgroud)

就我所见,我使用什么类型的内容类型并不重要。

回应是标准的事情,我无法控制自己:

HTTP/1.1 400 Bad Request
Content-Length: 1165
Content-Type: text/html
Server: Microsoft-HTTPAPI/2.0
Date: Mon, 15 Oct 2012 15:45:02 GMT

[then HTML code]
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激。谢谢。

L.B*_*L.B 5

我认为一个简单的代码可以回答你所有的问题

Task.Factory.StartNew(()=>StartServer());
Thread.Yield();
StartClient();
Run Code Online (Sandbox Code Playgroud)
void StartServer()
{
    Uri uri = new Uri("http://localhost:8080/test");
    WebServiceHost host = new WebServiceHost(typeof(WCFTestServer), uri);
    host.Open();
}

void StartClient()
{
    try
    {
        WebClient wc = new WebClient();

        //GET
        string response1 = wc.DownloadString("http://localhost:8080/test/PutMessageGET/abcdef");
        //returns: "fedcba"

        //POST with UriTemplate
        string response2 = wc.UploadString("http://localhost:8080/test/PutMessagePOSTUriTemplate/abcdef",
                                            JsonConvert.SerializeObject(new { str = "12345" }));
        //returns: fedcba NOT 54321


        //POST with BodyStyle=WebMessageBodyStyle.WrappedRequest
        //Request: {"str":"12345"}
        wc.Headers["Content-Type"] = "application/json";
        string response3 = wc.UploadString("http://localhost:8080/test/PutMessagePOSTWrappedRequest",
                                            JsonConvert.SerializeObject(new { str="12345" }));

        //POST with BodyStyle=WebMessageBodyStyle.Bare
        wc.Headers["Content-Type"] = "application/json";
        string response4 = wc.UploadString("http://localhost:8080/test/PutMessagePOSTBare", "12345" );

    }
    catch (WebException wex)
    {
        Console.WriteLine(wex.Message);
    }
}
Run Code Online (Sandbox Code Playgroud)
[ServiceContract]
public class WCFTestServer
{
    [OperationContract]
    [WebInvoke(Method = "GET", UriTemplate = "/PutMessageGET/{str}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    public string PutMessageGET(string str)
    {
        return String.Join("", str.Reverse());
    }

    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "/PutMessagePOSTUriTemplate/{str}", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    public string PutMessagePOSTUriTemplate(string str)
    {
        return String.Join("", str.Reverse());
    }

    [OperationContract]
    [WebInvoke(Method = "POST", BodyStyle=WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    public string PutMessagePOSTWrappedRequest(string str)
    {
        return String.Join("", str.Reverse());
    }

    [OperationContract]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    public string PutMessagePOSTBare(string str)
    {
        return String.Join("", str.Reverse());
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:你可以在这里找到 JsonConvert