.NET Standard 2、.NET Core 2和HttpClient未按预期工作(传递null)

4

简要说明:

我们有一个.NET Standard(2.0)项目,调用WebApi(.NET Core 2.0),应该处理消息(这里的消息可以是用户想要记录的任何内容,例如异常、警告或者只是存储在数据库中的注释),将该消息存储并将更新后的消息返回给调用方。

问题:

当我使用HttpClient从.NET Standard项目调用WebApi时,它实际上没有按照请求要求POST对象。当它通过.NET Standard项目运行时,对象被填充了所有必需的字段,在这种情况下,它是一个捕获到的异常,并且消息、堆栈跟踪等都一同传递。

这是来自.NET Standard项目的代码:

        IDataAccessResult<CaughtException> result = new DataAccessResult<CaughtException>();

        string baseUrl = "baseurl";
        var client = new HttpClient();

        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("a", "b");

        // HTTP POST
        var myContent = JsonConvert.SerializeObject(caughtException);
        StringContent sc = new StringContent(myContent, System.Text.Encoding.UTF8, "application/json");
        System.Uri uri = new System.Uri(string.Format("{0}/api/v6/CaughtException/SaveAsync", baseUrl));

        HttpResponseMessage response = await client.PostAsync(uri, sc);

        response.EnsureSuccessStatusCode();
        if (response.IsSuccessStatusCode)
        {
            result = JsonConvert.DeserializeObject<DataAccessResult<CaughtException>>(await response.Content.ReadAsStringAsync());
        }
当这个调用传递给WebApi时,对象不再包含任何数据,而是充满了null和空字符串,这让我相信POST实际上没有发送数据。 此时,我真的不确定我缺少什么。谷歌几乎没有帮助,我也没有找到任何类似我的问题的东西。 在它烧过调用堆栈后,它会输出一些错误消息,但我很难将其与我的代码连接起来,但以下是它们:
> WinHttpException: The connection with the server was terminated abnormally

> Unknown location

> IOException: The read operation failed, see inner exception.

>System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
>System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Threading.Tasks.RendezvousAwaitable.GetResult()
System.Net.Http.WinHttpResponseStream+<CopyToAsyncCore>d__18.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Net.Http.NoWriteNoSeekStreamContent+<>c.<SerializeToStreamAsync>b__4_0(Task t, object s)
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, object state)
System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref Task currentTaskSlot)
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Net.Http.HttpContent+<LoadIntoBufferAsyncCore>d__48.MoveNext()

> HttpRequestException: Error while copying content to a stream.

>System.Net.Http.HttpContent+<LoadIntoBufferAsyncCore>d__48.MoveNext()
>System.Net.Http.HttpContent+<LoadIntoBufferAsyncCore>d__48.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Net.Http.HttpClient+<FinishSendAsyncBuffered>d__58.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
LogService.Gateway.CaughtExceptionGateway+<SaveAsync>d__6.MoveNext() in CaughtExceptionGateway.cs
+
            HttpResponseMessage response = await client.PostAsync(uri, sc);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
LogService.Api.CaughtExceptionController+<LogError>d__11.MoveNext() in CaughtExceptionController.cs
+
            ce = (await _exceptions.SaveAsync(ce)).Payload;
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
LogService.Api.CaughtExceptionController+<GetCaughtExceptionAsync>d__5.MoveNext() in CaughtExceptionController.cs
+
                    CaughtException ce = await LogError(action, controller, loggingApplicationCodeId, accountId, loggingExceptionTypeId, e.Exception.Message, e.Exception.StackTrace, null, token, storedProcedureName, storedProcedureParameters);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__12.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

有人遇到/解决过这个问题吗?在使用HttpClient时,我是否做错了什么?


3
所有内部异常的完整堆栈跟踪是什么? - SLaks
2
EnsureSuccessStatusCode 会抛出异常,之后你不需要检查 IsSuccessStatusCode。 - Camilo Terevinto
看起来是在服务器端出现了故障。您能否检查一下您的服务器日志? - Subbu
@Sabbu 我正在本地运行这些项目,两个项目都是同一个解决方案的一部分(因此本质上属于服务器端)。从日志的角度来看,没有什么异常情况,似乎只是一个项目无法正确地(或根本不)将流传递到另一个项目。 - SlackerCoder
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4

好的,在完全愚蠢的行为中(不是一个词,但我需要创造一个词来解释我现在感到的多么愚蠢),我找出了问题所在。

WebAPI方法签名是罪魁祸首:

public async Task<IActionResult> SaveAsync([FromBody]CaughtException caughtExceptionItem)

我漏掉了[FromBody]。我之前已经为我们大部分的系统制作了api,但不知道为什么会错过这么简单的东西。

希望我的错误(以及随后几天的浪费)能帮助到其他人!!


只是为了更新 .NetCore 2.1:如果您使用属性 [ApiController] 指定类,则不需要使用 [FromBody] 属性。 - Emy Blacksmith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,