dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.46k stars 10.03k forks source link

There is no documented way to reuse interactive markup in a Razor page #41107

Open Neutrino-Sunset opened 2 years ago

Neutrino-Sunset commented 2 years ago

Is there an existing issue for this?

Describe the bug

How are you supposed to reuse UI markup in Razor pages?

After completing the Hello World tutorial for Razor pages, the first thing that you will notice is that you have view files full of duplicated markup like this.

<form method="post">
   <div asp-validation-summary="ModelOnly" class="text-danger"></div>
   <input type="hidden" asp-for="Movie.Id" />

   <div class="form-group">
      <label asp-for="Movie.Title" class="control-label"></label>
      <input asp-for="Movie.Title" class="form-control" />
      <span asp-validation-for="Movie.Title" class="text-danger"></span>
   </div>

   <div class="form-group">
      <label asp-for="Movie.ReleaseDate" class="control-label"></label>
      <input asp-for="Movie.ReleaseDate" class="form-control" />
      <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
   </div>

   <div class="form-group">
      <label asp-for="Movie.Genre" class="control-label"></label>
      <input asp-for="Movie.Genre" class="form-control" />
      <span asp-validation-for="Movie.Genre" class="text-danger"></span>
   </div>

   <div class="form-group">
      <label asp-for="Movie.Price" class="control-label"></label>
      <input asp-for="Movie.Price" class="form-control" />
      <span asp-validation-for="Movie.Price" class="text-danger"></span>
   </div>

   <div class="form-group">
      <label asp-for="Movie.Rating" class="control-label"></label>
      <input asp-for="Movie.Rating" class="form-control" />
      <span asp-validation-for="Movie.Rating" class="text-danger"></span>
   </div>

   <div class="form-group">
      <input type="submit" value="Save" class="btn btn-primary" />
   </div>

</form>

Naturally you will want to extract that duplicated markup into a reusable component.

This can be done using a partial file and Html Helpers like this.

@{
   string propertyName = (string)ViewData["PropertyName"];
}

<div class="form-group">

   @Html.Label(propertyName, null, new{ @class = "control-label" })
   @Html.Editor(propertyName, new { htmlAttributes = new { @class = "form-control" } })
   @Html.ValidationMessage(propertyName, null, new{ @class = "text-danger" })

</div>

Which can then be invoked like this

<form method="post">
   <div asp-validation-summary="ModelOnly" class="text-danger"></div>
   <input type="hidden" asp-for="Movie.Id" />

   <partial name="_MovieField" for="Movie"
            view-data='new ViewDataDictionary(ViewData){ {"PropertyName", "Title" }}' />

   <partial name="_MovieField" for="Movie"
           view-data='new ViewDataDictionary(ViewData){ {"PropertyName", "ReleaseDate" }}' />

   <partial name="_MovieField" for="Movie"
            view-data='new ViewDataDictionary(ViewData){ {"PropertyName", "Genre" }}' />

   <partial name="_MovieField" for="Movie"
            view-data='new ViewDataDictionary(ViewData){ {"PropertyName", "Price" }}' />

   <partial name="_MovieField" for="Movie"
            view-data='new ViewDataDictionary(ViewData){ {"PropertyName", "Rating" }}' />

   <div class="form-group">
      <input type="submit" value="Save" class="btn btn-primary" />
   </div>

</form>

However, working out how to do this will likely take you several days, since there is no documentation on Html helpers in the current ASP documentation. Where Html Helpers are mentioned they link to documentation that is 13 years old and uses classic ASP syntax that does not work in Razor pages at all.

What you will find in the current ASP documentation is lots of mention of Tag Helpers. But there does not seem to be any way to achieve this kind of basic markup reuse using Tag Helpers since the asp-for expressions they use to create Form controls only accept hard-coded expressions.

When you start asking around how this should be done and where is the documentation for Html Helpers you may well be told that up to date documentation for Html Helpers isn't required because they should probably be removed anyway.

https://github.com/dotnet/AspNetCore.Docs/issues/25494

Which is all a bit confusing. How are you supposed to effectively reuse markup if the only way to do it is using Html Helpers, and they don't have any documenation, and may end up being removed?

Expected Behavior

No response

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

6.0.201

Anything else?

.NET SDK (reflecting any global.json): Version: 6.0.201 Commit: ef40e6aa06

Runtime Environment: OS Name: Windows OS Version: 10.0.19043 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.201\

Host (useful for support): Version: 6.0.3 Commit: c24d9a9c91

.NET SDKs installed: 3.1.300 [C:\Program Files\dotnet\sdk] 5.0.302 [C:\Program Files\dotnet\sdk] 5.0.406 [C:\Program Files\dotnet\sdk] 6.0.201 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Neutrino-Sunset commented 2 years ago

@TanayParikh Why have you moved this from AspNetCore to AspNetCore.Docs? This is an issue with the library not the documentation.

It seems clear that Tag Helpers are intended to be the way to generate and enrich markup going forward, but the fact that the builtin form control tag helpers don't work with partials or view components completely breaks any effective markup reuse strategy.

One of the main features of ASP is the ability to do things like have server-side and client-side validation driven by model attributes, which is implemented by tag helpers. But markup reuse is also a basic requirement of any web app framework, so having one of the key features of the framework not working in any markup reuse scenario is surely a massive issue.

TanayParikh commented 2 years ago

However, working out how to do this will likely take you several days, since there is no documentation on Html helpers in the current ASP documentation.

I'd skimmed your issue and saw this, so I was under the impression this was a docs request.

ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.