Closed arivoir closed 4 years ago
We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.
This has been added in preview 7 - https://github.com/aspnet/AspNetCore/pull/10730 Note that preview 6 is the next release so you will have to wait a few weeks.
How will this finally work? adding the type converter attribute in each property, or can the attribute be specified in the class so it's globally taken?
Implement ToString()
on your class, and then implement a TypeConverter
and register with the attribute on your class.
I'm clear about registering the TypeConverter on the class, this way the converter can parse the string, but why is the ToString necessary?
ToString is used to convert the value to a string. We don't use the type converter at this point because we don't easily know what cases require it.
The idea of using the TypeConverter is to parse the string to the actual class, not the other way round. Can you clarify? I'm really confused by your statement. Will TypeConverter work or not?
Yes, the type converter is used in parsing.
While writing the release notes we realized this issue was closed as done by mistake. @bind-Value
and other @bind
related constructs support type converters.
We do not do any conversions when setting component parameters directly.
An (I think) elegant solution is to use the implicit conversion/cast operator in your C1Color
class. In that scenario, create an implicit cast from string
to C1Color
. See more here: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/user-defined-conversion-operators
With that, I am not sure what additional benefit TypeConverter
s have? Do they support interfaces? In that case, they can do stuff implicit operators cannot.
@egil The implicit operator is not working as expected. Despite so, it improves a little the razor assignment as now I can omit part of the class and method
Previously
GridLinesColor="@C1Color.Parse("#FFD0D7E5")"
Using implicit operator
GridLinesColor="@("#FFD0D7E5")"
Desired
GridLinesColor="#FFD0D7E5"
@rynowak When can we expect this to be addressed?
When can we expect this to be addressed?
I don't know that we'd ever do something like this. One of the advantages of Blazor is that you write C# code. I don't feel like Color.Parse(...)
has significant drawbacks.
Using type converters for parameters is something that's done in other languages like XAML that don't let you write code.
Using type converters for parameters is something that's done in other languages like XAML that don't let you write code.
What do you mean? Why there are some classes like string or int that can be assigned directly without the "@" and others like enums or custom classes that need them?
I'm not sure from the context if you're talking about Razor or XAML.
In Razor strings are special because attributes naturally use the same syntax as a .NET string. Otherwise you'd end up writing something like the following.
<div class="@("foo")" >
...
</div>
Please compare the readability of one code and the other and tell me what's easier to read
In Razor strings are special because attributes naturally use the same syntax as a .NET string. Otherwise you'd end up writing something like the following.
<div class="@("foo")" > ... </div>
Also bool and int are special, why only those? Why not enums? It looks the problem was resolved for a small set of types, but it persist for enums and custom types
Also bool and int are special, why only those? Why not enums?
No, I have to disagree. Those are using the normal C# syntax for bools and ints. Likewise, you use the normal C# syntax for enums and other types.
Those are using the normal C# syntax for bools and ints.
In preview7 that's incorrect, bool's can be specified using the c# syntax by appending the "@" before "true" or "false" terms, but they are also "special" and can be set without using the "@". My point is not only those types will benefit from being "special", other types too, especially enums. In this end this will help readability of razor files.
Whether or not an @
is required inside a component attribute is a function of the type of the declaring parameter. String-typed parameters are text by default because otherwise the syntax would be gross.
<MyComponent
BoolParameter="<this is C#>"
StringParameter="<this is text>"
AnotherStringParameter="@<now this is C#>"/>
String-typed parameters are text by default because otherwise the syntax would be gross.
The same reasoning would apply for any other type that has an implicit string cast operator. The syntax end up being gross. I'm still trying to understand where the reluctancy to improve this scenario comes from. I understand there could be reasons, but I haven't heard the arguments yet.
I'm still trying to understand where the reluctancy to improve this scenario comes from. I understand there could be reasons, but I haven't heard the arguments yet.
My reluctance is that it's different from C# and it doesn't have to be. We have to choose a default for each attribute - are you in a C# context or a text context. Every time an attribute is different, or unique, that's something that consumer have to learn about instead of just writing normal C#.
I don't think that shorter necessarily means better.
My reluctance is that it's different from C# and it doesn't have to be. We have to choose a default for each attribute - are you in a C# context or a text context. Every time an attribute is different, or unique, that's something that consumer have to learn about instead of just writing normal C#
What's the semantical difference between assigning a string directly or having to use a "@" plus parentheses?
GridLinesColor="@("#FFD0D7E5")" vs GridLinesColor="#FFD0D7E5"
Sorry I don't get your point. What you say it is different from c# is exactly what Blazor is doing right now with string class to avoid gross syntax, as you described. You are contradicting your own argument.
I don't think that shorter necessarily means better.
I agree, but in this case I think the extra "@" and "()" doesn't give any advantage to the users, all the contrary it makes the razor language boilerplate unnecessarily.
Sorry I don't get your point. What you say it is different from c# is exactly what Blazor is doing right now with string class to avoid gross syntax,
Right. Strings are special cased because the alternative is awful.
If you want to use some other type that isn't a string, there is no extra ceremony required.
@{
Color color = ....
}
<SomeComponent Color="color" />
<SomeComponent Color="new Color("#FFFFFF")" />
Right. Strings are special cased because the alternative is awful.
We both agree about this.
<SomeComponent Color="new Color("#FFFFFF")" />
I think I'm starting to get your point. I thought the above didn't work unless an "@" would be used. I imagined that inserting a peace of c# inside html would require the "@" (and the lack of intelli-sense coloring for some cases made me confuse).
Anyway I wonder if requiring the "@" to change context wouldn't be a better alternative to actual implementation. It would be more intuitive, the string case wouldn't be different from the rest, and it would allow enums and custom classes to be more easily specified. What do you think?
Anyway I wonder if requiring the "@" to change context wouldn't be a better alternative to actual implementation. It would be more intuitive, the string case wouldn't be different from the rest, and it would allow enums and custom classes to be more easily specified. What do you think?
We considered and rejected this because:
@
to change to C# context breaks compound expressions like 3 + 5
We're on the same page now. Thanks for taking time to explain this to me. I'll try to catch up with TagHelpers https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-2.2
Does TagHelpers work in Blazor?
No, tag helpers are incompatible at a fundamental level. TagHelpers output text, Blazor is like an instruction language for markup.
I'm having trouble to understand this argument
- Existing ASP.NET Core (TagHelpers) already put you in a C# context
I wonder if this applies to Blazor anyhow.
Regarding the other argument
- Requiring @ to change to C# context breaks compound expressions like 3 + 5
I would feel rather natural to need to use the "@" in this case.
MyProperty="@(3+5)"
I wonder if this applies to Blazor anyhow.
We want to be consistent and avoid two technologies that look the same with totally different semantics.
We want to be consistent and avoid two technologies that look the same with totally different semantics.
I can understand this. But anyway I don't get what does this mean "TagHelpers already put you in a c# context" and how is this related to the fact that the component attributes are actually c# code even if the "@" is not specified?
They are consistent today. Like I said, we considered a change and decided to do the same thing tag helpers do.
Whether or not an
@
is required inside a component attribute is a function of the type of the declaring parameter. String-typed parameters are text by default because otherwise the syntax would be gross.<MyComponent BoolParameter="<this is C#>" StringParameter="<this is text>" AnotherStringParameter="@<now this is C#>"/>
This was the post that clarified to me how Blazor is working.
I've had some time to think on this, and still think there could be a way to use TypeConverter. You said there is a function that determines whether the parameter type is a string and in that case assigns the string directly into the property, otherwise the attribute value is c#.
My point is the function that determined the kind of content inside the attribute, could use https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.typeconverter.canconvertfrom?view=netframework-4.8 with typeof(string) to determine whether the attribute value is a plain string of c#. Wouldn't that work?
Thanks for contacting us. After some further discussion regarding this we believe this is not something we plan to do.
I'm am trying to add a parameter of type "C1Color" I created to a razor component, and I'd like to pass it as a string.
Is there any way to use System.ComponentModel.TypeConverter for these scenarios?
I know I can do something like this
But I want to avoid it.