Open IngoManthey opened 3 years ago
Currently not possible, but its a feature i plan to add, but i am prioritizing the main library atm.
It would be nice if the Theme could be JSON Serializeable. At the moment I get following Exception for 'MudBlazor.Utilities.MudColor'
Unhandled exception rendering component: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'MudBlazor.Utilities.MudColor'. Path: $.Theme.Palette.Black | LineNumber: 0 | BytePositionInLine: 30.
System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'MudBlazor.Utilities.MudColor'. Path: $.Theme.Palette.Black | LineNumber: 0 | BytePositionInLine: 30.
---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'MudBlazor.Utilities.MudColor'.
--- End of inner exception stack trace ---
It would be nice if the Theme could be JSON Serializeable. At the moment I get following Exception for 'MudBlazor.Utilities.MudColor'
Unhandled exception rendering component: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'MudBlazor.Utilities.MudColor'. Path: $.Theme.Palette.Black | LineNumber: 0 | BytePositionInLine: 30. System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'MudBlazor.Utilities.MudColor'. Path: $.Theme.Palette.Black | LineNumber: 0 | BytePositionInLine: 30. ---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'MudBlazor.Utilities.MudColor'. --- End of inner exception stack trace ---
You can use Newtonsoft.Json to deserialize the same as I was also getting same error while deserializing with System.Text.Json
With Newtonsoft we are able serialize the ThemeManagerTheme object but not with System.Text.JSON. So for this particular case we used Newtonsoft to save the object,
` ThemesPropertyEntity themeProperties = new ThemesPropertyEntity();
themeProperties.PropertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(value);
themeProperties.PropertyID = uThemesProperty.PropertyID;
themeProperties.PropertyName = uThemesProperty.PropertyName;
themeProperties.PropertyType = value.GetType().ToString();
themeProperties.ThemeID = id;
await themepropertyservice.AddThemesProperty(themeProperties);
_themeManager = value;
await InvokeAsync(StateHasChanged);`
I'd like to add the request to also load a deserialized json into the mudblazor ThemeProvider. I couldn't figure out any way to accomplish that
I'd like to add the request to also load a deserialized json into the mudblazor ThemeProvider. I couldn't figure out any way to accomplish that
Theoretically you can write custom JsonConverter and it should work.
For example a custom MudColor
converter for System.Text.Json
that is working.
public class MudColorSerializer : JsonConverter<MudColor>
{
public override MudColor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Expected StartObject token");
}
byte R = 0, G = 0, B = 0, A = 0;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return new MudColor(R, G, B, A);
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string propName = reader.GetString();
reader.Read();
switch (propName)
{
case "r": R = reader.GetByte(); break;
case "g": G = reader.GetByte(); break;
case "b": B = reader.GetByte(); break;
case "a": A = reader.GetByte(); break;
}
}
throw new JsonException("Expected EndObject token");
}
public override void Write(Utf8JsonWriter writer, MudColor value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber("r", value.R);
writer.WriteNumber("g", value.G);
writer.WriteNumber("b", value.B);
writer.WriteNumber("a", value.A);
writer.WriteEndObject();
}
}
You just need to add it to the JsonSerializerOptions.Converters
I'd like to add the request to also load a deserialized json into the mudblazor ThemeProvider. I couldn't figure out any way to accomplish that
Theoretically you can write custom JsonConverter and it should work. For example a custom
MudColor
converter forSystem.Text.Json
that is working.public class MudColorSerializer : JsonConverter<MudColor> { public override MudColor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException("Expected StartObject token"); } byte R = 0, G = 0, B = 0, A = 0; while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return new MudColor(R, G, B, A); } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string propName = reader.GetString(); reader.Read(); switch (propName) { case "r": R = reader.GetByte(); break; case "g": G = reader.GetByte(); break; case "b": B = reader.GetByte(); break; case "a": A = reader.GetByte(); break; } } throw new JsonException("Expected EndObject token"); } public override void Write(Utf8JsonWriter writer, MudColor value, JsonSerializerOptions options) { writer.WriteStartObject(); writer.WriteNumber("r", value.R); writer.WriteNumber("g", value.G); writer.WriteNumber("b", value.B); writer.WriteNumber("a", value.A); writer.WriteEndObject(); } }
You just need to add it to the
JsonSerializerOptions.Converters
Thanks! It works perfectly. I had to change this:
string propName = reader.GetString();
because my json exported with capital letters
string propName = reader.GetString().ToLower();
For Anyone who needs a copy/paste of using this:
string jsonString = "{ \"Palette\": { \"PrimaryDarken\": \"rgb(62,44,221)\", \"Black\": { \"Value\": \"#ffffffff\", \"R\": 255, \"G\": 255, \"B\": 255, \"A\": 255, \"APercentage\": 1, \"H\": 0, \"L\": 1, \"S\": 0 } , \"White\": { \"Value\": \"#ffffffff\", \"R\": 255, \"G\": 255, \"B\": 255, \"A\": 255, \"APercentage\": 1, \"H\": 0, \"L\": 1, \"S\": 0 } } }";
var options = new JsonSerializerOptions();
options.WriteIndented = true;
options.Converters.Add(new MudColorSerializer());
var theme = JsonSerializer.Deserialize<MudTheme>(jsonString, options)!;
Is opening and saving a theme is now supported from the theme manager itself? There is the option to load a preset but it's saying "Not Implemented". Is it planned to work soon?
By the way, the MudColorSerializer
should no longer be necessary if you are using MudBlazor v7. In MudBlazor v7, I have implemented native support for System.Text.Json and Newtonsoft. You can find more information at https://github.com/MudBlazor/MudBlazor/pull/8579.
Is opening and saving a theme is now supported from the theme manager itself? There is the option to load a preset but it's saying "Not Implemented". Is it planned to work soon?
There are no current plans for this. This repository has a very low priority and is in maintenance mode, with only myself handling it when it breaks with new versions of MudBlazor. However, you can submit a pull request with this feature, and I would gladly review and accept it.
When I have created a theme with the ThemeManager, how can I save it to? add it as a MudTheme in my project?
best regards Ingo