skip to Main Content

This Blazor code works as expected:
Working code

However, if I insert anything inside the <Link> tag, I get errors: 
non-working code

The error messages I get are false:
Bad error message

Any idea what’s going on? By the way, that isn’t just a Visual Studio bug; the code also doesn’t build.

Edit

For those who can’t access the images, here’s the code in question. Delete the "DELETE ME" to make the code work.

@foreach(var Child in Children)
{
    <OrderedListItem>
         <ListGroup>
            <ListGroupItem>Name: <Link To=@($"/ide/hr_child_summary/{Child["Id"]}")>DELETE ME</Link></ListGroupItem>
            <ListGroupItem>SharePoint file prefix: @Child["SharePointFilePrefix"]</ListGroupItem>
            <ListGroupItem>Dependent? @Child["Dependent"]</ListGroupItem>
        </ListGroup>
    </OrderedListItem>
}

EDIT 2:

I’ve worked around the issue by using an a tag rather than a Link. Here’s the entire component in the form that works. To reproduce the issue, change the <a href=...> to <Link To=...>. Also, in reply to comments, <Link> comes from Blazorise; I didn’t write it.

<Card> 
    <CardTitle>Relations Summary</CardTitle>
    <CardText>
        
        <ListGroup>

            <ListGroupItem>
                
                <CardSubtitle>Spouse Info</CardSubtitle>
                <ListGroup>
                    
                    <ListGroupItem>Name: <Link To=@($"/ISE/r_IDE_Summary/{IseInfo["SpouseMissionaryId"]}")>@IseInfo["SpouseName"]</Link></ListGroupItem>
                    <ListGroupItem>Employee ID: @IseInfo["SpouseEmpId"]</ListGroupItem>
                    <ListGroupItem>GL Employee ID: @IseInfo["SpouseGlEmpId"]</ListGroupItem>
                    <ListGroupItem>SharePoint file prefix: @IseInfo["SpouseSharePointFilePrefix"]</ListGroupItem>
                </ListGroup>
            </ListGroupItem>
            
            @if(Children?.Count > 0)
            {
                <ListGroupItem>
                    <CardSubtitle>Children</CardSubtitle>
                        <OrderedList>
                        
                        @foreach(var Child in Children)
                        {
                            <OrderedListItem>
                                <ListGroup>
                                    <ListGroupItem>Name: <a href="@($"/ide/hr_child_summary/{Child["Id"]}")">@Child["Name"]</a></ListGroupItem>
                                    <ListGroupItem>SharePoint file prefix: @Child["SharePointFilePrefix"]</ListGroupItem>
                                    <ListGroupItem>Dependent? @Child["Dependent"]</ListGroupItem>
                                </ListGroup>
                            </OrderedListItem>
                        }
                    </OrderedList>
                </ListGroupItem>
            }
        </ListGroup>
    </CardText>
</Card>

@code
{
    [Parameter]
    public Dictionary<string, string> IseInfo { get; set; }

    [Parameter]
    public List<Dictionary<string, string>> Children { get; set; }
}

3

Answers


  1. Totally Revised Answer

    I’ve gone through the Blazorize source code and can’t see why there’s a problem, but there is!

    The problem is that something in Link is throwing the Razor compiler so it’s not compiling the C# file from the Razor file.

    You can bypass the problem by coding the RenderTreeBuilder code directly as I’ve done below.

    Not what you want, but…

    @page "/"
    
    @foreach (var child in _children)
    {
        <ListGroup>
            @GetListItem(child)
        </ListGroup>
    }
    
    @code {
        private RenderFragment<KeyValuePair<string, string>> GetListItem => (item) => (builder) =>
        {
            builder.OpenComponent<ListGroupItem>(0);
            builder.AddAttribute(5, "ChildContent", this.GetChildContent1(item));
            builder.CloseComponent();
        };
    
        private RenderFragment<KeyValuePair<string, string>> GetChildContent1 => (item) => (builder) =>
        {
            builder.AddContent(0, "Name :");
            builder.OpenComponent<Link>(3);
            builder.AddAttribute(4, "To", item.Value);
            builder.AddAttribute(5, "ChildContent", this.GetChildContent(item));
            builder.CloseComponent();
        };
    
        private RenderFragment<KeyValuePair<string, string>> GetChildContent => (item) => (builder) =>
        {
            builder.AddContent(0, item.Key);
        };
    
        private Dictionary<string, string> _children = new Dictionary<string, string>() {
            {"Index", "/Counter" },
            {"Counter", "/Counter" },
            {"Fetch Data", "/FetchData" },
        };
    }
    
    Login or Signup to reply.
  2. If you are using Blazor and have found that adding anything inside a <Link> tag breaks the surrounding code, it is likely because the <Link> tag is an HTML tag and not a Blazor component. Blazor components are defined using Razor syntax, which is a mix of HTML and C# code.
    To use a link in Blazor, you should use the <NavLink> component instead. This component is specifically designed for creating links in Blazor applications and works seamlessly with the surrounding code.
    For example, instead of using:html

    <a href="/dashboard">Go to dashboard</a>
    You would use:html
    <NavLink href="/dashboard">Go to dashboard </NavLink>
    

    This will create a link that behaves like a normal link but is also fully compatible with Blazor.

    Login or Signup to reply.
  3. This is a known bug that is clearly mentioned in Blazorise documentation:

    Note: due to a bug in
    VisualStudio tooling you should write <Link> as <Blazorise.Link>
    until the issue is resolved. Or if you prefer the alternative, you can
    also use the <Anchor> alias.

    Are you sure you tried Blazorise.Link because in my tests it fixes the issue:

    @foreach (var Child in _children)
    {
        <ListGroup>
            <ListGroupItem>Name: <Blazorise.Link To=@($"/ide/hr_child_summary/{Child["Id"]}")>DELETE ME</Blazorise.Link></ListGroupItem>
        </ListGroup>
    }
    
    @code {
        [Parameter]
        public List<Dictionary<string, string>> Children { get; set; }
    }
    

    The code above compiles and runs without any errors. Anchor alias works as well.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search