Because you're using
@Model.UserName. In your HTML you're using model binding. When the HTML is sent to the browser any @ expressions are replaced with their current value. So when the HTML goes to the browser
@Model.UserName is most likely empty, unless you're setting it on the server side somehow. Hence the route parameter will be an empty string.
You are wanting to get the user name that the user typed in on the client side. Until the data is posted back to the server via a submit button then this is all client side and
Model won't help you as it is server side only.
What you'll need to do is write some JS to fetch the current value of the input control. When the user clicks the link, call your JS function that gets the user name from the input. Then you'll need to append that to the URL yourself as part of the query string. You cannot use the ASP.NET Core attributes on the client side code. If you look at the HTML actually sent to the browser you'll see that the various
asp- attributes you are using are being translated on the server side first. Hence the client side code cannot use them. You'll have to do traditional client side coding.
Note that if you're using a client side library like Knockout, Angular or Vue then this problem can be easily solved using a client side binding instead. However that is beyond the scope of this post and not even relevant if you're just using ASP.NET Core.