ASP.NET Core

ASP.NET Core

ASP.NET Core is a cross-platform, high-performance, open-source framework for building modern, cloud-enabled, internet-connected apps.

...see more

The sitemap.xml file must be encoded with UTF-8. Example of sitemap:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.example.com/</loc>
      <lastmod>2005-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
   <!-- ... -->
</urlset>

As you can see, each URL in a sitemap contains four pieces of metadata:

  • urlset - Sitemap start and ending tag. Sitemap document start with <urlset> and ends with </urlset>
  • URL - parent tag for each URL entry
  • loc - URL of our site.
  • lastmod (Optional) - A last modified timestamp. This tells search engines whether or not they should re-index the page to reflect any changes that have been made.
  • changefreq (Optional) - A change frequency indicator (This can take the values: always, hourly, daily, weekly, monthly, yearly, never). This gives search engines an indication of how often they should come back and re-index the page.
  • priority (Optional) - A number from zero to one indicating the page's importance compared to other pages on the site.

The last three values only give search engines an indication of when they can or should index or even re-index a page. It is not a guarantee that it will happen, although it makes it more likely.

...see more

sitemap is a standalone page. On the razor page model, the ApplicationDbcontext is injected to work with the database.

Below code will generate XML string and return as ContentResult having ContentType = "application/xml"

Our page model code looks like as written below:

namespace Sample.Pages
{
  public class SitemapModel : PageModel
  {
    public readonly ApplicationDbContext dbContext;

    public SitemapModel(ApplicationDbContext dbContext)
    {
      this.dbContext = dbContext;
    }

    public IActionResult OnGet()
    {
      var pages = dbContext.Pages.ToList();
      StringBuilder sb = new StringBuilder();
      sb.Append("<?xml version='1.0' encoding='UTF-8' ?><urlset xmlns = 'http://www.sitemaps.org/schemas/sitemap/0.9'>");

      foreach (var page in pages)
      {
        string mDate = page.ModifiedDate.ToString("yyyy-MM-ddTHH:mm:sszzz");
        var url = $"https://www.snippset.com/{page.Title}";
        sb.Append("<url><loc>" + url + "</loc><lastmod>" + mDate + "</lastmod><changefreq>{page.Frequency}</changefreq><priority>{page.Priority}</priority></url>");
      }

      sb.Append("</urlset>");

      return new ContentResult
      {
        ContentType = "application/xml",
        Content = sb.ToString(),
        StatusCode = 200
      };
    }
  }
}
...see more

ASP.NET Core provides the option to set a friendly URL. So instead of just sitemap, it can be set to sitemap.xml.

By using AddPageRoute the route to a page can be configured with a friendly URL.

options.Conventions.AddPageRoute("/Sitemap", "Sitemap.xml");
...see more

This snipp explains how to configure Response Caching Middleware in an ASP.NET Core app.


Add Response Caching Middleware

In Startup.ConfigureServices, add the Response Caching Middleware to the service collection using services.AddResponseCaching():

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCaching();
    services.AddRazorPages(options =>
    ...
}

Configure Response Cache

Configure the app to use the middleware with the UseResponseCaching extension method, which adds the middleware to the request processing pipeline in Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  ...
  app.UseResponseCaching();
  app.UseEndpoints(endpoints =>
  ...
}

Set ResponseCache attribute

In a controller action, add the [ResponseCache] attribute. The response cache middleware only works if the response cache attribute is added to the action method or controller.

[ResponseCache(Duration = 300)]
public class ImagesController : Controller
{
  ...

The following is a Response Header. It shows the cache-control:public and max-age=300

Response Header 

cache-control: public,max-age=300
status: 200
...
x-powered-by: ASP.NET


...see more

Inject Configuration

To inject configuration settings in your ASP.NET Core application, use Microsoft.Extensions.Configuration and inject IConfiguration into your page or component. Access configuration values using Configuration["KeyName"].

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<!-- Access configuration value -->
@Configuration["ApplicationInsights:InstrumentationKey"]

Options Pattern

For more structured configuration management, use the options pattern with Microsoft.Extensions.Options. Inject IOptionsMonitor<TOptions> with @inject and access configuration values through OptionsAccessor.Value.PropertyName.

@using Microsoft.Extensions.Options
@inject IOptionsMonitor<ApplicationInsightsOptions> ApplicationInsightsOptionsAccessor

<!-- Access configuration value -->
var instrumentationKey = ApplicationInsightsOptionsAccessor.Value.InstrumentationKey;

For detailed information, refer to the ASP.NET Core documentation on configuration options.

...see more

The contents of a code block ({ ... }) are expected to be code, not markup.

If you want to put text directly in a code block, you have three choices:

