【问题标题】:Call post API from-data body using MVC使用 MVC 从数据主体调用 post API
【发布时间】:2020-10-12 08:49:36
【问题描述】:

如何使用 MVC 客户端调用在正文消息中使用表单数据的 post API。

API 正文在表单数据中有两个属性,即消息,另一个是附件:

我尝试了一些方法,但由于格式错误而返回错误。这是我的代码:

var client = new HttpClient();
        string APIUrl = "https://mynewuploadapi.azurewebsites.net/api/v1/customers/discount";
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZXhwIjoxNTkzMzYyMTYwLCJpc3MiOiJQbHVzbWlsZXNBUEkifQ.DC42fI7dmKCTwzXPyrI5vs6Sxp0FMrOgvvr_uECzJ7Q");
        client.BaseAddress = new Uri("https://mynewuploadapi.azurewebsites.net/api/v1/customers/discount");
        client.Timeout = TimeSpan.FromMilliseconds(1000000);
        
        var converter = new JavaScriptSerializer().Serialize(model);
        var formContent = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("message", @converter),
            new KeyValuePair<string, string>("attachements", null)
        });

        var HTTPcontent = new StringContent(@converter, Encoding.UTF8, "multipart/form-data");

        var response = await client.PostAsync(APIUrl, HTTPcontent);

它在邮递员上工作,如下图所示:

这是我的控制器上的另一个尝试,它也是返回码:500

#region New Try 26Jun
        var newclient = new HttpClient();
        newclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZXhwIjoxNTkzMzYyMTYwLCJpc3MiOiJQbHVzbWlsZXNBUEkifQ.DC42fI7dmKCTwzXPyrI5vs6Sxp0FMrOgvvr_uECzJ7Q");
        newclient.Timeout = TimeSpan.FromMilliseconds(1000000);
        var dict = new Dictionary<string, string>
        {
            { "message", jsonDeserilizeFromModel},
            { "attachements", null }
        };
        var values = new FormUrlEncodedContent(dict);
        var newresponse = await newclient.PostAsync(APIUrl, values);
        newresponse.EnsureSuccessStatusCode();
        #endregion

详细邮递员电话如下: 网址 - https://mynewuploadapi. azurewebsites.com/api/v1/customers/discount

标题: 授权:Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZXhwIjoxNTkzNDIzNzg2LCJpc3MiOiJQbHVzbWlsZXNBUEkifQ.MWa-pbYneOUKvO0_dVVXVFENwBrpU3eGWc47j1YpcmQ

身体。方法(表单-发布) 留言:

 {
  "tx_type": "Kad Perjalanan",
  "applicant_type": "Pekerja/Pelajar",
  "reg_type": "Permohonan Baharu",
  "ic_type": "NRIC",
  "ic_no": "821210-10-1010",
  "title": "Encik",
  "ic_name": "Ali",
  "dob": "1982-12-10",
  "gender": "Lelaki / Male",
  "mailing_address": "",
  "state": "Selangor",
  "postcode": "40000",
  "city": "Subang",
  "email": "ali@plusti.my",
  "mobile_no": "01020202020",
  "v_make": "Proton",
  "v_model": "Saga",
  "v_year": "2009",
  "v_grant": "12345",
  "v_plateno": "BTP2021VC",
  "co_name": "PLUSTI",
  "co_address": "Tepi PLUSTI Highway",
  "co_postcode": "40000",
  "co_state": "Selangor",
  "co_phone": "0375525251",
  "tngcardno": "1234554321",
  "tngcard_expiry": null,
  "rfidtagno": null,
  "v_owner": "Y",
  "discount_type":"JPP"
}

表单后正文示例截图:

有人可以帮我解决这个问题吗?谢谢

【问题讨论】:

  • 你能告诉我们控制器签名和完整的错误信息吗?
  • 响应结果的消息是错误代码500。
  • 邮递员没有发送用户名和密码。标头中的不记名 JWT 令牌。和源代码中的一样
  • @HoomanBahreini 我只是用控制器上的代码更新我的问题
  • 我要求的是控制器代码(服务器端)而不是客户端...

标签: c# asp.net-mvc api multipartform-data form-data


【解决方案1】:

