Home > database >  Parsing Json array to C# Object
Parsing Json array to C# Object

Time:10-25

I'm building a .NET WebAPI that receives Json through a Post operation. The Json that's being received could look like the following:

{
  "site": "00131231201d010231",
  "publishTime": 123123123123,
  "domains": [
    "example.com"
  ],
  "publishedBy": {
    "name": "John Doe",
    "id": "00211231201d010231"
  }
}

I converted my Json response type to C# objects which look like the following:

public class Project
{
    [Key]
    [JsonPropertyName("site")]
    public string Site { get; set; }

    [JsonPropertyName("publishTime")]
    public long PublishTime { get; set; }

    [JsonPropertyName("domains")]
    public List<Domain> Domains { get; set; }

    [JsonPropertyName("publishedBy")]
    public PublishedBy PublishedBy { get; set; }
}

public class PublishedBy
{
    [JsonPropertyName("name")]
    public string Name { get; set; }

    [Key]
    [JsonPropertyName("id")]
    public string Id { get; set; }
}

public class Domain
{
    [Key]
    public string Id { get; set; }
    public string Name { get; set; }
}

As you can see, my goal is to add the contents to my database. Only when I use List Domains, it gives me an error saying I can't use strings in EFCore when I try to add a migration.

So, I created an object called Domain. But now when I try to deserialize it gives me the following error:

System.Text.Json.JsonException: The JSON value could not be converted to spine_management.Models.Domain.

Does anyone happen to know what type I should make Domains and/or what the best way to deserialize this object is?

EDIT:

I want to keep the domains attribute, I don't want to ignore or delete them.

CodePudding user response:

It's not uncommon to split between two different model structures for interacting with different infrastructure points. In this case your infrastructure points are:

  1. Deserializing JSON input
  2. Persisting data with EF

You can treat the JSON input like a "view model". It's not your core model which maps to EF database entities, but rather just an anemic DTO for deserializing data. For that model, Domains is simply a list of strings:

[JsonPropertyName("domains")]
public List<string> Domains { get; set; }

This view model is local to the application layer, not part of the core domain. Within the application logic, after deserializing the input, you can map it to the domain object. That's where you would translate the list of simple strings into a list of Domain objects. (And translate back in any output operations.)

As long as the mapping logic (which might be made simple by using tools like AutoMapper, though in this case the logic is pretty straightforward and doesn't really necessitate adding more tools) is encapsulated within that application layer, it won't pollute the rest of the domain logic.


Though it may certainly be possible to configure one or both of these tools to work together more smoothly, I often find that a simple translation layer between dependency-specific DTOs and core domain models is much simpler to build and maintain.

CodePudding user response:

I currently use Newtonsoft JSON for serialize and deserializing. I think the reason for this error is you wrote named the string in domain "Name", but it has to be "name". Hope it works!

  • Related