.NET Standard 2、.NET Core 2、HttpClient 未按预期运行(传递 null)

.NET Standard 2, .NET Core 2, HttpClient not behaving as expected (passing null)

小提纲:

我们有一个调用 WebApi (.NET Core 2.0) 的 .NET Standard (2.0) 项目,它应该处理一条消息(通过消息,它可以是用户想要记录的任何内容,可以是异常、警告、或者只是存储在数据库中的注释)存储该消息和 return 更新后的消息给调用者。

问题: 当我从 .NET Standard 项目(使用 HttpClient)调用 WebApi 时,它实际上并没有按要求 POSTing 对象。当它在 .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 时,该对象不再包含任何数据,而是充满了空值和空字符串,这让我相信 POST 实际上并未发送数据。

在这一点上,我真的不确定我错过了什么。 Google 几乎没有帮助,而且我找不到任何与我的问题类似的东西。

在遍历调用堆栈后,它吐出一些错误消息,同样,我在连接到我的代码时运气不佳,但它们是:

> 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()

有人 seen/come across/fixed 这个问题吗?在与 HttpClient 的通话中我做错了什么吗?

好吧,在绝对和彻底的愚蠢行为中(不是一个词,但我需要编造一些东西来解释我现在的感觉有多愚蠢)我想通了这个问题。

webapi 方法签名是罪魁祸首:

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

我错过了 [FromBody]。我之前为我们的大多数系统制作了 api,我不知道为什么我错过了这么简单的东西。

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