【问题标题】:Why is the receiving API not getting content in the parameter?为什么接收 API 没有获取参数中的内容?
【发布时间】:2019-08-14 18:16:27
【问题描述】:

我正在尝试让一个 API(报告 API)与另一个 API(存储过程运行程序 API)通信,鉴于我们在 .NET Core 2.2 中创建了第一个 API 和Sap.Data.SQLAnywhere.v4.5 驱动程序仅适用于 .NET 4.7.2 框架。因此,我们将它们隔离以进行补偿。我在过去 4 或 5 小时内看到的所有答案让我相信我这样做是正确的,但它仍然不起作用。

我可以使用 json/text 正文从 Postman 访问存储过程运行程序,并从数据库中获取结果。但是,当我尝试从 C# 中解决这个问题时,我首先得到了Unsupported Media Type,我认为我已经修复了它,但现在我得到了 500 个错误,当从报告 API 调试到存储过程运行器时,我注意到我没有得到参数从身体传递过来。

[HttpPost]
[Route("api/Reports/GetStuff")]
[ResponseType(typeof(ResponseObject))]
public ResponseObject GetStuff([FromBody]string report)
{
        var response = new ResponseObject();

        try
        {
            response = new ReportService().RunStuff(report);
        }
        catch (Exception e)
        {
            throw;
        }

        return response;
}

以上是 SprocRunnerAPI,我得到了

response = new ReportService().RunStuff(report);

在它失败之前,因为它在“报告”中没有任何内容。

public class ApiService
{
    public static HttpClient ApiClient { get; set; }

    public static void InitializeClient()
    {
        ApiClient = new HttpClient();
        //ApiClient.BaseAddress = new Uri("");
        ApiClient.DefaultRequestHeaders.Accept.Clear();
        ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }
}

这是我初始化所有内容的地方,然后在以下类方法中使用它:

public ResponseObject RunReportToCSV(string report)
    {
        var rep = new ResponseObject();
        ApiClient.ApiService.InitializeClient();
        string url = @"http://localhost/EnterpriseReportRunner/api/reports/GetStuff";

        var httpContent = new StringContent(report, Encoding.UTF8, "application/json");

        //ServicePointManager.Expect100Continue = false; I honestly don't know where this goes... or if it is needed.

        var response = ApiClient.ApiService.ApiClient.PostAsync(url , httpContent).Result;

        if (response.IsSuccessStatusCode)
        {
            rep = response.Content.ReadAsAsync<ResponseObject>().Result;
        }
        else
        {
            throw new Exception(response.ReasonPhrase);
        }

        return rep;
}

我做到了

var response = ApiClient.ApiService.ApiClient.PostAsync(url, httpContent).Result;

当它在外部调用上述 api 方法并失败时。我注意到我在 C# 中放入的正文与我在 Postman 中放入的正文之间没有区别,在进行任一调用时,我也没有注意到通过 Fiddler 在标题上的区别。我很困惑为什么我在各处看到的东西都在使用,这是行不通的。

谢谢。

从 SprocRunnerAPI 添加堆栈跟踪……这并没有多大帮助,因为我确切地知道为什么会发生这种情况。至此,我期望一个 JsonSerialized 对象,但我没有它,因为它没有从第一个 API 传递到第二个。

在 Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings 设置) 在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](字符串值,JsonSerializerSettings 设置) 在 EnterpriseReportRunner.Service.ReportService.RunStuff(String report) 在 C:\Workspace\Solution.NET\LOB\InternalReportsAdminConsole Solution\EnterpriseReportRunner\EnterpriseReportRunner\Service\ReportService.cs:line 27 在 EnterpriseReportRunner.Controllers.ReportsController.GetStuff(String report) 在 C:\Workspace\Solution.NET\LOB\InternalReportsAdminConsole Solution\EnterpriseReportRunner\EnterpriseReportRunner\Controllers\ReportsController.cs:line 67

需要明确的是,这是来自 SprocRunnerAPI 的堆栈,而不是调用它的 ReportsAPI。我试图在 HttpContext 中查找 body 以查看 Postman 调用和 C# 调用之间的区别但似乎找不到它,它真的埋在 InputStream 中吗?

【问题讨论】:

  • 当我的 IIS 不支持文件 MIME 类型类型/流格式时,我遇到了类似的问题。您是否有权访问托管您的系统的 IIS?
  • 您绝对不应该在未等待的任务上使用.Result。你可以使用async/await(或者如果你不想让你的方法异步,可以使用ContinueWith()),比如rep = await response.Content.ReadAsAsync&lt;ResponseObject&gt;();包裹在try/catch中,这会产生任何冒泡的错误。
  • @bcr 是的,我忘了说要忽略这样的明显问题......我只需要它先工作,然后我可以清理它。我意识到示例代码中的错误/处理不足,我会在它运行时对其进行清理。谢谢。
  • @ComputerAidedTradingSystems 是的,我现在只是在本地,它被设置为所有默认值......
  • 你知道500-ing在哪里吗?你看到堆栈跟踪了吗?一个值得一看的地方是 Windows 事件查看器。

标签: c# .net-core dotnet-httpclient


【解决方案1】:

这个问题似乎是我认为多余的问题。最重要的是,即使您期望一个序列化的 JSON 对象,您也需要再次序列化它,否则当您通过 HttpClient 传递 StringContent 时,主体内容不会显示在接收控制器的参数中以供使用.

var httpContent = new StringContent(JsonConvert.SerializeObject(report), Encoding.UTF8, "application/json");

尽管“report”已经是一个字符串了……对我来说真的很奇怪。但这解决了它。

发现进入控制器的字符串也被包裹在另一个对象中,所以 .Root 在反序列化时似乎是你的朋友。至少我从这次经历中学到了一些东西。

感谢您的所有意见。可能想将此链接到this other question

【讨论】:

  • 我绝对希望能解释一下为什么需要这样做。
猜你喜欢
  • 2020-12-12
  • 1970-01-01
  • 2018-10-26
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多