  • Wrap it in any HTML tag
  • Wrap it in the special Razor <text> tag, which will just render the text without the tag
  • Prepend the line with @:, which is equivalent

Use the <text> tags

The <text> tag signals to the razor view engine to write the contents to the output.

@{ var foo = true; }
@if(foo) { <text>Yes</text> } else { <text>No</text> }

Use @:

Prefix the text with @: before the first instance of text in the line. The parser is interpreting everything following @:Yes... to be text.

@{ var foo = true;
    if (foo)
    {
        @:Yes
    }
    else
    {
        @:No
    }
}
...see more

Razor Syntax allows you to embed code (C#) into page views through the use of a few keywords (such as “@”), and then have the C# code be processed and converted at runtime to HTML. In other words, rather than coding static HTML syntax in the page view, a user can code in the view in C# and have the Razor engine convert the C# code into HTML at runtime, creating a dynamically generated HTML web page.

@page
@model IndexModel
<h2>Welcome</h2>
 
<ul>
  @for (int i = 0; i < 3; i++)
  {
    <li>@i</li>
  }
</ul>
...see more

Let’s say that you have class Person and one of its properties is enum (in our case it’s enum Gender).

public enum Gender
{
    Unknown,
    Male,
    Female
}

Below you can see Razor Page with a simple HTML form. Please remember to add the using statement to the folder where is defined your enum type (in my case it’s @using SelectBindingEnum.Models).

<div class="form-group">
    <label asp-for="Person.Gender" class="control-label"></label>
    <select asp-for="Person.Gender" asp-items="Html.GetEnumSelectList<Gender>()" class="form-control"></select>
    <span asp-validation-for="Person.Gender" class="text-danger"></span>
</div>

As you can see above to binding enum values to HTML select tag you should use Tag Helper asp-items and HtmlHelper method GetEnumSelectList<T> where T is an enum type. This method generates a SelectList object for all enum values. Also, this method allows you to add Display attribute to your enum to change display text.

public enum Gender
{
   [Display(Name = "None")]
   Unknown,
   Male,
   Female
}

If you would add this attribute, you will see the following values in HTML select tag: None, Male and Female.

...see more

Some properties of model classes come as enums and we want to show Enum values in a select list. Sometimes we want enum element names but sometimes we want to use custom names or even translations.

Let’s define the enum and make it use DisplayAttribute and resource file.

public enum CustomerTypeEnum
{
    [Display(Name = "Companies")]
    PrivateSector,

    [Display(Name = "PublicSector", ResourceType = typeof(Resources.Common))]
    PublicSector,
            
    Internal
}

There are three different cases together now:

  1. Enum member with just a name
  2. Enum member with Display attribute and static name
  3. Enum member with Display attribute and resource file

Important thing: set resource modifier to Public.

Now use the Html.GetEnumSelectList() extension method to fill the select list with enum members. Notice the first empty selection (Select type …) as the only member of the select list.

<div class="form-group">
    <label asp-for="Type" class="control-label"></label>
    <select asp-for="Type" 
            class="form-control" 
            asp-items="Html.GetEnumSelectList<CustomerTypeEnum>()">
        option>Select type ...option>
    </select>
    <span asp-validation-for="Type" class="text-danger"><span>
<div>

When we run the application we can see that the select list is filled with enum members and ASP.NET Core respects DisplayAttribute with static name and resource files.

If you don’t have control over enum (enum is defined in already built assembly) then you can’t apply Display attribute to enum and you need some other solution to get values you need.

Wrapping up

ASP.NET Core has built-in Html.GetEnumSelectList() method we can use to turn enum members to select list items. The method is intelligent enough to support the Display attribute and therefore we can use custom names for enum members and even translations from resource files.

...see more

Here’s my claims transformation that adds roles to user identity.

public class AddRolesClaimsTransformation : IClaimsTransformation
{
    private readonly IUserService _userService;
 
    public AddRolesClaimsTransformation(IUserService userService)
    {
        _userService = userService;
    }
 
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        // Clone current identity
        var clone = principal.Clone();
        var newIdentity = (ClaimsIdentity)clone.Identity;
 
        // Support AD and local accounts
        var nameId = principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier ||
                                                          c.Type == ClaimTypes.Name);
        if (nameId == null)
        {
            return principal;
        }
 
        // Get user from database
        var user = await _userService.GetByUserName(nameId.Value);
        if (user == null)
        {
            return principal;
        }
 
        // Add role claims to cloned identity
        foreach(var role in user.Roles)
        {
            var claim = new Claim(newIdentity.RoleClaimType, role.Name);
            newIdentity.AddClaim(claim);
        }
 
        return clone;
    }
}
...see more

