Aspnetcore: Html meta tags, page title

Created on 16 May 2018  Â·  19Comments  Â·  Source: dotnet/aspnetcore

Hello people

You guys are doing a wonderful job with Blazor :-)

I have a question regarding Html meta tags. The app itself will be placed in the app element on the page. But how about stuff in the header? Like meta tags and so on.
Let say I would like to change/update meta tag data depending on what page (in the app). Or just update the page title.
How to do this? By Javascript interop?

area-blazor

Most helpful comment

JS Interop? What? No!

You don't even need anything sophisticated to do this.
This is terrible code made one late night in 0.9 but it should give you an idea on how to do this; you can probably do this more way efficiently.

Basically, create an html component, a body component, and a head component; render the html component in Index.cshtml; put a reference to the Head Component inside a Metatag Container; set the reference to "this" from the Head component upon init, and also pass this container into the Body component and whatever is inside of the body.

From there you can update the Head component from within the body, which will update the SEO tags as expected as long as you invoke StateHasChanged on the Head blazor component. This works with pre-rendering, allowing you to be appropriately crawled.

Here's what my Index.cshtml looks like

@page "{*clientPath}"
@using dao.Server
<!DOCTYPE html>
<html>

@(await Html.RenderComponentAsync<html>())

</html>

Then I have two classes called "html" and "metatags".
The html class creates the html tags, and I just store the the header (script tags, etc) inside of a html file that I inject as markup.

    public class html : ComponentBase
    {
        public static string HeadTXT = File.ReadAllText("head.htm");
        Metatags meta = new Metatags() { Title = "some title" };
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
        {

            builder.OpenElement(0, "head");
            builder.AddMarkupContent(1, HeadTXT);
            builder.OpenComponent<Head>(2);
            builder.AddAttribute(3, "MetaInfo", meta);
            builder.CloseComponent();
            builder.CloseElement();

            builder.OpenElement(4, "body");
            builder.OpenComponent<Body>(5);
            builder.AddAttribute(6, "MetaInfo", meta);
            builder.CloseComponent();
            builder.AddMarkupContent(7, "<script src=\"_framework/components.server.js\"></script>");
            builder.CloseElement();

        }
    }

    public class Metatags
    {
        public string Title { get; set; } = "example.nyc — weirdest hack ever";
        public string Description { get; set; } = "testing";
        public Head Component;
    }

A "body" Component.

<DetectPrerender MetaInfo="@MetaInfo">
    <Router AppAssembly="typeof(Startup).Assembly" />
</DetectPrerender>


@functions {

    [Parameter]
    private Metatags MetaInfo { get; set; }

}

And a "head" component.

@using example.Shared

<title>@MetaInfo.Title</title>
<meta name="description" content="@MetaInfo.Description">
@{
    MetaInfo.Component = this;
}
@functions {

    [Parameter]
    private Metatags MetaInfo { get; set; }
    private bool ShouldRend = false;
    protected override bool ShouldRender()
    {
        if (ShouldRend)
        {
            ShouldRend = false;
            return true;
        }
        return false;
    }

    public void ShouldRe()
    {
        ShouldRend = true;
        base.Invoke(() => base.StateHasChanged());
    }

}

All 19 comments

Good question. I was thinking about this problem in my own application and so far I have no solution. Think about server side rendering in the future. Correct meta tags are essential for SEO, for integration with Facebook/Twitter, etc.

I hope that we will be able to create multilingual Blazor applications in the future. To do it correctly we have to handle lang attribute in html element.

We have to be able to modify main index.html file from Blazor application and selected solution have to be compatible with server side rendering.

Yes exactly. My vision/hope is that Blazor will be "the new way" of doing web pages. Like replacing the "old way" of doing server-rendered pages. If we(you) could find a way how to handle stuff outside the app element, like Meta tags, title etc. Then the game is afoot :-)

