簡體   English   中英

C# Web API 在 HTTP Post REST 客戶端中發送正文數據

[英]C# Web API Sending Body Data in HTTP Post REST Client

我需要發送這個 HTTP Post 請求:

 POST https://webapi.com/baseurl/login
 Content-Type: application/json

 {"Password":"password",
 "AppVersion":"1",
 "AppComments":"",
 "UserName":"username",
 "AppKey":"dakey" 
  }

它在 RestClient 和 PostMan 中效果很好,就像上面一樣。

我需要以編程方式進行此操作,但不確定是否要使用

WebClient、HTTPRequest 或 WebRequest 來實現這一點。

問題是如何格式化正文內容並將其與請求一起發送到上面。

這是我使用 WebClient 示例代碼的地方...

  private static void Main(string[] args)
    {
        RunPostAsync();
    } 

    static HttpClient client = new HttpClient();

    private static void RunPostAsync(){

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            Inputs inputs = new Inputs();

            inputs.Password = "pw";
            inputs.AppVersion = "apv";
            inputs.AppComments = "apc";
            inputs.UserName = "user";
            inputs.AppKey = "apk";


            var res = client.PostAsync("https://baseuriplus", new StringContent(JsonConvert.SerializeObject(inputs)));

            try
            {
                res.Result.EnsureSuccessStatusCode();

                Console.WriteLine("Response " + res.Result.Content.ReadAsStringAsync().Result + Environment.NewLine);

            }
            catch (Exception ex)
            {
                Console.WriteLine("Error " + res + " Error " + 
                ex.ToString());
            }

        Console.WriteLine("Response: {0}", result);
    }       

    public class Inputs
    {
        public string Password;
        public string AppVersion;
        public string AppComments;
        public string UserName;
        public string AppKey;
    }

這現在可以工作並使用(200)OK服務器和響應進行響應

為什么要生成自己的json?

使用JSONConvert從JsonNewtonsoft。

您的 json 對象字符串值需要" "引號和,

我會使用 http 客戶端進行發布,而不是 web 客戶端。

using (var client = new HttpClient())
{
   var res = client.PostAsync("YOUR URL", 
     new StringContent(JsonConvert.SerializeObject(
       new { OBJECT DEF HERE },
       Encoding.UTF8, "application/json")
   );

   try
   {
      res.Result.EnsureSuccessStatusCode();
   } 
   catch (Exception e)
   {
     Console.WriteLine(e.ToString());
   }
}   

在發送之前,您沒有正確地將您的值序列化為 JSON。 與其嘗試自己構建字符串,不如使用 JSON.Net 之類的庫。

你可以得到正確的字符串做這樣的事情:

var message = JsonConvert.SerializeObject(new {Password = pw, AppVersion = apv, AppComments = acm, UserName = user, AppKey = apk});
Console.WriteLine(message); //Output: {"Password":"password","AppVersion":"10","AppComments":"","UserName":"username","AppKey":"dakey"}
            var client = new RestClient("Your URL");
            var request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("apk-key", apk);

            //Serialize to JSON body.
            JObject jObjectbody = new JObject();
            jObjectbody.Add("employeeName", data.name);
            jObjectbody.Add("designation", data.designation);

            request.AddParameter("application/json", jObjectbody, ParameterType.RequestBody);

            try
            {
                var clientValue= client.Execute<Response>(request);
                return RequestResponse<Response>.Create(ResponseCode.OK, "", clientValue.Data);
            }
            catch (Exception exception)
            {
                throw exception;
            }

我制作了一個工具來快速輕松地完成它:

Install-Package AdvancedRestHandler

或者

dotnet add package AdvancedRestHandler
AdvancedRestHandler arh = new AdvancedRestHandler("https://webapi.com/baseurl");
var result = await arh.PostDataAsync<MyLoginResponse, MyLoginRequest>("/login", new MyLoginRequest{
  Password = "password",
  AppVersion = "1",
  AppComments = "",
  UserName = "username",
  AppKey = "dakey"
});

public class MyLoginRequest{
  public string Password{get;set;}
  public string AppVersion{get;set;}
  public string AppComments{get;set;}
  public string UserName{get;set;}
  public string AppKey{get;set;}
}

public class MyLoginResponse {
  public string Token{get;set;}
}

額外的:

您可以做的另一件事是使用ArhResponse

  • 無論哪種方式,在類定義中:
public class MyLoginResponse: ArhResponse 
{
...
}
  • 或者這樣,在 API 調用中:
var result = await arh.PostDataAsync<ArhResponse<MyLoginResponse>, MyLoginRequest> (...)

而不是嘗試或緩存,使用簡單的if語句檢查您的 API 調用狀態:

// check service response status:
if(result.ResponseStatusCode == HttpStatusCode.OK) { /* api receive success response data */ }

// check Exceptions that may occur due to implementation change, or model errors
if(result.Exception!=null) { /* mostly serializer failed due to model mismatch */ }

// have a copy of request and response, in case the service provider need your request response and they think you are hand writing the service and believe you are wrong
_logger.Warning(result.ResponseText);
_logger.Warning(result.RequestText);

// Get deserialized verion of, one of the fallback models, in case the provider uses more than one type of data in same property of the model
var fallbackData = (MyFallbackResponse)result.FallbackModel;

標題可能的問題

由於HttpClient生成的標頭,存在服務器不接受 C# 請求的情況。

這是因為 HttpClient 默認使用application/json; charset=utf-8的值application/json; charset=utf-8 Content-Type application/json; charset=utf-8 ...

僅發送application/json部分作為Content-Type並忽略; charset=utf-8 ; charset=utf-8部分,您可以執行以下操作:

對於HttpClient您可以通過查看此線程來修復它: How do you set the Content-Type header for an HttpClient request?

至於 (AdvancedRestHandler) ARH,由於與某家公司的整合,我修復了它,但我記不清了……我做到了,要么通過請求之類的options ,要么通過重置header值。

我們將使用 HttpPost 和 HttpClient PostAsync 來解決這個問題。

using System.Net.Http;
    static async Task<string> PostURI(Uri u, HttpContent c)
    {
    var response = string.Empty;
    using (var client = new HttpClient())
    {
    HttpResponseMessage result = await client.PostAsync(u, c);
    if (result.IsSuccessStatusCode)
    {
    response = result.StatusCode.ToString();
    }
    }
    return response;
    }

我們將通過創建一個用於發布的字符串來調用它:

  Uri u = new Uri("http://localhost:31404/Api/Customers");
        var payload = "{\"CustomerId\": 5,\"CustomerName\": \"Pepsi\"}";

        HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
        var t = Task.Run(() => PostURI(u, c));
        t.Wait();

        Console.WriteLine(t.Result);
        Console.ReadLine();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM