首页 > 解决方案 > 为什么接收 API 没有获取参数中的内容?

问题描述

Sap.Data.SQLAnywhere.v4.5我正在尝试让一个 API(报告 API)与另一个 API(存储过程运行程序 API)通信,鉴于我们在 .NET Core 2.2 中创建了第一个 API 并且驱动程序只播放,我们不得不采用这种解决方案.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 settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at EnterpriseReportRunner.Service.ReportService.RunStuff(String report) in C :\Workspace\Solution.NET\LOB\InternalReportsAdminConsole Solution\EnterpriseReportRunner\EnterpriseReportRunner\Service\ReportService.cs:C:\Workspace\Solution.NET\LOB\InternalReportsAdminConsole 中 EnterpriseReportRunner.Controllers.ReportsController.GetStuff(String report) 的第 27 行解决方案\EnterpriseReportRunner\EnterpriseReportRunner\Controllers\ReportsController.cs:第 67 行

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

标签: c#.net-coredotnet-httpclient

解决方案


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

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

即使“报告”已经是一个字符串......对我来说真的很奇怪。但这解决了它。

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

感谢您的所有意见。可能想将此链接到另一个问题


推荐阅读