簡體   English   中英

從 API 響應 Cannot deserialize current JSON object

[英]From API response Cannot deserialize the current JSON object

嘗試反序列化數據時出現此錯誤。 詳情如下。 還有正在運行的應用程序的屏幕截圖,我在其中調試了該應用程序,並且可以看到來自我的 api 響應的數據。

調試的應用程序

我的 Controller 行動

 public async Task<JsonResult> GetJsonBooks()
    {
        List<Book> books = new List<Book>();
        
        using (var httpclient = new HttpClient())
        {
            using (var response = await httpclient.PostAsync("https://localhost:44374/api/Books",null))
            {
                var apiresponse = await response.Content.ReadAsStringAsync();
                books =  JsonConvert.DeserializeObject<List<Book>>(apiresponse);
            }
        }
        var jsonData = new
        {
            draw = 1,
            recordsFiltered = 100,
            recordsTotal = 100,
            data = books
        };
        return Json(jsonData);
    }

這行代碼給了我這個錯誤。

books = JsonConvert.DeserializeObject<List>(apiresponse);

    Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[BookStoreWebUI.Models.Book]' 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 'draw', line 1, position 8.
   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 BookStoreWebUI.Controllers.BooksController.GetJsonBooks() in D:\Farman Ali\VS\B_API\BookStoreWebUI\Controllers\BooksController.cs:line 46
   at lambda_method31(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Failed to load resource: the server responded with a status of 500 () [https://localhost:44377/Books/GetJsonBooks]

Model Class

public partial class Book
{
    public int Id { get; set; }
    [Required(ErrorMessage = "Title is Required")]
    public string Title { get; set; }

    [Required(ErrorMessage = "Author Name is Required")]
    public string Author { get; set; }
    [Required(ErrorMessage = "Publication Year is Required and is only number")]
    [RegularExpression(@"[0-9]{4}$")]
    public int PublicationYear { get; set; }
    [Required(ErrorMessage = "Check Availabilty")]
    public bool IsAvailable { get; set; }
    [Required(ErrorMessage = "Call Number is Required")]
    public string CallNumber { get; set; }

}
public partial class Book
{
    public partial class Product
    {
        public int TotalCount { get; set; }
        public int FilteredCount { get; set; }
    }
}

我的 Ajax 方法

        function getallbooks() {
        
        $.ajax({
            url: "/Books/GetJsonBooks",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            data: '{}',
            method:"post",
            async: true,
            success: OnSuccess,
            error: function (response) {
                console.log(response);
            }
        });
    }
    function OnSuccess(response) {

        console.log(typeof (response) + " ---- " + response.data);
        var obj = JSON.stringify(response.data);
        // var obj1 = jso JSON.stringify(response);
        console.log(typeof (obj) + " ---- " + obj);
        $("#tblbooks").DataTable(
            {
                bLengthChange: true,
                lengthMenu: [[10, 20, 50, -1], [10, 20, 50, "All"]],
                bFilter: true,
                bSort: true,
                serverSide: true,
                bPaginate: true,
                bDestroy: true,
                deferLoading: 10,
                data: response.data,
                columns: [
                    { "data": "id", "name": "id", "autoWidth": true },
                    { "data": "title", "name": "title", "autoWidth": true },
                    { "data": "author", "name": "author", "autoWidth": true },
                    { "data": "publicationYear", "name": "publicationYear", "autoWidth": true },
                    { "data": "isAvailable", "name": "isAvailable", "autoWidth": true },
                    { "data": "callNumber", "name": "callNumber", "autoWidth": true },
                    { "data": "callNumber", "name": "callNumber", "autoWidth": true },
                    { "data": "callNumber", "name": "callNumber", "autoWidth": true }
                    {
                        data: null, render: function (data, type, row) {
                            return "<a href='#' class='btn btn-info' onclick=EditBook('" + row.id + "'); >Edit</a>";
                        }
                    },
                    {
                        data: null, render: function (data, type, row) {
                            return "<a href='#' class='btn btn-danger' onclick=DeleteBook('" + row.id + "'); >Delete</a>";
                        }
                    }
                ]
            });
    }

我明白了,你有json結果,里面有一些屬性,但你正在做的是,將嵌套的 object data提取到你的List<Book>中,這是不正確的。

如果你的json object 是這樣表述的:

{
    draw: 0,
    recordsTotal: 12012,
    recordsFiltered: 121212,
    data: [
        {
            id: 0,
            author: 1231
            ....... so on
        }
    ]
}

然后你需要像這樣制定你的課程:

public class RootBook
{
    public int draw {get;set;}
    public int recordsTotal {get;set;}
    public int recordsFiltered {get;set;}
    public List<Book> data {get;set}

}
public partial class Book
{
    public int id { get; set; }
    [Required(ErrorMessage = "Title is Required")]
    public string title { get; set; }

    [Required(ErrorMessage = "Author Name is Required")]
    public string author { get; set; }
    [Required(ErrorMessage = "Publication Year is Required and is only number")]
    [RegularExpression(@"[0-9]{4}$")]
    public int publicationYear { get; set; }
    [Required(ErrorMessage = "Check Availabilty")]
    public bool isAvailable { get; set; }
    [Required(ErrorMessage = "Call Number is Required")]
    public string callNumber { get; set; }
}
// ... further things that you might have as partials

然后當您使用此代碼Deserialize json 時:

var books = JsonConvert.DeserializeObject<RootBook>(apiresponse);

另外,當對json c#進行相關的c# PascalCase json camelCase

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM