skip to Main Content

I have a json file to store all the messages in the application, for example :

{
    "MSG_1": {
        "en":"Something went wrong, please try again later",
        "ar":"..."
    },
    "MSG_2": {
        "en": "User created successfully",
        "ar": "..."
    },
    "MSG_3": {
        "en": "Phone number already exists",
        "ar": "..."
    },
    "MSG_4": {
        "en": "Validation Error, Fix it then try again",
        "ar": "..."
    }
}
  • I extracted the josn into variable with this DataType Dictionary<string, Dictionary<string, string>> everything working fine to read the values from this json like this : jsonValues["MSG_1"]["en"]

With this way I faced some typo issues, I want to use this json as model and everytime I update the json file the model will update it self automaticlly.

I built something to fix the issue:

public class BusinessMessagesModel{
    // I want to add some other Msg in this model automaticlly.
    public MSGModel Msg {set; get;}
}

public class MSGModel{
    public required string En {get; set;}
    public required string Ar {get; set;}
}

I want to use the json file like this :

string value = businessMessagesModel.MSG_1.en; 

Output : Something went wrong, please try again later

3

Answers


  1. This seems like a very bad idea, but if you want to do it anyway you can write a source generator with a dependency on your json as an "additional file" that will build your models for you at compile time.

    Login or Signup to reply.
  2. i would not suggest to store data in json due to usage you need at compile time.
    so something like this string value = businessMessagesModel.MSG_1.en – will be available at compile time.

    as a different approach i would suggest:
    this is example to have class as enum which you can add messages at compilation and dynanicaly pick base on key name…

    public sealed class RejectReasons
    {
        public static RejectReasons SI { get; } = new RejectReasons("SI", "INVALID SELLER ID");
        public static RejectReasons SD { get; } = new RejectReasons("SD", "INVALID SELLER DBA NAME");
        public static RejectReasons SM { get; } = new RejectReasons("SM", "INVALID SELLER MCC");
        public static RejectReasons SS { get; } = new RejectReasons("SS", "INVALID SELLER STREET ADDRESS 1");
        public static RejectReasons SN { get; } = new RejectReasons("SN", "INVALID SELLER CITY NAME");
        public static RejectReasons SR { get; } = new RejectReasons("SR", "INVALID SELLER REGION CODE");
        public static RejectReasons SP { get; } = new RejectReasons("SP", "INVALID SELLER POSTAL CODE");
        public static RejectReasons SC { get; } = new RejectReasons("SC", "INVALID SELLER COUNTRY CODE");
        public static RejectReasons SU { get; } = new RejectReasons("SU", "INVALID SELLER CURRENCY CODE");
        public static RejectReasons SL { get; } = new RejectReasons("SL", "INVALID SELLER LANGUAGE(Canada)");
        public static RejectReasons AX { get; } = new RejectReasons("AX", "AMEX ISSUE.Please contact Premium Partner Servicing for details.");
    
        private RejectReasons(string name, string description)
        {
            Name = name;
            Description = description;
        }
    
        public string Name { get; }
        public string Description { get; }
    
        public override string ToString() => Name;
        public static IEnumerable<string> GetNames() => GetValues().Select(RejectReasons => RejectReasons.Name);
        public static string GetValue(string name) => GetValues().FirstOrDefault(RejectReasons => RejectReasons.Name == name)?.Description;
    
        public static IReadOnlyList<RejectReasons> GetValues()
        {
            return typeof(RejectReasons).GetProperties(BindingFlags.Public | BindingFlags.Static)
                .Select(property => (RejectReasons)property.GetValue(null))
                .ToList();
        }
    
    }
    

    usage:

    RejectReasons.GetValues(); //will return all as List<rejectedReasons>
    RejectReasons.GetValue("AX").Dump(); // will return text
    

    UPDATE:
    another option is to use class as enumerator would be close to haw you want to use yours solution.
    Without JSON

    
    public static class JobSettings
    {
        public static JobOptions ExcesiveReattempts { get; } = new JobOptions("ExcessiveReattempts msg");
        public static JobOptions VisaDataConsistancy { get; } = new JobOptions("DataConsistancy msg");
        public static JobOptions VisaExcessiveFallbacks { get; } = new JobOptions("ExcessiveFallbacks msg");
    }
    
    public class JobOptions
    {
        public string Msg {get;set;}
        
        public JobOptions() {}
        public JobOptions(string msg)
        {
            Msg = msg;
        }
    }
    

    usage

    Console.WriteLine(JobSettings.ExcesiveReattempts.Msg);
    
    Login or Signup to reply.
  3. Your structure when viewed as a table means for every new message, your adding a new column to the table. (and that’s why you have the mess of having to re-generate the class each time).

    Why not make the Message ID a column like all the other fields?

    Hence this:

    [
        {
          "ID": 0,
          "en": "Something went wrong, please try again later",
          "ar": "..."
        },
        {
          "ID": 1,
          "en": "User created successfully",
          "ar": "..."
        },
        {
          "ID": 2,
          "en": "Phone number already exists",
          "ar": "..."
        },
        {
          "ID": 3,
          "en": "Validation Error, Fix it then try again",
          "ar": "..."
        }
    ]
    

    So, now in code you can read/load the above into a list,

    Say this class:

    public class Msg
    {
        public int id { get; set; }
        public  string en { get; set; }
        public string ar { get; set; }
    
    }
    

    And now to load the above, we have this:

            string sFile = @"c:testmsg.txt"; 
    
            string sjson = File.ReadAllText(sFile);
    
            msgs = JsonConvert.DeserializeObject<List<Msg>>(sjson);
    
            Debug.Print(msgs[0].en);
            Debug.Print(msgs[1].en);
    

    So, you address each message by a number, but you have to lookup, and know that number, so LITTLE advantages by using a column name for the message number.

    The above is thus not only far more friendly, but allows you to pull such data into a List "of some class" item.

    This will allow you to make a nice editor for all the messages, and editing, or adding new messages becomes rather simple.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search