Skip to main content
 首页 » 编程设计

c#之让 POST 端点在自托管 (WebServiceHost) C# web 服务中工作

2024年01月25日24zfyouxi

所以,我已经在 web 服务上摆弄了一段时间,并且我一直在回到一些基础知识上,但我似乎从来没有做对过。

问题一:

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

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

如果我调用 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); 

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

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

问题2:

在我试图理解这一点的过程中,我想我会做一个非常简单的 POST 方法,如下所示:

[OperationContract] 
[WebInvoke] 
string PutJSONRequest(string pc); 

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

public string PutJSONRequest(string pc) 
{ 
    return null; 
} 

同样,.NET 如何知道我使用 Fiddler 发布的内容应该包含在“字符串 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 

据我所知,我使用什么类型的 Content-type 并不重要。

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

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] 

如有任何帮助,我们将不胜感激。谢谢。

请您参考如下方法:

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

Task.Factory.StartNew(()=>StartServer()); 
Thread.Yield(); 
StartClient(); 

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); 
    } 
} 

[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()); 
    } 
} 

PS:您可以找到 JsonConvert here