【发布时间】: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<ResponseObject>();包裹在try/catch中,这会产生任何冒泡的错误。 -
@bcr 是的,我忘了说要忽略这样的明显问题......我只需要它先工作,然后我可以清理它。我意识到示例代码中的错误/处理不足,我会在它运行时对其进行清理。谢谢。
-
@ComputerAidedTradingSystems 是的,我现在只是在本地,它被设置为所有默认值......
-
你知道500-ing在哪里吗?你看到堆栈跟踪了吗?一个值得一看的地方是 Windows 事件查看器。
标签: c# .net-core dotnet-httpclient