我对此进行了测试,它确实有效:

 var client = new HttpClient();
            string APIUrl = "https://localhost:44398/api/values/test1";
            client.Timeout = TimeSpan.FromMilliseconds(1000000);
            var dict = new Dictionary<string, string>
            {
                { "message", "message" },
                { "attachements", null }
            };
            var values = new FormUrlEncodedContent(dict);
            var response = await client.PostAsync(APIUrl, values);
            response.EnsureSuccessStatusCode();
            Console.WriteLine(await response.Content.ReadAsStringAsync());

【讨论】:

  • 我刚刚更新了我的问题,附上邮递员成功
【解决方案2】:

成功了:


  using (var response = await Task.Run(() => httpClient.PostAsync(httpClient.BaseAddress, httpContent)))
                    {
                        var bodyString = await response.Content.ReadAsStringAsync();
                        if (response.StatusCode == HttpStatusCode.OK)
                        {
                            return new HttpResponseResult<T>()
                            {
                                StatusCode = response.StatusCode,
                                Body = JsonConvert.DeserializeObject<T>(bodyString),
                                ContentType = response.Content.Headers.ContentType?.MediaType
                            };
                        }}

【讨论】:

    【解决方案3】:

    这对我有用

     var baseUrl = "https://mynewuploadapi.azurewebsites.net/api/v1/customers/discount";
            var token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZXhwIjoxNTkzMzYyMTYwLCJpc3MiOiJQbHVzbWlsZXNBUEkifQ.DC42fI7dmKCTwzXPyrI5vs6Sxp0FMrOgvvr_uECzJ7Q";
    
            using (var httpClient = new HttpClient())
            {
             
                using (var formData = new MultipartFormDataContent())
                {
                    formData.Add(new JsonContent(message), "message");
                    formData.Add(new JsonContent(fileContent), "attachements");
    
                    httpClient.Timeout = TimeSpan.FromMilliseconds(1000000);
                    httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
                    var response = await httpClient.PostAsync(baseUrl, formData);
                    if (!response.IsSuccessStatusCode)
                    {
                        //ErrorEventArgs handling here
                    }
                }
            }
    

    【讨论】:

      【解决方案4】:

      首先,这是您代码中HttpClient.BaseAddress误用。你必须像这样使用它:

      string APIUrl = "https://mynewuploadapi.azurewebsites.net/api/v1";
      client.BaseAddress = new Uri(APIUrl);
      
      //then call api with the following
      var response = await client.PostAsync("/customers/discount", content);
      

      其次,根据target api期望参数发送给他的方式,你应该弄清楚请求结构,这里你不知道它,除非尝试执行一些测试。所以让我们专注于代码的重要部分:

      授权

      您采用了正确的方式发送授权承载,即:

      httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Your Oauth token");
      

      数据

      您第一次尝试序列化然后编码两次使用FormUrlEncodedContentStringContent看起来不寻常。您的第二次尝试在 Dictionary 中使用 jsonDeserilizeFromModel 作为 string,而这不是合并模型的方法。根据目标 API 中的预期请求表单,您可以使用以下解决方案之一:

      解决方案 A(当您可以从 模型 中创建 Dictionary&lt;string, string&gt; 时):

      MultipartFormDataContent form = new MultipartFormDataContent();
      HttpContent file = new StringContent("file to upload as StreamContent");
      HttpContent msgItems = new FormUrlEncodedContent(model.ToDictionary());//<string, string>
      form.Add(file, "attachements");
      form.Add(msgItems, "message");
      var response = await client.PostAsync("/customers/discount", form);
      

      解决方案 B 创建一个包含 消息 模型和 附件 的新 model(例如 unitModel):

      var json = JsonConvert.SerializeObject(unitModel);// or JavaScriptSerializer().Serialize
      var data = new StringContent(json, Encoding.UTF8, "application/json");
      var response = await client.PostAsync("/customers/discount", data);
      

      解决方案 C 以 Json 身份发布:

      //'unitModel' is a class containing both 'message' & 'attachements'
      var result = await client.PostAsJsonAsync("/customers/discount", unitModel);
      

      我们不知道哪一个可以帮助您,因为我们无法重现您的问题。考虑到任何额外的操作,例如编码绑定请求正文 可能是目标API返回错误的原因.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 2020-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多