I have found yet another example why we need a way to modify HTML page elements outside of our Blazor application tag. We can have an application with multiple pages and someone can add a link to Favourites in the web browser. Link should have proper title - otherwise links to different pages are indistinguishable.

For most nontrivial Blazor apps, you'll want some notion of a data store that issues notifications when its state changes. There's an example of this in the FlightFinder sample: https://github.com/aspnet/samples/tree/master/samples/aspnetcore/blazor/FlightFinder

With this kind of architecture, you can have "page title" as one of the data items tracked in the store, and can subscribe to that in your layout to change the <title> element's contents whenever that changes.

@SteveSandersonMS How do you change the content of the element located in <head> in index.html? Using JS-Interop (document / page.title, I suppose?)</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars0.githubusercontent.com/u/3329952?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="DNF-SaS picture"> <strong>DNF-SaS</strong> <span class="text-muted ml-1">on 22 May 2018</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="mb-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3731713875" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>@DNF-SaS Yes</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/1101362?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="SteveSandersonMS picture"> <strong>SteveSandersonMS</strong> <span class="text-muted ml-1">on 22 May 2018</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p><strong>@SteveSandersonMS</strong> Thank you for suggestion. Of course we can use data store and modify what we want in JavaScript (title, metatags, etc.). But in the future we will have server side rendering. It would be nice to find a solution which will work on the client and on the server.</p> <p>In ordinary ASP.NET Core application I have a base ViewModel for all my pages. I use this base class in _Layout.cshtml like this:</p> <pre><code class="prettyprint"><strong>@model</strong> ViewModelBase <!DOCTYPE html> <html lang="@Model.Language" prefix="og: http://ogp.me/ns#"> <head> <title>@Model.Title</title> <strong>@if</strong> (!string.IsNullOrEmpty(Model.OgVideo)) { <meta property="og:video" content="@Model.OgVideo" /> } </code></pre> <p>As you can see I assume that some model properties (Language, Title) are always available and I render them unconditionally. On the other hand not every page has video which can be shared on social sites and og:video metatag is rendered conditionally. It would be nice to have similar experience on the client. Maybe it is possible to add some event to the router (for example OnHeadRender). In that event we should be able to render at least the opening <code><html></code> tag and <code><head></head></code>. This event probably should be executed after OnParametersSet - page component should have a chance to set some state in global data store (similar in concept to my base ViewModel in ASP.NET Core application).</p> <p>I understand that it is not a high priority task at this stage of Blazor development, but I think it should be tracked somewhere.</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/32604409?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="Andrzej-W picture"> <strong>Andrzej-W</strong> <span class="text-muted ml-1">on 22 May 2018</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">3</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>If would be great if you had a namespace (or helpers) to manage header's metadata (such as title, meta keywords), and also a set of helpers to manage Cookies, and also a wrapper to the windows javascript namepace ! </p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/3438864?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="raphadesa picture"> <strong>raphadesa</strong> <span class="text-muted ml-1">on 25 Jun 2018</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">2</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>@Andrew-MSFT SAP always face the issue meta tags and title with the SEO :( haiz.. so.. Blazor has nothing diff about that, right?</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/15808788?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="topnguyen picture"> <strong>topnguyen</strong> <span class="text-muted ml-1">on 3 Sep 2018</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p><strong>@topnguyen</strong> Correct, the story is pretty much the same.</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars2.githubusercontent.com/u/1874516?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="danroth27 picture"> <strong>danroth27</strong> <span class="text-muted ml-1">on 4 Sep 2018</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="mb-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3731713875" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>I have similar problem for seo purposes,<br /> I need to be able to modifiy title and description tags for every "page"</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/11575166?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="evrenunal picture"> <strong>evrenunal</strong> <span class="text-muted ml-1">on 4 Jan 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">1</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>I used a bunch of ugly JS-Interop and pre-rendering pages as static HTML to get crawlers working around; but it's definitely not ideal. </p> <p>It would be really great to see a "MetaHelper" built into Blazor akin to UriHelper where I can just call <code>MetaHelper.Links["en"].href = "XYZ";</code> or <code>MetaHelper.Title = "XYZ";</code></p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/16845709?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="honkmother picture"> <strong>honkmother</strong> <span class="text-muted ml-1">on 16 Feb 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">2</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>Is there an official recommended way to solve this yet?<br /> The only way possible right now seems to build the whole site with .cshtml + .razor pairs, for example:</p> <p>Home.cshtml (which renders the home component)<br /> Home.Razor<br /> Products.cshtml (which renders the products component)<br /> Products.razor<br /> etc...etc...</p> <p>This way you create a hybrid approach, in which everything in the page is interactive (without postbacks), except links to other pages which would trigger the browser redirect to another .cshtml razor page, each one with its custom head tags.</p> <p>Is there a known better solution?</p> <p>Also even this solution doesn't work since <code><a href="etc"></code> link tags seem to be catched by the framework blocking the browser to properly redirect.<br /> (issue which is being tracked here https://github.com/aspnet/AspNetCore/issues/9834 )</p> <p>Regards!</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars1.githubusercontent.com/u/20750172?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="chrdlx picture"> <strong>chrdlx</strong> <span class="text-muted ml-1">on 8 May 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">1</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>Currently the simplest and cleanest solution is to use JS interop to modify the document state.</p> <p>We are planning to improve this, though we don't have a final design or ETA yet.</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/1101362?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="SteveSandersonMS picture"> <strong>SteveSandersonMS</strong> <span class="text-muted ml-1">on 8 May 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">1</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>JS Interop? What? No! </p> <p>You don't even need anything sophisticated to do this.<br /> This is terrible code made one late night in 0.9 but it should give you an idea on how to do this; you can probably do this more way efficiently.</p> <p>Basically, create an html component, a body component, and a head component; render the html component in Index.cshtml; put a reference to the Head Component inside a Metatag Container; set the reference to "this" from the Head component upon init, and also pass this container into the Body component and whatever is inside of the body. </p> <p>From there you can update the Head component from within the body, which will update the SEO tags as expected as long as you invoke StateHasChanged on the Head blazor component. This works with pre-rendering, allowing you to be appropriately crawled.</p> <p>Here's what my <strong>Index.cshtml</strong> looks like</p> <pre><code class="prettyprint"><strong>@page</strong> "{*clientPath}" <strong>@using</strong> dao.Server <!DOCTYPE html> <html> @(await Html.RenderComponentAsync<html>()) </html> </code></pre> <p>Then I have two classes called "html" and "metatags".<br /> The html class creates the html tags, and I just store the the header (script tags, etc) inside of a html file that I inject as markup.</p> <pre><code class="prettyprint"> public class html : ComponentBase { public static string HeadTXT = File.ReadAllText("head.htm"); Metatags meta = new Metatags() { Title = "some title" }; protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder) { builder.OpenElement(0, "head"); builder.AddMarkupContent(1, HeadTXT); builder.OpenComponent<Head>(2); builder.AddAttribute(3, "MetaInfo", meta); builder.CloseComponent(); builder.CloseElement(); builder.OpenElement(4, "body"); builder.OpenComponent<Body>(5); builder.AddAttribute(6, "MetaInfo", meta); builder.CloseComponent(); builder.AddMarkupContent(7, "<script src=\"_framework/components.server.js\"></script>"); builder.CloseElement(); } } public class Metatags { public string Title { get; set; } = "example.nyc — weirdest hack ever"; public string Description { get; set; } = "testing"; public Head Component; } </code></pre> <p>A "body" Component.</p> <pre><code class="prettyprint"><DetectPrerender MetaInfo="@MetaInfo"> <Router AppAssembly="typeof(Startup).Assembly" /> </DetectPrerender> <strong>@functions</strong> { [Parameter] private Metatags MetaInfo { get; set; } } </code></pre> <p>And a "head" component.</p> <pre><code class="prettyprint"><strong>@using</strong> example.Shared <title>@MetaInfo.Title</title> <meta name="description" content="@MetaInfo.Description"> @{ MetaInfo.Component = this; } <strong>@functions</strong> { [Parameter] private Metatags MetaInfo { get; set; } private bool ShouldRend = false; protected override bool ShouldRender() { if (ShouldRend) { ShouldRend = false; return true; } return false; } public void ShouldRe() { ShouldRend = true; base.Invoke(() => base.StateHasChanged()); } } </code></pre> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/16845709?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="honkmother picture"> <strong>honkmother</strong> <span class="text-muted ml-1">on 9 May 2019</span> </div> <div class="col text-right"> 👍<span class="ml-2 mr-3">5</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>That's a nice way to do it where Blazor has full control over most of the document, but it could pose a mild load time issue in certain cases and still requires interop implicitly.</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars1.githubusercontent.com/u/16641853?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="TheFanatr picture"> <strong>TheFanatr</strong> <span class="text-muted ml-1">on 9 May 2019</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p><strong>@honkmother</strong> does this work for client side blazor or only server side. And if it does work for client side blazor, can you provide a git repo showing your configuration?</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars0.githubusercontent.com/u/33181301?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="smartprogrammer93 picture"> <strong>smartprogrammer93</strong> <span class="text-muted ml-1">on 9 May 2019</span> </div> <div class="col text-right"> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p>@TheFanatr</p> <p>Yes it requires some minimal interop between the components; but doesn't need any Javascript. </p> <p>I think this is close to as good as we can get in terms of patterns that already exists within Blazor. I wouldn't mind seeing default HTML, Body, and Head component classes with Dictionary structures, and having those references passed down a cascade or something.</p> <p>re: load time: not as far as I can tell.</p> <p>@smartprogrammer93<br /> It should work for both, but I would have to double check because for all I know <app>...</app> could be a hard coded hook into the DOM; but I am almost certain if you rename App.razor to Html.razor, it will allow you to use the HTML element instead. <br /> Client side might be a little different because you need the script tag in the document for Blazor to even boot up (where as serverside renders the components for you). I am 99% certain you can just throw the script tag inside of the loading placeholder.</p> <p>After I'm done working today I will set up a repo with an example that works with preview4/5 for both the client and server. </p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/16845709?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="honkmother picture"> <strong>honkmother</strong> <span class="text-muted ml-1">on 9 May 2019</span> </div> <div class="col text-right"> 🎉<span class="ml-2 mr-3">2</span> </div> </div> </div> </div> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown"> <p><strong>@honkmother</strong> I really like the sample code you provided, and i've tried to make attempts at replicating it based on instructions you've provided. I cant tell if preview version i'm using is an issue, or if i'm not following your steps properly. Is it possible for you to offer some more clarity to the sample you've given? Maybe a direct link to download base/template files that i may eventually modify and build on. I'm not sure what your using tag points to on <code>index.cshtml</code>; or if if the code only works for server side or client side... if i'm to use both <code>.razor</code> and <code>.cs</code> files... why i get errors on <code>_generated_component_.Head</code> does not equal inherited <code>(Head)this</code>... if i explicitly reference <code>Head</code> component as an inheritance of ComponentBase, then the other half of code in element builder on html file doesnt work, because <code>ComponentBase.Head</code> is not equal to <code>Head.razor</code> component.</p> <p>I'm sorry, i just have so much confusion and there's just not enough information and resources available for blazor to properly make sense of anything. Users are writing articles on blazor, but no one is really saying where they get their data from. So their articles don't really touch on any of the concerns i share or look forward to learning more about. I didnt even realize you can only edit the html code for layout only once in <code>index.html</code> till i googled <code>Html.RenderComponentAsync</code> which leads me back to <a rel="nofollow noopener" target="_blank" href="https://github.com/aspnet/Blazor/issues/552">Warnings on <script> in razor components</a> being a thing i found out only recently. I'm dying to create really amazing projects, but i'm so confused that everything looks exactly the same because i cant even modify the layouts dynamically, much less change silly meta-tags for seo and page title. Two weeks of youtube, blogs, articles, github, and 10 visual studio projects later... i find out that you have to edit the <code>wwwroot/index.html</code> to insert your own css/js. //end rant. </p> <p>I just need a little bit of direction, if you could offer any that'll help clear a bit of the fog (smoke and mirrors)</p> </div> <div class="card-footer"> <div class="row"> <div class="col"> <img src="https://avatars3.githubusercontent.com/u/15901670?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="herbertmilhomme picture"> <strong>herbertmilhomme</strong> <span class="text-muted ml-1">on 12 Sep 2019</span> </div> <div class="col text-right"> </div> </div> </div> </div> </div> <div class="col-12"> <div class="card card-custom mb-4"> <div class="card-body pt-3 pb-3 markdown text-center helpful"> <div class="title">Was this page helpful?</div> <div class="mt-1" onMouseLeave="rating(512931254, 0);"> <i class="fas fa-star inactive" id="star-1" onMouseOver="rating(512931254, 1);" onclick="rate(512931254, 1);"></i> <i class="fas fa-star inactive" id="star-2" onMouseOver="rating(512931254, 2);" onclick="rate(512931254, 2);"></i> <i class="fas fa-star inactive" id="star-3" onMouseOver="rating(512931254, 3);" onclick="rate(512931254, 3);"></i> <i class="fas fa-star inactive" id="star-4" onMouseOver="rating(512931254, 4);" onclick="rate(512931254, 4);"></i> <i class="fas fa-star inactive" id="star-5" onMouseOver="rating(512931254, 5);" onclick="rate(512931254, 5);"></i> </div> <div class="description text-small"><span id="rating-val">0</span> / 5 - <span id="rating-count">0</span> ratings</div> </div> </div> <div class="mb-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3452512275" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> </div> <div class="col-12 col-lg-4"> <div id="ph-above-related"></div> <div class="card card-custom issue-box"> <div class="card-body pt-3 pb-5"> <h2 class="mb-4">Related issues</h2> <div> <strong> <a href="/aspnetcore/372130270/cors-allowanyheader-issue-with-firefox">CORS AllowAnyHeader issue with Firefox</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars3.githubusercontent.com/u/234581?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="rbanks54 picture"> <strong class="pr-1" dir="ltr">rbanks54</strong>  Â·  <span class="px-1" dir="ltr">3</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/aspnetcore/199963656/ivalidatableobject-validate-only-called-if-attribute-defined">IValidatableObject.Validate Only Called If Attribute-Defined Validation Rules Pass?</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars0.githubusercontent.com/u/857202?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="bgribaudo picture"> <strong class="pr-1" dir="ltr">bgribaudo</strong>  Â·  <span class="px-1" dir="ltr">3</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/aspnetcore/392783596/please-consider-splitting-the-azuread-package-apart-to">Please consider splitting the AzureAD package apart to reduce dependencies</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars1.githubusercontent.com/u/1396388?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="mj1856 picture"> <strong class="pr-1" dir="ltr">mj1856</strong>  Â·  <span class="px-1" dir="ltr">3</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/aspnetcore/390904494/support-multiple-fromroute-fromheader-frombody-etc-in-a">Support multiple [FromRoute], [FromHeader], [FromBody], etc in a single object</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars0.githubusercontent.com/u/1266245?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="snebjorn picture"> <strong class="pr-1" dir="ltr">snebjorn</strong>  Â·  <span class="px-1" dir="ltr">3</span><span>Comments</span> </div> <hr /> <div> <strong> <a href="/aspnetcore/251436972/deploy-using-kestrel-server-only-instead-of-iis-on-windows">Deploy using KESTREL server only instead of IIS on Windows.</a> </strong> </div> <div class="text-muted text-small mt-2"> <img src="https://avatars3.githubusercontent.com/u/262147?v=4&s=40" style="width:20px; height:20px;" class="mr-2 rounded float-left" alt="githubgitgit picture"> <strong class="pr-1" dir="ltr">githubgitgit</strong>  Â·  <span class="px-1" dir="ltr">3</span><span>Comments</span> </div> </div> </div> <div class="sticky-top pt-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3919948963" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div id="ph-below-related-2" class="mt-4"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="3919948963" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> <div class="col-12 col-lg-4"> </div> </div> <div class="skyscraper-container"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-3835332123789605" data-ad-slot="7879185320" data-ad-format="vertical" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> <div class="mt-5 spacer"></div> <footer class="mt-5 pb-2 py-4 text-center mt-auto"> <div class="container"> <a class="navbar-brand logo mr-5" href="/"> <img src="/assets/img/logo.svg" width="40" height="40" alt="bleepingcoder logo"> bleeping<strong>coder</strong> </a> <div class="mt-4"> bleepingcoder.com uses publicly licensed GitHub information to provide developers around the world with solutions to their problems. We are not affiliated with GitHub, Inc. or with any developers who use GitHub for their projects. We do not host any of the videos or images on our servers. All rights belong to their respective owners. </div> <div> Source for this page: <a href="https://www.github.com/dotnet/aspnetcore/issues/16018" rel="nofollow noreferrer" target="_blank">Source</a> </div> </div> <hr class="mb-5 mt-5"> <div class="container"> <div class="row"> <div class="col-sm-4 col-lg mb-sm-0 mb-5"> <strong>Popular programming languages</strong> <ul class="list-unstyled mb-0 mt-2"> <li class="mb-2"> <a href="/python" dir="ltr">Python</a> </li> <li class="mb-2"> <a href="/javascript" dir="ltr">JavaScript</a> </li> <li class="mb-2"> <a href="/typescript" dir="ltr">TypeScript</a> </li> <li class="mb-2"> <a href="/cpp" dir="ltr">C++</a> </li> <li class="mb-2"> <a href="/csharp" dir="ltr">C#</a> </li> </ul> </div> <div class="col-sm-4 col-lg mb-sm-0 mb-5"> <strong>Popular GitHub projects</strong> <ul class="list-unstyled mb-0 mt-2"> <li class="mb-2"> <a href="/microsoft/vscode" dir="ltr">vscode</a> </li> <li class="mb-2"> <a href="/numpy/numpy" dir="ltr">numpy</a> </li> <li class="mb-2"> <a href="/ant-design/ant-design" dir="ltr">ant-design</a> </li> <li class="mb-2"> <a href="/mui-org/material-ui" dir="ltr">material-ui</a> </li> <li class="mb-2"> <a href="/vercel/next-js" dir="ltr">next.js</a> </li> </ul> </div> <div class="col-sm-4 col-lg mb-0"> <strong>More GitHub projects</strong> <ul class="list-unstyled mb-0 mt-2"> <li class="mb-2"> <a href="/rust-lang/rust" dir="ltr">rust</a> </li> <li class="mb-2"> <a href="/moment/moment" dir="ltr">moment</a> </li> <li class="mb-2"> <a href="/yarnpkg/yarn" dir="ltr">yarn</a> </li> <li class="mb-2"> <a href="/mozilla/pdf-js" dir="ltr">pdf.js</a> </li> <li class="mb-2"> <a href="/JuliaLang/julia" dir="ltr">julia</a> </li> </ul> </div> </div> </div> <hr class="mb-5 mt-5"> <div class="container text-muted"> © 2024 bleepingcoder.com - <a href="/bleeps" rel="nofollow">Contact</a><br /> By using our site, you acknowledge that you have read and understand our <a href="/cookies" rel="nofollow">Cookie Policy</a> and <a href="/privacy" rel="nofollow">Privacy Policy</a>. </div> </footer> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script> <script async src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> <!--<script defer type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5fb2db66acbd74b2"></script>--> <script type="text/javascript" src="/assets/js/main.js"></script> <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script></body> </html>