Open a new command prompt window and navigate to the folder that has your C#project file (.csproj file). Before we install Webpack, let us first create a package.json file. The package.json file holds metadata information and is used to give information to npm about a project’s (module)dependencies. To create a “default” package.json file, type the “npm init” command:

npm init -y

The “-y” option uses default options.

If the command was successful, it should have created a package.json file with contents similar to this:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
  }
...see more

To now install Webpack (which is also a “module”), type the following command:

npm install webpack -D

If the command ran successfully, it should have created a new folder named “node_modules” in your project folder and downloaded several modules into this folder (into various folders), of course including the Webpack package as well. 

Instead of a run-time dependency, the “ — save-dev” option adds a “dev dependency” to the package.json file. This indicates that the Webpack package is only useful during development. That would make sense, as once we have created the “bundles” as we require, we would use them directly in production. The package.json file should look similar to this:

{
 "name": "demo",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 },
 "devDependencies": {
  "webpack": "^4.46.0",
 }
}
...see more

Create the webpack.config.js file in the root folder with this code:

const path = require(‘path’);
module.exports = {
 mode: ‘development’,
 entry: ‘./wwwroot/source/app.js’,
 output: {
 path: path.resolve(__dirname, ‘wwwroot/dist’),
 filename: ‘bundle.js’
 }
};

As you can see above, we are giving Webpack the entry point, which is our app.js file. As well as telling it where to output the bundled file.

...see more

Babel is a transpiler. The transpiler transforms ES6 code to use ES5 syntax that older browsers can understand. While Babel itself is very feature-rich and can be used independently, for our purposes, we can use the corresponding babel “loaders” to do the job.

Before we can use any loaders, we need first to install them. For our purpose, we will have to install the relevant babel loaders. Use the following command to install the babel loaders and the “presets”.

npm install "babel-loader" @babel/core @babel/preset-env --save-dev

If the command ran successfully, these loaders would be installed in the node_modules folder and the package.json would be modified.

...see more

Update webpack with Babel using the next code 

module: {
rules: [
  {
    test: /\.js$/,
    exclude: /(node_modules)/,
    use: {
      loader: ‘babel-loader’,
      options: {
        presets: [‘@babel/preset-env’]
        }
      }
    }
  ]
}
...see more

Install React:

npm install react react-dom --save-dev

Install the Babel preset to process React JSX code:

npm install @babel/preset-react --save-dev

Add the React preset to Babel. It will convert React (JSX) code to raw JavaScript:

module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-react', '@babel/preset-env']
          }
        }
      }
    ]
  }
...see more

Signing up for reCAPTCHA can be done here: https://www.google.com/recaptcha/about/. Once signed up, you will be guided through creating a new site (reCAPTCHA v2).


In the following steps, we will need both a reCAPTCHA Site Key and Secret Key. Bot keys are found on the settings screen on the new site:

...see more

reCAPTCHA is added by including the JavaScript from Google somewhere. For ASP.NET Core add it to the Scripts section:

@section Scripts {
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<partial name="_ValidationScriptsPartial" />
</script>

Next, you will need to tell reCAPTCHA where to put the CAPTCHA control. Paste the following markup inside the form element:

<div class="form-group">
<div class="g-recaptcha" data-sitekey="SITE_KEY"></div>
</div>

For the data-sitekey attribute, use the reCAPTCHA site key from the site settings.

...see more

The following sample will return JSON with a 200 OK status code (it's an Ok type of ObjectResult)

public IActionResult GetAsJson()
{
   return new OkObjectResult(new Catagory { Id = 1234, Name = "Articles" });
}

The following code uses the Produces() attribute (which is a ResultFilter) with contentType = application/json

[Produces("application/json")]
public Student GetWithProduces()
{
    return new Catagory { Id = 1234, Name = "Articles" };
}

Return JSON with a 400 error code with a message

public IActionResult ErrorJSON()
{
    return new JsonResult(new { message = "The Error Messages" })
    {
StatusCode = StatusCodes.Status400BadRequest // Status code here 
    };
}
...see more

How to return JSON in camelCase?

Configure in Startup.cs

First of all, add this dependency:

using System.Text.Json;

Then add this in ConfigureServices():

services.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});

