Search code examples
c#razorblazorthis

How to iterate over "this" keyword in c# and Blazor


I currently am trying to dynamically get all variables for a given page using the "this" keyword and convert it to a JSON format. I can see that the "this" keyword contains all the information I am looking for but when trying to convert using JsonConvert.SerializeObject(this) it returns an empty string.

I have gone about the route of possibly doing a foreach on the "this" value but get an error that the page's class doesn't contain a definition for GetEnumerator. I'm looking for a way to either iterate over "this" by typecasting it to an IEnumerable or correctly implement the GetEnumerator definition to be able to iterate over the object itself. My ultimate goal is to get something like

string jsonData= "";

foreach (var item in this)
{
    jsonData += JsonConvert.SerializeObject(item);
}

or even better just string

jsonData = JsonConvert.SerializeObject(this);

A more proper example may be within a file "Pages/Index" having

@page "/home"
<h2>HELLO WORLD</h2>
@code{
int tester = 13;
NavigationManager navMan = new NavigationManager();
UserService user = new UserService();
}

Theoretically I could do

string jsonData = "";
jsonData += JsonConvert.SerializeObject(this.user);
jsonData += JsonConvert.SerializeObject(this.navMan);
...

which would work correctly but would be very time consuming given some pages contain hundreds of variables.

By running the server in debugger I can see within "this" it contains something such as

navMan | Microsoft.AspNetCore.Components.Server.Circuits.RemoteNavigationManager
user | Services.UserService
tester | 13

Which in itself by expanding one like "user" I can see it contains for values for name, email, etc.

By doing jsonData += JsonConvert.SerializeObject(this.user);, I get back the name, email, etc. variable names and values saves into jsonData but would like to do this for each of the objects within "this" without having to hardcode each variable into the SerializeObject function


Solution

  • The reason JsonConvert.SerializeObject(this); returns empty json is because by default Newtonsoft.Json serializes only public members. So I enabled serialization of all members by adding.

    @attribute [JsonObjectAttribute(MemberSerialization = MemberSerialization.Fields)]
    

    Then I got exception 'Self referencing loop detected...' so to fix that I added.

    string jsonData = JsonConvert.SerializeObject(this, new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });
    

    After that I got exception 'Operation is not supported on this platform.'. So at that point I stopped because it looks like trying to serialize the whole razor component is a bad idea.

    So instead of all this nonsense I suggest to simply manually add [JsonProperty] to the members that you want to get serialized and hope for the best:

    @page "/home"
    
    <h2>HELLO WORLD</h2>
    
    @code {
        [JsonProperty]
        int tester = 13;
    
        [JsonProperty]
        [Inject]
        NavigationManager navMan { get; set; }
    
        [JsonProperty]
        UserService user = new UserService();
    
        protected override void OnInitialized()
        {
            string jsonData = JsonConvert.SerializeObject(this);
        }
    }