-1

Currently I am trying to write the data from my list, to a JSOn file. I have already read a very similar post to this issue, only for some reason it does not seem to work for me.

This is my model:

namespace ERP.Classes
{
    public class User_Role
    {
        public string RoleId { get; init; }
        public string RoleName { get; set; }
        public string RoleDescription { get; set; }
        public List<User> Users { get; set; }

        public User_Role(string roleName, string roleDescription)
        {
            RoleId = Guid.NewGuid().ToString("N");
            RoleName = roleName;
            RoleDescription = roleDescription;
            Users = new List<User>();
        }
    }
}

This is my razor page, where i want to create this list and save the JSON file:

@page "/user_roles"
@using ERP.Classes
@using Microsoft.AspNetCore.Components.Forms

<PageTitle>User Roles</PageTitle>

<h1>User Roles</h1>

<EditForm Model="@_userRoles" OnValidSubmit="@createRoleName"> 
    <InputText id="roleName" @bind-Value="_roleName"/>
    <InputText id="roleDescription" @bind-Value="_roleDescription"/>
    <button type="submit">Create user role</button>
</EditForm>
<p>@_confirmation</p>
<table>
    <tr>
        <th><h5>Role Id</h5></th>
        <th><h5>Role Name</h5></th>
        <th><h5>Role Description</h5></th>
    </tr>
    @foreach(User_Role list in _userRoles)
    {
        <tr>
            <td>@list.RoleId</td>
            <td>@list.RoleName</td>
            <td>@list.RoleDescription</td>
        </tr>
    }
</table>
// Button to call the method
<button onclick="@saveData">Save</button>

@code {
    private string _confirmation = "";
    private string _roleName = "";
    private string _roleDescription = "";
    private List<User_Role> _userRoles = new List<User_Role>();

    private void createRoleName()
    {
        if(roleExists(_userRoles,_roleName))
        {
            _confirmation = "Role already exists";
        }
        else
        {
            User_Role _userRole = new User_Role(_roleName,_roleDescription);
            _userRoles.Add(_userRole);
            _confirmation = "Role created";
        }        
    }

    private List<User_Role> loadRoles()
    {
        return _userRoles;
    }
    // Calling the SaveData class to send over the data
    private void saveData()
    {                
        SaveData<User_Role> _data = new SaveData<User_Role>();
        _data.SavetoJson("userRoles.txt",_userRoles);
    }

    private bool roleExists(List<User_Role> user_Roles, string currentRoleName)
    {
        bool hasRole = false;
        foreach(var item in user_Roles)
        {
            if(item==null)
            {
                hasRole = false;
            }          
            else if(item.RoleName == currentRoleName)
            {
                hasRole = true;
            }
        }
        return hasRole;
    }
}

This is the class with the save functionality:

using System.Collections.Generic;
using Newtonsoft.Json;

namespace ERP.Classes
{
    public class SaveData <T>
    {
        public void SavetoJson(string filename, List<T> dataList)
        {
            using (StreamWriter file = File.CreateText(@"C:\Data\" + filename))
            {
                JsonSerializer serializer = new JsonSerializer();
                serializer.Serialize(file, dataList);
            }
        }
    }
}

The reason for making my SaveData class generic, is so that i can use this for all my other models aswell. To prevent repetitive coding. But for some reason it does not create the json file. I have tried it with both ".txt" and ".json". I am quite new to programming, so excuse me if this has been answered already. But I was unable to find it.

  • On the method SavetoJson, after the ")" put this "where T : class" – Camadas Mar 21 '23 at 14:02
  • @Camadas I did this so it now looks like this 'public void SavetoJson(string filename, List dataList) where T : class', but I am getting the error : Constraints are not allowed on non-generic declarations – DrSjoers Mar 21 '23 at 14:32
  • Hi and welcome to SO. I tried your code and it creates the file just fine for me. I had to mock the `User` class since you didn't provide the definition so there is a chance the serializer is unable to work with it. Are you getting any errors? Have you stepped through the code? What do you see? Does your list have the items you think it has? – JuanR Mar 21 '23 at 14:38
  • @JuanR Thanks! the only thing i am getting is a warning that states: Converting method group 'saveData' to non-delegate type 'object'. Did you intend to invoke the method? When I step through all the steps for the method and it has all the values that I am expecting. From the complete User_Role and the User object itself. – DrSjoers Mar 21 '23 at 14:56
  • @DrSjoers have you stepped through the code for the `SavetoJson` method? Line by line? What does it do? Are you sure you are looking in the right folder? It makes no sense that it would not output a file and not break. These are mutually exclusive. – JuanR Mar 21 '23 at 15:09
  • @JuanR thank you for your time to respond. I stepped trough the method, and the only thing that i noticed that it got "stuck" twice on the streamwriter. I also noticed a lot of null values in the file variable. Could it be that my path is wrong? Even though i copied it from my file explorer. It did not break though, neither did it create a file – DrSjoers Mar 21 '23 at 15:22
  • Where do you want to save the data? To the `C:\Data` directory on the server, or on the client? Blazor `@code` code [runs on the server](https://stackoverflow.com/a/62180959) so it looks like you are trying to save to the server's `C:\Data` directory, but are you sure your Blazor app even has permission to access that directory? Alternatively, if you want to save the file on the client, take a look at [How can one generate and save a file client side using Blazor?](https://stackoverflow.com/q/52683706). – dbc Mar 21 '23 at 16:29
  • By the way, although this is unlikely to be the cause of your problem, you should use [`Path.Combine(@"C:\Data", filename)`](https://learn.microsoft.com/en-us/dotnet/api/system.io.path.combine) rather than string concatenation to construct the full path to your file. – dbc Mar 21 '23 at 16:31
  • 1
    @dbc thank you for the response! It is running on the client, so that is indeed the cause of the issue. I will be using a database for storage instead. – DrSjoers Mar 22 '23 at 08:52

1 Answers1

-1

try this

public void SavetoJson(string filename, List<T> dataList)
 {
   var json = JsonConvert.SerializeObject(dataList);

   var path = @"C:\Data\"; 
  
  File.WriteAllText(Path.Combine(path, filename), json);

and the most important that the path folder should have permissions to keep and change the applicaton data

Serge
  • 40,935
  • 4
  • 18
  • 45
  • Thank you for your response! I tried this, but the filename here does not specify the path where I want it to be stored. Neither did it when i did give the path for the destination folder. – DrSjoers Mar 21 '23 at 15:30