Change JsonSerializer options

Supply JsonSerializer.Serialize() with the optional JsonSerializerOptions object and override the casing:

string jsonString = JsonSerializer.Serialize(m, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
...see more

Razor Syntax allows you to embed code (C#) into page views through the use of a few keywords (such as “@”), and then have the C# code be processed and converted at runtime to HTML. In other words, rather than coding static HTML syntax in the page view, a user can code in the view in C# and have the Razor engine convert the C# code into HTML at runtime, creating a dynamically generated HTML web page.

@page
@model IndexModel
<h2>Welcome</h2>
 
<ul>
  @for (int i = 0; i < 3; i++)
  {
    <li>@i</li>
  }
</ul>
...see more

In a Razor view page (.cshtml), the @page directive indicates that the file is a Razor Page.

In order for the page to be treated as a Razor Page, and have ASP.NET parse the view syntax with the Razor engine, the directive @page should be added at the top of the file.

There can be empty space before the @page directive, but there cannot be any other characters, even an empty code block.

@page
@model IndexModel
 
<h1>Welcome to my Razor Page</h1>
<p>Title: @Model.Title</p>
...see more

The page model class, i.e. the data and methods that hold the functionality associated with a view page, is made available to the view page via the @model directive.

By specifying the model in the view page, Razor exposes a Model property for accessing the model passed to the view page. We can then access properties and functions from that model by using the keyword Model or render its property values on the browser by prefixing the property names with @Model, e.g. @Model.PropertyName.

@page
@model PersonModel
 
// Rendering the value of FirstName in PersonModel
<p>@Model.FirstName</p>
 
<ul>
 // Accessing the value of FavoriteFoods in PersonModel
 @foreach (var food in Model.FavoriteFoods)
 {
  <li>@food</li>
 }
</ul>
...see more

Razor pages use the @ symbol to transition from HTML to C#. C# expressions are evaluated and then rendered in the HTML output. You can use Razor syntax under the following conditions:

  • Anything immediately following the @ is assumed to be C# code.
  • Code blocks must appear within @{ ... } brackets.
  • A single line of code that uses spaces should be surrounded by parentheses ( ).
@page
@model PersonModel
 
// Using the `@` symbol:
<h1>My name is @Model.FirstName and I am @Model.Age years old </h1>
 
// Using a code block:
@{
 var greet = "Hey threre!";
 var name = "John";
 <h1>@greet I'm @name!</h1>
}
 
// Using parentheses:
<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>
...see more

In Razor Pages, you can use the ViewData property to pass data from a Page Model to its corresponding view page, as well as share it with the layout, and any partial views.

ViewData is a dictionary that can contain key-value pairs where each key must be a string. The values can be accessed in the view page using the @ symbol.

A huge benefit of using ViewData comes when working with layout pages. We can easily pass information from each individual view page such as the title, into the layout by storing it in the ViewData dictionary in a view page:

@{ ViewData["Title"] = "Homepage" }

We can then access it in the layout like so: ViewData["Title"]. This way, we don’t need to hardcode certain information on each individual view page.

// Page Model: Index.cshtml.cs
public class IndexModel : PageModel
{
 public void OnGet()
 {
  ViewData["Message"] = "Welcome to my page!";
  ViewData["Date"] = DateTime.Now();
 }
}
 
// View Page: Index.cshtml
@page
@model IndexModel
 
<h1>@ViewData["Message"]</h1>
<h2>Today is: @ViewData["Date"]</h2>
...see more

Razor is a concise markup language that integrates server-side code (C# or VB) into ASP.NET web pages seamlessly. It simplifies web development by blending code and HTML, enhancing productivity and maintainability.

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}
<h1>@ViewData["Title"]</h1>
<p>Welcome to my ASP.NET Core Razor Pages!</p>

In this code snippet, the @page directive specifies the page, @model defines the page's model, and @ViewData displays dynamic data within the Razor Page markup.

Resources

...see more

Razor Syntax allows you to embed code (C#) into page views through the use of a few keywords, and then have the C# code be processed and converted at runtime to HTML.

...see more

Before jumping to the solution, let's talk about use cases. Using both tokens and cookies is not a common use case, but it typically comes up when you have a SPA or pure API applications that also need to secure some non-SPA pure Web Browser end points that the server sends directly to the browser. If that content needs to be protected behind authentication you might need Cookie authentication, because you can't do Bearer Token authentication with plain HTML interfaces in the browser.

services.AddAuthentication(options =>
    {
        // custom scheme defined in .AddPolicyScheme() below
        options.DefaultScheme = "JWT_OR_COOKIE";
        options.DefaultChallengeScheme = "JWT_OR_COOKIE";
    })
    .AddCookie("Cookies", options =>
    {
        options.LoginPath = "/login";
        options.ExpireTimeSpan = TimeSpan.FromDays(1);
    })
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = config.JwtToken.Issuer,
            ValidateAudience = true,
            ValidAudience = config.JwtToken.Audience,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.JwtToken.SigningKey))
        };
    })

