In .cshtml file, I can use the convenient tag helpers such as asp-area, asp-page, but are these still possible in .razor file? I have a razor component, inside the code, I am building the breadcrumb links, and I thought I can do something like <a asp-page="@PageName">My Page</a>, but end up I have to hard code the link such as <a href="Area1/MyPage">My Page</a>. The @PageName is the value generated from within the class that inherits the ComponentBase.
Hello @Locomotion77 ... Blazor has a different rendering that creates structured markup, not HTML strings like Tag Helpers do. There are two different bulding/rendering technologies at play here. In your scenario, can you write the element as <a href="@PageName">My Page</a> and set the PageName property in your code?
Whatever the case with that, leave this issue open. I'm not 100% happy with the clarity on the lack of availability of page/view TH in components. I'd like to take a look at this for some enhancements where we discuss the use of components in RP/MVC projects.
[EDIT by guardrex to apply text/code formatting]
Hello guardrex, yeah, in fact I was using the workaround as you have suggested, but do let me describe a little of my use case by using the aforementioned workaround. Prior to that, let me show you my simplified project structure.
- OrdersOverview
- Pages
- _ViewImports.cshtml
- _ViewStart.cshtml
- Index.cshtml
- Order.cshtml
- Components
- _Imports.razor
- ContentWithBreadCrumb.cs
- ContentWithBreadCrumbComponent.cs (inherits ComponentBase)
- Pages
- Shared
- _Layout.cshtml
- ValidationScriptsPartial.cshtml
- Index.cshtml
- Omitted for clarity..
The Order.cshtml is the view that will calls and renders the ContentWithBreadCrumb.cs Razor component. Since I am at the Order.cshtml, the URL is http://mysite.com/orders-overview/order, to build the breadcrumb link, the code in Order.cshtml generates the @PageName, but I have to handle the relative path manually, such as to navigate the folder up one level such as to assign @PageName equals to "../orders-overview/order". I was hoping that the tag helper could help me to handle relative path generation automatically without any hassle. As pointed out by you, so now I know that the way how Razor works is different, at least this is by design, I hope I don't get you wrong.
I am new to Razor, and I have invested about a month time to learn web technology and I have decided to go for Razor because I would like to get away from JavaScript esp. there are too many different libraries, framework, you know, npm, babel, ES script or what, Typed Script, Lint what, webpack, bla bla bla, and many more, making the productivity very slow, I believe Razor is the future.
I am not sure if I describe my use case comprehensive enough (I am no native English speaking person), if you would like to know more details, I can create a sample project to show my use case. If the use case make sense, maybe you can point me to an alternative solution before the permanent solution arrives, but I am quite happy with the current workaround already.
Try the Navigation Manager ... https://docs.microsoft.com/en-us/aspnet/core/blazor/routing?view=aspnetcore-3.1#uri-and-navigation-state-helpers ... in the ContentWithBreadCrumb component to build the breadcrumb link for PageName. See what NavigationManager.Uri holds (or use BaseUri with ToBaseRelativePath).
Ran a test with Navigation Manager. It worked ...
@inject NavigationManager NavigationManager
Uri: @NavigationManager.Uri
... in a component embedded into a Razor Pages page (/Nested/TestPage.cshtml). It produced in the component ...
Uri: https://localhost:44375/Nested/TestPage
Use the value in NavigationManager.Uri to construct your breadcrumb links.
ToRelativeBasePath doesn't work with BaseUri. I tried this in the component ...
<p>
ToBaseRelativePath 1: @(NavigationManager.ToBaseRelativePath(NavigationManager.BaseUri))
</p>
<p>
ToBaseRelativePath 2: @(NavigationManager.ToBaseRelativePath(NavigationManager.Uri))
</p>
... nothing on the first one, but the second one worked well ...
ToBaseRelativePath 1:
ToBaseRelativePath 2: Nested/TestPage
... so use Uri if you want a pure relative path.
@guardrex, thanks! I didn't know that there is a cool navigation helper, it works!
Using your example, I change a bit to meet what I want, in the Nested/TestPage, I return a list of class instance representing the Razor pages page link infos:
// Wrapped inside a Param class that is decorated with [Parameter]
public List<BreadcrumbItem> GetBreadcrumbItems()
{
return new List<BreadcrumbItem>()
{
new BreadcrumbItem()
{
Caption = "Nested",
PageName = "Nested"
},
new BreadcrumbItem()
{
Caption = "TestPage",
PageName = "Nested/TestPage"
}
}
}
Since I want my breadcrumb items to be like this:
Nested > TestPage
and Inside the Razor component, I build each breadcrumb link with the code as shown in code snippet below:
@for (int i = 0; i < Param.GetBreadcrumbItems(); i++)
{
var item = Param.GetBreadcrumbItems()[i];
if (i < Param.GetBreadCrumbItems().Count - 1)
{
<a href="@NavigationManager.ToAbsoluteUri(item.PageName)">item.Caption</a>
<span> > </span>
}
else
{
<span>item.Caption</span>
}
}
Thanks again for the assistant, really appreciate the support.
Cool ... I'm glad it had a happy ending. :beers:
Let's leave this issue open ... I'd like to address the concept that page/view TH aren't for use in components and tell readers what they should do: build a component that encapsulates their TH logic/functionality and use that instead of a TH.
Yes, please leave this issue open, may be there will be one who will ask the same question again because it is kind of intuitive to relate the component to the page/view with both having markup syntax therein
All in all, it is a great experience encapsulating stuff in components, it is truly enjoying, cheers!
Most helpful comment
@guardrex, thanks! I didn't know that there is a cool navigation helper, it works!
Using your example, I change a bit to meet what I want, in the
Nested/TestPage, I return a list of class instance representing the Razor pages page link infos:Since I want my breadcrumb items to be like this:
Nested > TestPage
and Inside the Razor component, I build each breadcrumb link with the code as shown in code snippet below:
Thanks again for the assistant, really appreciate the support.