Aspnetcore: Make component binding case-sensitive

Created on 30 Apr 2019  路  6Comments  路  Source: dotnet/aspnetcore

Summary

We've going to change component binding to be case-sensitive and add warnings for cases where you made an obvious mistake. We've treated all of these issues as conventions or recommendations thus far, but having components fail to bind usually results is really vexing compiler errors from C#

  • [x] Make compiler bind components case-sensitively
  • [x] Make completion of components and attributes case-sensitive (not the case today when an attribute has the same name a known HTML thing)
  • [x] Add a diagnostic for components attempting to use lower case
  • [x] Add a diagnostic for elements that start with a capital letter but don't match a component

The problem

Suppose that you rename a component without renaming all of the usages (or suppose you change the namespace). If you were using event handlers with that component:

<MyButton OnClick="Clicked" Message="So enticing, you know you want to click!"/>
@code {
    void Clicked() {
        ...
    }
}

You now get a compile error that says something like Cannot convert method group Clicked to type System.Object.. This is because method-group-to-delegate-conversion doesn't support object, but it's fairly common with components.

You now miss the forest for the trees. You're distracted from the root cause, which is that the MyButton tag didn't resolve to a component.

Solution

We've had on the roadmap for a while to make binding case-sensitive. So this is not really a surprise.

The additional goal is to detect and warn in the case where a developer tries to reference a component, but no such component is found. Currently the behavior is to treat it as an HTML element, which is potentially very confusing.

To fix this, we want to turn the PascalCasing of component names into a stronger, built-in convention:

  1. If you try to compile a component whose name starts with a lowercase character in a-z, fail the compilation with an error (Component names cannot start with lowercase characters).

    • I don't think we can do this as a suppressible warning, because where would you put the suppression?
    • I think this rule is correct internationally. We're not stopping you from starting a component name with some non-Roman character, since that's not ambiguous.
  2. Each time something in your .razor source resolves as an element (not a component), check that its name starts with a lowercase character in a-z. If we find an element whose first char isn't in a-z case sensitively, emit a warning (Found markup element with unexpected name '{0}'. If this is intended to be a component, add a @using directive for its namespace.).

    • Again, I think this is right internationally, because all standard HTML element names do start with a character in a-z (case-insensitively), and will do probably forever.
  3. Allow the warning from (2) to be suppressed. See https://github.com/aspnet/AspNetCore/issues/9786#issuecomment-487223538

Done XL area-blazor enhancement

Most helpful comment

Does this also imply that a

Yes

All 6 comments

To fix this, we want to turn the PascalCasing of component names into a stronger, built-in convention:

Does this also imply that a <Button> component won't collide with HTML's <button>?

Does this also imply that a

Yes

I'm a traditional Xaml developer and can say that most Xaml developers are turned off by HTML syntax. Pascal-case brings a lot of authority and elegance to symbols, IMO. Plus it's consistent with C# and VB.NET, of course.

That said, Blazor's syntax has a lot going for it. I think the more Pascal-case you bring to the table, the more adoption -- and perhaps, less complaining 馃槅 -- you're going to see from Xaml developers as there won't be so much Frankenstein inconsistency between .NET and HTML symbols.

Forcing Pascal-case for .NET symbols is a major win, IMO. It will make it easier to know what is HTML and what is .NET, especially for the newbs such as myself who are onboarding and are learning the terrain.

FWIW, it would be ideal to take it a step further and _allow_ (read: not require) the directives themselves to be Pascal-cased as well, e.g. @Bind="...".

In any case, thank you for all your efforts here. Very impressed with and excited for Blazor. 馃憤

@ajaybhargavb - one of the first considerations here is to make sure the the WTE editor is updated to align with this behavior. So, we need to do gap analysis - are there places where WTE would complete or colorize things differently from what we expect.

<3 @ajaybhargavb - make sure you blast out an email update when we have a build of VS 馃憤

@ajaybhargavb Really glad to see this go in! This is a huge improvement 馃槃

Was this page helpful?
0 / 5 - 0 ratings