Source: Combining Bearer Token and Cookie Authentication in ASP.NET - Rick Strahl's Web Log (west-wind.com)

...see more

Here are six different ways to run your ASP.NET Core web application:

  1. Visual Studio F5: Simply press F5 in Visual Studio to run your application.
  2. Command Line (dotnet run): Open a terminal and run dotnet run in your project directory.
  3. Publish and Run: Use dotnet publish to create a publish folder, then navigate to bin\{...}\publish and run dotnet YourProject.dll.
  4. IIS: Host your application on IIS for production-level hosting.
  5. Linux Console: Run dotnet YourProject.dll on Linux from the console.
  6. Linux with Supervisor and Nginx: For robust production setups on Linux, use Supervisor to manage your application and Nginx as a reverse proxy.

For more detailed information, check out the guide on 6 different ways to run an asp.net core web application (secretGeek.net)

...see more

Kubernetes ist in der Cloud-Welt allgegenwärtig; nahezu alle Public-Cloud-Anbieter offerieren Kubernetes als Managed Service oder nutzen es intern für ihre PaaS- und Serverless-Dienste. Auch in lokalen Rechenzentren wird Kubernetes häufig eingesetzt und entfaltet dort seine Stärken als Plattform. Obwohl sich die verschiedenen Kubernetes-Distributionen und Managed Services in technischen Details wie Installation und Integration von Netzwerk- und Speicherressourcen unterscheiden, bleibt die Plattform für Anwendungen weitgehend einheitlich. Mit minimalen Konfigurationsanpassungen können Applikationen sowohl in der Cloud als auch in On-Premises-Umgebungen nahtlos betrieben werden.

Quelle: Kurs auf Kubernetes! (dotnetpro.de)

...see more

The following Razor markup caches the current date:

<cache>@DateTime.Now</cache>

The first request to the page that contains the Tag Helper displays the current date. Additional requests show the cached value until the cache expires (default 20 minutes) or until the cached date is evicted from the cache.

...see more
  • enabled - Used to specify if this tag is enabled or not
  • expires-after - Specifies the period of time after which the cached item should expire
  • expires-on - Specifies the time at which the cached entry should expire
  • expires-sliding - The period of time after the last access that the item should expire
  • priority - Specifies the CacheItemPriority value of the cached item
  • vary-by - Used to specify the parameters that determine whether different versions of the same content should be cached
...see more

The Cache Tag Helper provides the ability to improve the performance of your ASP.NET Core app by caching its content to the internal ASP.NET Core cache provider.

The cache tag helper enables you to cache regions of a Razor page in memory on the server. Typical uses for this helper are for View Components or partial views that require relatively expensive database or web service calls, but where the content doesn't change very often. This type of caching its primarily used to improve a website's performance.

Unlike most other tag helpers, the Cache tag helper doesn't target a standard HTML element. It targets the <cache> tag, which is not rendered to the browser and doesn't appear in the HTML source either.

...see more

A sitemap is an XML file that contains all URLs of a website. When a website creates dynamic web pages, it is very difficult for Search Engines to search all URLs and index them. That is why we created a sitemap XML file and include all required URLs in it. It helps search engines find URLs easily and index them quickly.

The default URL is https://example.com/sitemap.xml

Add to Set
  • .NET
  • Agile
  • AI
  • ASP.NET Core
  • Azure
  • C#
  • Cloud Computing
  • CSS
  • EF Core
  • HTML
  • JavaScript
  • Microsoft Entra
  • PowerShell
  • Quotes
  • React
  • Security
  • Software Development
  • SQL References
  • Technologies
  • Testing
  • Visual Studio
  • Windows
 
Sets