C#Web API在HTTP Post REST Client中发送正文数据

时间:2018-05-22 01:20:12

标签: c# asp.net-web-api asp.net-core advanced-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来实现这一目标。

问题是如何格式化Body Content并将其与请求一起发送到上面。

以下是我使用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服务器和响应

进行工作和响应

5 个答案:

答案 0 :(得分:2)

你为什么生成自己的json?

使用JsonNewtonsoft的" "

您的json对象字符串值需要,引号和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()); } }

我使用http客户端进行发布,而不是webclient。

<select id="type1" onchange="myFunction()">
 <option value="000">000</option>
 <option value="111">111</option>
 <option value="222">222</option>
</select>

<select id="type2" onchange="myFunction()">
 <option value="AAA">AAA</option>
 <option value="BBB">BBB</option>
 <option value="CCC">CCC</option>
</select>

<div class="logodiv">
    <a href="http://test.com/redir.php?"><img src="logo1.jpg"></a>
</div>
<div class="logodiv">
    <a href="http://test.com/redir.php?"><img src="logo2.jpg"></a>
</div>
<script>
function myFunction() {

  var mylinks = [];
    var mylogo = document.querySelectorAll(".logodiv");
    for(var j = 0; j < mylogo.length; j++) {
        mylinks[j] = mylogo[j].childNodes[1].href;
    }

  var type1 = document.getElementById("type1").value;
  var type2 = document.getElementById("type2").value;


  for(var i = 0; i < mylogo.length; i++) {
    mylogo[i].childNodes[1].href = mylinks[i].substring(0,  mylinks[i].indexOf('?') + 1) + "&type1=" + type1 + "&type2=" + type2;
   }

}
</script>

答案 1 :(得分:0)

在发送之前,您没有正确地将值序列化为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"}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我制作了一个工具来快速轻松地完成它:

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 的值作为 Content-Type...

对于仅将 application/json 部分作为 Content-Type 发送而忽略 ; charset=utf-8 部分,您可以执行以下操作:

对于 HttpClient,您可以通过查看此线程来修复它:How do you set the Content-Type header for an HttpClient request?

至于 (AdvancedRestHandler) ARH,由于与某些公司的整合,我修复了它,但我不记得完全...我是通过 options 之类的请求或通过重置 {{ 1}} 值。

答案 4 :(得分:-2)

我们将使用HttpPost和HttpClient PostAsync解决问题。

// Global variable to produce a unique address as the AssociatedObjectHandle
var AssociatedObjectHandle: UInt8 = 0

public extension UIView {

    @IBInspectable var styleName: String {
        get {
            return objc_getAssociatedObject(self, &AssociatedObjectHandle) as? String ?? ""
        }
        set {
            objc_setAssociatedObject(self, &AssociatedObjectHandle, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

我们将通过创建用于发布的字符串来调用它:

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