8

I am new to asp.net core WebApi and I am trying to read data from a valid json file which is saved inside a folder called mydata inside my webapi

/mydata/userData.json

userData.json:

{
    "users": [
        {
            "id": 1,
            "firstName": "John",
            "lastName": "Doe"
        },
        {
            "id": 2,
            "firstName": "Jane",
            "lastName": "Doe"
        }
}

I wrote a web method that takes an input as first name, and returns single user object (first found record incase multiple results).

UserController.cs:

[Route("user/{firstName}")]  
public User GetUser(string firstName)  
{  
using (StreamReader r = new StreamReader("~/mydata/userData.json"))
    {
         string json = r.ReadToEnd();
         User item =JsonConvert.DeserializeObject<User>(json);
    }
    var user = User; 
    return user;  
} 

I am facing the following issues:

  1. I am not able to map the file userData.json, i tried Server.MapPath but it looks like its not available, httpcontext also did not work.
  2. I do not understand how to return a User Object from this api, which will be used in a react app.
2
  • Your file name is user.json but in your StreamReader you're trying to read a file with different name userData.json. Is that a typo? Commented Aug 11, 2021 at 10:23
  • @Izzy that was a typo, I fixed that. Thanks Commented Aug 11, 2021 at 22:09

4 Answers 4

6

You can achieve this by making use of IHostingEnvironment to get the root path and Path.Combine() method. So your controller should look like:

public class UserController : Controller
{
    private readonly IHostingEnvironment _hostingEnvironment;

    public UserController(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    [Route("user/{firstName}")]
    public User GetUser(string firstName)
    {
        var rootPath = _hostingEnvironment.ContentRootPath; //get the root path

        var fullPath = Path.Combine(rootPath, "mydata/user.json"); //combine the root path with that of our json file inside mydata directory

        var jsonData = System.IO.File.ReadAllText(fullPath); //read all the content inside the file

        if (string.IsNullOrWhiteSpace(jsonData)) return null; //if no data is present then return null or error if you wish

        var users = JsonConvert.DeserializeObject<List<User>>(jsonData); //deserialize object as a list of users in accordance with your json file

        if (users == null || users.Count == 0) return null; //if there's no data inside our list then return null or error if you wish

        var user = users.FirstOrDefault(x => x.FirstName == firstName); //filter the list to match with the first name that is being passed in

        return user;

    }
}

Please note: IHostingEnvironment will be removed in the future releases so if you can upgrade your framework then do so, so you can use the recommended IWebHostEnvironment type.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, I am trying this approach. and getting this error: - $exception {"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[App.Models.User]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or ...... I will keep debugging.
Is this error in derealization happing because JSON file contains a "Users" object that contains a list of users (json file does not directly contains a list) ?
The JSON file content which you included in your question, the syntax was incorrect because you was missing the closing ]. Before posting my answer yesterday, I added the closing ] and manage to deserialize without any issues. If you're JSON file content has changed, please add it to your question and I will update my answer.
5

Here is a working demo:

/mydata/userData.json:

{
  "users": [
    {
      "id": 1,
      "firstName": "John",
      "lastName": "Doe"
    },
    {
      "id": 2,
      "firstName": "Jane",
      "lastName": "Doe"
    }
  ]
}

project structure:

enter image description here

Model:

public class User
    {
        public List<UserModel> users { get; set; }
    }
    public class UserModel
    {
        public int id { get; set; }
        public string firstName { get; set; }
        public string lastName { get; set; }


    }

action:

[Route("user/{firstName}")]
        public User GetUser(string firstName)
        {
            using (StreamReader r = new StreamReader("mydata/userData.json"))
            {
                string json = r.ReadToEnd();
                User item = JsonConvert.DeserializeObject<User>(json);
                return item;
            }
            return new User();
           
        }

result: enter image description here

Comments

1

First of all, in asp.net core you are only able (by default) to read data from the wwwroot folder. If you want to change that, then refer here.

Second of all, you are trying to read only single object, but in you json file, there are multiple user objects. You can fix this by replacing your code User item =JsonConvert.DeserializeObject<User>(json); by this List<User> items = JsonConvert.DeserializeObject<List<User>>(json);

And finally, as mentioned in comments, when you StreamRead, you reference wrong file... Also it's better if you reference the file using enviromental variables

Hope I helped!

Comments

0

1-) Sample path;

StreamReader r = new StreamReader(@"C:\Users\Suleyman\Desktop\users.json");

2-) sample;

  public List<User> GetUser(string firstName){}


List<User> item = JsonConvert.DeserializeObject<List<User>>(json);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.