Angular 13 在 Http 删除时将多个 ID 发送到 .Net C#(使用 Newtonsoft C#)

Angular 13 send multiple Id's to .Net C# on Http Delete (using Newtonsoft C#)

我正在尝试将要从 Angular 13 中删除的多个对象 ID 发送到我的 C# .net API。

通过在线研究,这是建议使用 http.delete 发送正文的方法,这将需要 return 更新的显示费用。

我的第一个问题,这是通过 RESTful API 调用此方法的合适方法吗?

  deleteMultipleReturnShowCosts(showId: number, objs: number[]): Observable<ShowCost[]>{
    const options = { headers: new HttpHeaders({'Content-Type': 'application/json'}),
    body: { ids: JSON.stringify({...objs})}};
    return this.http.delete<ShowCost[]>(`${this.url}/${showId}`, options)
      .pipe(
        catchError(this.handleError<ShowCost[]>('Delete: Show Item'))
      );
  }

例如,在这个方法中,我发送 objs: number[] of [151,152,153]

这是我的 C# 当前测试代码 API 删除方法

        /// <summary>
        /// Delete Show Item
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="showId"></param>
        /// <returns></returns>
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [HttpDelete("{showId:int}", Name = nameof(DeleteShowItem))]
        public async Task<IActionResult> DeleteShowItem([FromBody] object jsonObj, int showId)
        {
            try
            {
                var jsonString = JsonConvert.SerializeObject(jsonObj);
                var jsonKeyValuePair = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
                jsonKeyValuePair.TryGetValue("ids", out var stringArray);

                if (stringArray == null) return BadRequest("Array did not parse.");

                var showItemIds = JsonConvert.DeserializeObject<int[]>(stringArray);

              
                return Ok();
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return BadRequest(e.Message);
            }
        }

我一直在尝试以多种不同的方式分解对象,但没有任何乐趣。

这些是当前的变量值:

jsonObj

{
  "ids": "{\"0\":151,\"1\":152,\"2\":153}"
}

jsonKeyValuePair

Count = 1
key[0] = ids
value[0] = {"0":151,"1":152,"2":153}

showItemIds

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Int32[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '0', line 1, position 5.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
   at Assembly2021.API.Controllers.ShowItemController.DeleteShowItem(Object jsonObj, Int32 showId) in /Users/alexanderlynn/RiderProjects/assembly2021-angular/Assembly2021-API/Assembly2021.API/Controllers/ShowItemController.cs:line 182

最终,我想为剩余的 API 调用获取一个 IEnumerable。

提前致谢!

你可以通过将你的 json 更改为一个数组而不是那个奇怪的对象来简化这个,所以而不是:

 body: { ids: JSON.stringify({...objs})}};

 body: objs };

json 将变成简单的数组:

[ 1,2,3,4 ]

在 api 中只需将您的参数声明为可以接受对象列表的内容,例如数组或列表或 IEumerable:

    public async Task<IActionResult> DeleteShowItem([FromBody] int[] jsonObj, int showId)

不需要额外的代码,开箱即用。


也不要将捕获日志逻辑烘焙到所有端点中

catch (Exception e)
        {
            _logger.LogError(e.Message);
            return BadRequest(e.Message);
        }

你已经做错了,只记录消息关于异常最重要的事情是堆栈跟踪,第二重要的是来自最内部异常的消息。你这样做的方式会阻碍你发现错误的能力。因此,记录完整的异常要么你的记录器应该接受 Exception 作为参数,要么至少将 e.ToString() 传递给它。为了不重复此代码,请写一个 action filter。 Bad Request 是针对用户使用无效参数调用您的端点 :) 现在,对于您代码的每个错误,您都在责怪用户 :)。