European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

ASP.NET 5 Hosting Available NOW!

clock November 24, 2020 07:35 by author Scott

HostForLIFE.eu is a popular online Windows and ASP.NET based hosting service provider catering to those people who face such issues. The company has managed to build a strong client base in a very short period of time. It is known for offering ultra-fast, fully-managed and secured services in the competitive market.

.NET 5 is the next version of .NET Core and the future of the .NET platform. With .NET 5 you have everything you need to build rich, interactive front end web UI and powerful backend services. .NET 5 contains great performance improvements in the
runtime and libraries and for the gRPC components. These improvements, when applied to ASP.NET Core, result in some significant wins in throughput (RPS) and latency.

HostForLIFE.eu hosts its servers in top rate data centers that's located in Amsterdam (NL), London (UK), Washington, D.C. (US), Paris (France), Frankfurt (Germany), Chennai (India), Milan (Italy), Toronto (Canada) and São Paulo (Brazil) to ensure 99.9% network period. All data center feature redundancies in network connectivity, power, HVAC, security, and fire suppression. HostForLIFE.eu proudly announces available ASP.NET 5 feature for new customers and existing customers. 


 

HostForLIFE.eu is a popular online Windows based hosting service provider catering to those people who face such issues. The company has managed to build a strong client base in a very short period of time. It is known for offering ultra-fast, fully-managed and secured services in the competitive market. Their powerful servers are especially optimized and ensure ASP.NET 5 performance. They have best data centers on three continent, unique account isolation for security, and 24/7 proactive uptime monitoring.

Further information and the full range of features ASP.NET 5 Hosting can be viewed here
https://hostforlife.eu/European-ASPNET-5-Hosting.



European ASP.NET Core Hosting :: How to Fix Method Not Allowed on PUT and DELETE

clock November 23, 2020 07:16 by author Scott

This tutorial shows how to fix method not allowed on PUT and DELETE requests in ASP.NET Core.

After pushing code to the beta server, most of it was working fine. The front-end was being able to call GET, POST and OPTIONS requests normally. When trying to DELETE or PUT entries, however, the following error would show up on the browser’s console:
 


 
Method not allowed? CORS error? What?

Initially, I was misled by the CORS error. Having had problems with this in the past, I thoroughly checked my API code for any possible problem in the configuration that could lead to this error only after deployed. I found none.

Then, it dawned on me that the CORS error could be not because my API wasn’t sending the ‘Access-Control-Allow-Origin’ on its response, but because it wasn’t being sent on the HTTP 405 error seen above.

Solution

What happens is that, when published, .NET Core enables the WebDAVModule, which disables PUT and DELETE requests by default.

So, to solve the issue, I ended up disabling WebDAV in the whole application, by adding these lines to the auto-generated web.config:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
   <remove name="WebDAVModule" />
  /modules>
</system.webServer>


After restarting the API in IIS, TA-DA! Everything (or at least your PUT and DELETE requests) should be working normally.

I hope this will be helpful to someone that host ASP.NET website on Windows Server.



ASP.NET 5 Now Available on HostForLIFE.eu Hosting Server!

clock November 12, 2020 09:34 by author Scott

Today, we are announcing ASP.NET 5 on our hosting environment. We are happy to support this new ASP.NET 5 for our customers on our servers.

High-level goals for .NET 5 include providing a unified .NET SDK experience, with a single BCL (base class library) across all .NET 5 applications, and with support for both native and web applications across multiple operating systems. A single .NET 5 native application project would support targets such as Windows, Microsoft Duo (Android), and Apple iOS using native controls on those platforms.

Additional goals of .NET 5 include support for building high-performance cloud applications, faster algorithms in the BCL, better support for containers in the runtime, and support for HTTP3. .NET 5.0 includes support for the WebAssembly binary format, via the Mono runtime and .NET libraries. A set of nullable reference type annotations also is featured.

The following is ASP.NET 5 features

1. Cross-Platform Runtime

As we know that ASP.NET 5 can work with two different environment .NET core and .NET Framework to provide you a better experience and flexibility.

The .NET core runtime is a cross-platform and modular runtime with a small impression. .NET Core runtime has the following benefits.

  • You can run your application with a deployed version of runtime instead of that runtime which is installed on a host operating system. That makes easy to the app deployment and framework update.
  • The ASP.NET 5 provides a cross-platform version of .NET Core for Linux, Mac, and Windows operating system rather than that operating system you use for development.
  • .NET Core runtime will never ask you for update the runtime feature which is not relevant to your application. You can save your time on testing and deploying updates.

2. Fast HTTP performance

ASP.NET 5 has introduced a modular HTTP request pipeline so you can add the component according to your requirements. A pipeline does not depend on system.web. By reducing upward in pipeline app can work better and tuned better HTTP stack. The pipeline is also supported OWIN.

You can use the configure method in your Startup class to customize the pipeline the configure method used to specify which middleware you want to use in your requested pipeline. ASP.NET 5 has introduced many different middlewares from katana project including middleware for authentication, diagnostics, and static files.

3. Dependency injection

ASP.NET Frameworks like SignalR, Web API and MVC supports the dependency injection but not the holistic way and consistent through the entire web stack. You can access service in middleware, in filters,  at startup, in model binding, virtually any part of the pipeline and in controllers wherever you want use your service. ASP.NET 5 has a minimum dependency injection container to bootstrap the system. but it also provides the facility of changing containers of your choice like Ninject, Autofac, etc.

4. Cloud-ready configure

The best feature of ASP.NET 5 is you not need to use Web.config file for configuration. The main aim of ASP.NET 5 is making easy to deploy an application to the cloud and automatically read the correct configuration value for particular environment. The new system allows you to request name value from different sources like XML, environment variable and XML you have to decide which format is best in your scenario.

5. MVC 6 – a unified programming model

Web API, Web Pages, and MVC frequently used together in developing solution and they provide complementary functionality. in past ASP.NET release, this framework was implemented separately due to this they have inconsistencies and duplication issues. In MVC 6 we can merge those models in a single programming model. Now you are able to create a single web app that handles the data services and Web UI without reconciling in the programing framework. You also able to transition a site first developed with a web page into a more robust MVC app.

Now you can return content-negotiated data and Razor views from same controller and using same MVC filter pipeline.

Conclusion

The .NET 5 project is an important and exciting new direction for .NET. You will see .NET become simpler but also have broader and more expansive capability and utility. All new development and feature capabilities will be part of .NET 5, including new C# versions.

Now, you can host your ASP.NET 5 with us as low as €3.00/month. For more information about this new ASP.NET 5, please visit our site at
https://www.hostforlife.eu.



European ASP.NET Core 3.1 Hosting :: Is .NET Core 3.1 Secure?

clock November 5, 2020 09:12 by author Scott

Well, Microsoft will release Asp.net 5 version, now it is on RC version and of course we will support this feature on our hosting environment. Asp.net Core keep improving and it is very fast. Previously, we have also advise steps by steps to migrate your Asp.net Core to latest Asp.net Core 3.1. Why? It because with latest Asp.net Core, it will be more secure and improving your website speed.

Why .NET Core is Better for Security

If you’ve ever tried to update an old house, you know that it can be challenging. As we’ve learned more about home construction and materials we have updated building codes and standards to ensure that modern homes have far few troubles and are far more efficient. .NET Core is the same thing.

Microsoft built .NET Core from the ground up with twenty years of lessons learned and updated best practices built in. Application and website security are not add-ons and patches. Security was a fundamental attribute of design and structure which means we can build more secure apps with less complexity and faster performance. And this is especially important in the age of platforms and the cloud when APIs and service calls are flying back and forth to keep your business tech connected to the world at the speed of light.

Importantly, one of the lessons Microsoft learned was to always be looking forward. So even though .NET Core was built to be cloud-native, they were also looking at the fledgling technologies of connected devices (IoT) and edge-computing. So, this forward-looking technology is wired in as well.

In other words, many of the same things that make .NET Core orders of magnitude faster than previous .NET iterations also make it more secure.

Security for .NET Core 3.1

Security is still in the hands of the developers and admins who write, deploy, and maintain the applications. The best practices that have been developed over the last two decades – some of which we’ve documented over the years — are still best practices. .NET Core 3.1 just makes them easier to deploy, easier to maintain, and faster to run.

The basics still apply, including:

Manage Your Identity Providers in .NET 3.1

Great security starts with keeping the black-hats out and letting the good guys in to do business. Before we talk about things like authentication, we need to start with the tools to do that user authentication. .NET Core 3.1 natively includes Identity providers. But it also supports major third-party identity services, including from the major social networks (e.g., Facebook, Twitter, LinkedIn).

Authentication First / Authorization Second

Old-school applications used to focus on Authorization — which allowed users to access certain functions or features based upon roles first. But once given any degree of access, a system is less secure if that individual has bad intent.

Enforce HTTPS

Deploying HTTPS is not the same as enforcing it.

Encryption keys used to cost money. But we live in a time when adding encryption to your web application is either free or VERY inexpensive. Three years ago we wrote extensively about great services like
LetsEncrypt that offer free basic encryption. But there are a surprising number of sites that still have no encryption at all and many that do offer it as a security to visitors but do not enforce it as a security for and across the application itself.

Common Vulnerability Issues

According to Microsoft, the most common vulnerability types to guard against in .NET Core 3.1 are as follows:

  • Cross-Site Scripting (XSS) — An attacker places client-side scripts inside vulnerable website code, allowing the interception of cookies or access tokens.
  • SQL Injection — An attacker places executable database statements in an entry field. This is one of the most common attack types today. You can read about SQL injections on our blog.
  • Cross-Site Request Forgery (XSRF) — An attacker takes advantage of a previously authorized session. To learn more about
  • Open Redirect — Page/URL redirects are important tools in the hands of coders. But vulnerable websites can have redirects tampered with to point to a malicious URL. Information on preventing this kind of attack can be found on Microsoft’s website.

Summary - .NET Core 3.1 is Fully Secure

It is our opinion that the latest version of .NET Core 3.1.x is the safest and most secure development platform available today for creating business-class and enterprise-class websites and applications. But as with all development frameworks, deploying best practices and proper maintenance are key.



European ASP.NET Core Hosting - HostForLIFE.eu :: ASP.NET Core Custom Authentication

clock April 3, 2020 07:23 by author Scott

ASP.NET Core Identity is popular choice when web application needs authentication. It supports local accounts with username and password but also social ID-s like Facebook, Twitter, Microsoft Account etc. But what if ASP.NET Core Identity is too much for us and we need something smaller? What if requirements make it impossible to use it? Here’s my lightweight solution for custom authentication in ASP.NET Core.

We don’t have to use ASP.NET Core Identity always when we need authentication. I have specially interesting case I’m working on right now.

I’m building a site where users authenticate using Estonian ID-card and it’s mobile counterpart mobile-ID. In both cases users is identified by official person code. Users can also use authentication services by local banks. Protocol is different but users are again identified by official person code. There will be no username-password or social media authentication.

In my case I don’t need ASP.NET Core Identity as it’s too much and probably there are some security requirements that wipe classic username and password authentication off from table.

Configuring authentication

After some research it turned out that it’s actually very easy to go with cookie authentication and custom page where I implement support for those exotic authentication mechanisms.

First we have to tell ASP.NET Core that we need authentication. I’m going with cookie authentication as there’s no ping-pong between my site and external authentication services later. Let’s head to ConfigureServices() method of Startup class and enable authentication.

public void ConfigureServices(IServiceCollection services)
{
    // Enable cookie authentication
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
 
    services.AddHttpContextAccessor();
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

In Configure() method of Startup class we need to add authentication to request processing pipeline. The line after comment does the job.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ...
 
    // Add authentication to request pipeline
    app.UseAuthentication();
 
    app.UseStaticFiles();           
 
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

No we have done smallest part of work – ASP.NET Core is configured to use cookie authentication.

Implementing AccountController

Where is user redirected when authentication is needed? We didn’t say anything about it Startup class. If we don’t specify anything then ASP.NET Core expects AccountController with AccessDenied and Login actions. It’s bare minimum for my case. As users must be able to log out I added also Logout() action.

Here’s my account controller. Login() action is called with SSN parameter only by JavaScript that performs actual authentication. There’s always SSN when this method is called (of course, I will add more sanity checks later). Notice how I build up claims identity claim by claim.

public class AccountController : BaseController
{
    private readonly IUserService _userService;
 
    public AccountController(IUserService userService)
    {
        _userService = userService;
    }
 
    [HttpGet]
    public IActionResult Login()
    {
        return View();
    }
 
    [HttpPost]
    public async Task<IActionResult> Login(string ssn)
    {
        var user = await _userService.GetAllowedUser(ssn);
        if (user == null)
        {
            ModelState.AddModelError("", "User not found");
            return View();
        }
 
        var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
        identity.AddClaim(new Claim(ClaimTypes.Name, user.Ssn));
        identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName));
        identity.AddClaim(new Claim(ClaimTypes.Surname, user.LastName));
 
        foreach (var role in user.Roles)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role.Role));
        }
 
        var principal = new ClaimsPrincipal(identity);
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
 
        return RedirectToAction("Index","Home");
    }
 
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync();
 
        return RedirectToAction(nameof(Login));
    }
 
    public IActionResult AccessDenied()
    {
        return View();
    }
}

And this is it. I have now cookie-based custom authentication in my web application.

To try things out I run my web application, log in and check what’s inside claims collection of current user. All claims I expected are there. 

Wrapping up

ASP.NET Core is great on providing the base for basic, simple and lightweight solutions that doesn’t grow monsters over night. For authentication we can go with ASP.NET Core Identity but if it’s too much or not legally possible then it’s so-so easy to build our own custom cookie-based authentication. All we did was writing few lines of code to Startup class. On controllers side we needed just a simple AccountController where we implemented few actions for logging in, logging out and displaying access denied message.



European ASP.NET Core Hosting - HostForLIFE.eu :: 9 Tips to Increase Your ASP.NET Core 3.0 Applications

clock March 31, 2020 09:56 by author Scott

Performance is very important; it is a major factor for the success of any web application. ASP.NET Core 3.0 includes several enhancements that scale back memory usage and improve turnout. In this blog post, I provide 10 tips to help you improve the performance of ASP.NET Core 3.0 applications by doing the following:

Avoid synchronous and use asynchronous

Try to avoid synchronous calling when developing ASP.NET Core 3.0 applications. Synchronous calling blocks the next execution until the current execution is completed. While fetching data from an API or performing operations like I/O operations or independent calling, execute the call in an asynchronous manner.

Avoid using Task.Wait and Task.Result, and try to use await. The following code shows how to do this.

public class WebHost
{
    public virtual async Task StartAsync(CancellationToken cancellationToken = default)
    { 

        // Fire IHostedService.Start
        await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false); 

        // More setup
        await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false); 

        // Fire IApplicationLifetime.Started
        _applicationLifetime?.NotifyStarted(); 

        // Remaining setup
    }
}

Entity Framework 3.0 Core also provides a set of async extension methods, similar to LINQ methods, that execute a query and return results.

Asynchronous querying

Asynchronous queries avoid blocking a thread while the query is executed in the database. Async queries are important for quick, responsive client applications.

Examples:

  • ToListAsync()
  • ToArrayAsync()
  • SingleAsync()

public async Task<List> GetBlogsAsync()
{
    using (var context = new BloggingContext())
    {
        return await context.Blogs.ToListAsync();
    }
}

Asynchronous saving

Asynchronous saving avoids a thread block while changes are written to the database. It provides DbContext.SaveChangesAsync() as an asynchronous alternative to DbContext.SaveChanges().

public static async Task AddBlogAsync(string url)
{
    using (var context = new BloggingContext())
    {
        var blogContent = new BlogContent { Url = url };
        context.Blogs.Add(blogContent);
        await context.SaveChangesAsync();
    }
}

Optimize data access

Improve the performance of an application by optimizing its data access logic. Most applications are totally dependent on a database. They have to fetch data from the database, process the data, and then display it. If it is time-consuming, then the application will take much more time to load.

Recommendations:

  • Call all data access APIs asynchronously.
  • Don’t try to get data that is not required in advance.
  • Try to use no-tracking queries in Entity Framework Core when accessing data for read-only purposes.
  • Use filter and aggregate LINQ queries (with .Where, .Select, or .Sum statements), so filtering can be performed by the database.

You can find approaches that may improve performance of your high-scale apps in the new features of EF Core 3.0.

Use response caching middleware

Middleware controls when responses are cacheable. It stores responses and serves them from the cache. It is available in the Microsoft.AspNetCore.ResponseCaching package, which was implicitly added to ASP.NET Core.

In Startup.ConfigureServices, add the Response Caching Middleware to the service collection.

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

Use JSON serialization

ASP.NET Core 3.0 uses System.Text.Json for JSON serialization by default. Now, you can read and write JSON asynchronously. This improves performance better than Newtonsoft.Json. The System.Text.Json namespace provides the following features for processing JSON:

  • High performance.
  • Low allocation.
  • Standards-compliant capabilities.

  • Serializing objects to JSON text and deserializing JSON text to objects.

Reduce HTTP requests

Reducing the number of HTTP requests is one of the major optimizations. Cache the webpages and avoid client-side redirects to reduce the number of connections made to the web server.

Use the following techniques to reduce the HTTP requests:

  • Use minification.
  • Use bundling.
  • Use sprite images.

By reducing HTTP requests, these techniques help pages load faster.

Use exceptions only when necessary

Exceptions should be rare. Throwing and catching exceptions will consume more time relative to other code flow patterns.

  • Don’t throw and catch exceptions in normal program flow.

  • Use exceptions only when they are needed.

Use response compression

Response compression, which compresses the size of a file, is another factor in improving performance. In ASP.NET Core, response compression is available as a middleware component.

Usually, responses are not natively compressed. This typically includes CSS, JavaScript, HTML, XML, and JSON.

  • Don’t compress natively compressed assets, such as PNG files.
  • Don’t compress files with a size of 150-1,000 bytes.
  • Don’t compress small files; it may produce a compressed file larger than the uncompressed file.

Package: Microsoft.AspNetCore.ResponseCompression is implicitly included in ASP.NET Core apps.

The following sample code shows how to enable Response Compression Middleware for the default MIME types and compression providers.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCompression();
    }
}

These are the providers:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes =
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

HttpContext accessibility improvements

HttpContext accessibility is only valid as long as there is an active HTTP request in ASP.NET Core. Here are some suggestions for accessing HttpContext from Microsoft’s documentation:

Client-side improvements

Client-side optimization is one important aspect of improving performance. When creating a website using ASP.Net Core, consider the following tips:

Bundling

Bundling combines multiple files into a single file, reducing the number of server requests. You can use multiple individual bundles in a webpage.

Minification

Minification removes unnecessary characters from code without changing any functionality, also reducing file size. After applying minification, variable names are shortened to one character and comments and unnecessary whitespace are removed.

Loading JavaScript at last

Load JavaScript files at the end. If you do that, static content will show faster, so users won’t have to wait to see the content.

Use a content delivery network

Use a content delivery network (CDN) to load static files such as images, JS, CSS, etc. This keeps your data close to your consumers, serving it from the nearest local server.

Conclusion

Now you know 10 tips to help improve the performance of ASP.NET Core 3.0 applications. I hope you can implement most of them in your development.

 



European ASP.NET Core Hosting - HostForLIFE.eu :: How to Use AutoMapper with ASP.NET Core 3

clock March 19, 2020 09:20 by author Scott

AutoMapper is well known in the .NET community. It bills itself as "a simple little library built to solve a deceptively complex problem - getting rid of code that maps one object to another," and it does the job nicely.

In the past, I've used it exclusively with ASP.NET APIs. However, the method for utilizing it via dependency injection has changed. So let's review how to get started, how to define mappings and how to inject our mappings into ASP.NET Core APIs.

Getting Started

Like most .NET libraries, we can install the AutoMapper package from Nuget.

Install-Package AutoMapper

For our purposes, we'll focus on two classes that are related; User and UserDTO.

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string FavoriteFood { get; set; }
    public DateTime BirthDate { get; set; }
}

public class UserDTO
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int BirthYear { get; set; }
}

These classes will serve as source and destination types that we can work with.

Default Mappings

Without specific configuration, AutoMapper will match properties based on their name. By default, it will ignore null reference exceptions when mapping source and destination types. Below is a snippet mapping the source and destination types using the default configuration.

var config = new MapperConfiguration(cfg => cfg.CreateMap<User, UserDTO>());

var user = new User()
{
    Id = Guid.NewGuid(),
    Name = "Wayne Curry",
    FavoriteFood = "Sushi",
    BirthDate = new DateTime(1986, 10, 12)
};

var mapper = config.CreateMapper();
UserDTO userDTO = mapper.Map<UserDTO>(user);

The above will create a UserDTO object with an Id and Name that matches the original user object, but no error is thrown as a result of not having the FavoriteFood property on the UserDTO type. Also, the BirthYear property of the UserDTO will be zero.

Custom Mappings

We can use projection to translate properties as they are mapped. For instance, the code snippet below shows how we can map the BirthDate property of the User type to the BirthYear property of the UserDTO type.

var config = new MapperConfiguration(cfg =>
    cfg.CreateMap<User, UserDTO>()
        .ForMember(dest => dest.BirthYear,
                   opt => opt.MapFrom(src => src.BirthDate.Year));

var user = new User()
{
    Id = Guid.NewGuid(),
    Name = "Wayne Curry",
    FavoriteFood = "Sushi",
    BirthDate = new DateTime(1986, 10, 12)
};

var mapper = config.CreateMapper();
UserDTO userDTO = mapper.Map<UserDTO>(user);

The resulting userDTO object will be similar to our first example, but this time it will
include the BirthYear property of 2000.

Profiles

A clean way to organize and maintain our mapping configurations is with profiles. Many times these Profile classes will encapsulate business areas (e.g. Ordering, Shipping). To start, we'll create a class that inherits from Profile and put the configuration in the constructor.

public class UserManagementProfile : Profile
{
    public UserManagementProfile()
    {
        CreateMap<User, UserDTO>()
            .ForMember(dest => dest.BirthYear,
            opt => opt.MapFrom(src => src.BirthDate.Year));

        // Configurations for other classes in this business
        // area can be included here as well, like below:

        // CreateMap<Role, RoleDTO>();
        // CreateMap<Permission, PermissionDTO>();
    }
}

For added isolation, we can create a project just for our Profile configurations. Using profiles helps us keep configurations more manageable as our application grows.

Dependency Injection

Dependency injection is baked into ASP.NET Core, but to use AutoMapper with it we'll need additional configuration and an additional Nuget package.

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

Register AutoMapper

Once installed, we can define the configuration using profiles. In the Startup.ConfigureServices method, we can use the AddAutoMapper extension method on the IServiceCollection object as shown below:

// By Marker
services.AddAutoMapper(typeof(ProfileTypeFromAssembly1) /*, ...*/);

// or by Assembly
services.AddAutoMapper(profileAssembly1, profileAssembly2 /*, ...*/);

Inject AutoMapper

With AutoMapper registered and its configurations set, we can now inject an IMapper into our controllers.

public class UsersController
{
    private readonly IMapper _mapper;

    public UsersController(IMapper mapper) => _mapper = mapper;

    // use _mapper.Map
}

With the IMapper we can map our objects to their DTO equivalents using the .Map method.

Wrap It Up

Now that ASP.NET Core is injecting AutoMapper to our controllers, we can add configurations to our profiles or create new profiles for new business areas and still map appropriately without further configuration.

Of course, we didn't cover all of the features of AutoMapper so I'd suggest checking out their documentation for more information about their capabilities. Hopefully this post gave you enough information to start trying AutoMapper yourself. Let me know in the comments how you use AutoMapper in your applications.



European ASP.NET Core Hosting :: How to Create a Multi Tenant .NET Core Application

clock January 21, 2020 07:30 by author Scott

Introduction

In the final installment we will extend our multi-tenant solution to allow each tenant to have different ASP.NET Identity providers configured. This will allow each tenant to have different external identiy providers or different clients for the same identity provider.

This is important to allow consent screens on third party services reflect the branding of the particular tenant that the user is signing in to.

Tenant specific authentication features

In this post we will enable three features

Allow different tenants to configure different authentication options

This is useful if different tenants want to allow different ways of signing in, e.g. one tenant might want to allow Facebook and Instagram while another wants local logins only.

Make sure each tenant has their own authentication cookies

This is useful if tenants are sharing a domain, you don’t want the cookies of one tenant signing you in to all tenants.

Note: If you follow this post your tenants will be sharing decryption keys so one tenant’s cookie is a valid ticket on another tenant. Someone could send one tenant’s cookie to a second tenant, you will need to either also include a tenant Id claim or extend this further to have seperate keys to verify the cookie supplied is intended for the tenant.

Allow different tenants to use different configured clients on an external identity provider

With platforms such as Facebook if it’s the first time the user is signing in they will often be asked to grant access to the application for their account, it’s importannt that this grant access screen mentions the tenant that is requesting access. Otherwise the user might get confused and deny access if it’s from a shared app with a generic name.

Implementation

There are 3 main steps to our solution

1. Register the services depending on your tenant: Configure the authentication services depending on which tenant is in scope

2. Support dynamic registration of schemes: Move the scheme provider to be fetched at request time to reflect the current tenant context

3. Add an application builder extension: Make it nice for developers to enable the feature

This implementation is only compatible with ASP.NET Core 2.X. In 1.0 the Authentication was defined in the pipeline so you could use branching to configure services on a per-tenant basis, however this is no longer possible. The approach we’ve taken is to use our tenant specific container to register the different schemes/ options for each tenant.

This post on GitHub outlines all of the changes between 1.0 and 2.0.

1. Register the services depending on your tenant

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    ...

    return services.UseMultiTenantServiceProvider<Tenant>((t, c) =>
    {
        //Create a new service collection and register all services
        ServiceCollection tenantServices = new ServiceCollection();       

        var builder = tenantServices.AddAuthentication(o =>
            {
                //Support tenant specific schemes
                o.DefaultScheme = $"{t.Id}-{IdentityConstants.ApplicationScheme}";
            }).AddCookie($"{t.Id}-{IdentityConstants.ApplicationScheme}", o =>
            {
                ...
            });

        //Optionally add different handlers based on tenant
        if (t.FacebookEnabled)
                builder.AddFacebook(o => {
                    o.ClientId = t.FacebookClientId;
                    o.ClientSecret = t.FacebookSecret; });

        //Add services to the container
        c.Populate(tenantServices);

        ...
    });
}

Seems too easy right? It is. If you run it now your handlers aren’t registered using the default “.UseAuthentication” middleware. The schemes are registered in the middleware constructor before you have a valid tenant context. Since it doesn’t support registering schemes dynamically OOTB we will need to slightly modify it.

2. Update the authentication middleware to support dynamic registration of schemes

Disclaimer ahead! The ASP.NET framework was written by very smart people so I get super nervous about making any changes here - I’ve tried to limit the change but there could be unintended consequences! Proceed with caution

We’re going to take the existing middleware and just move the IAuthenticationSchemeProvider injection point from the constructor to the Invoke method. Since the invoke method is called after we’ve registered our tenant services it will have all the tenant specific authentication services available to it now.

/// <summary>
/// AuthenticationMiddleware.cs from framework with injection point moved
/// </summary>
public class TenantAuthMiddleware
{
    private readonly RequestDelegate _next;

    public TenantAuthMiddleware(RequestDelegate next)
    {
        _next = next ?? throw new ArgumentNullException(nameof(next));
    }  

    public async Task Invoke(HttpContext context, IAuthenticationSchemeProvider Schemes)
    {
        context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
        {
            OriginalPath = context.Request.Path,
            OriginalPathBase = context.Request.PathBase
        });

        // Give any IAuthenticationRequestHandler schemes a chance to handle the request
        var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
        foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
        {
            var handler = await handlers.GetHandlerAsync(context, scheme.Name)
                as IAuthenticationRequestHandler;
            if (handler != null && await handler.HandleRequestAsync())
            {
                return;
            }
        }

        var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
        if (defaultAuthenticate != null)
        {
            var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
            if (result?.Principal != null)
            {
                context.User = result.Principal;
            }
        }       

        await _next(context);
    }
}

3. Add an application builder extension to register our slightly modified authentication middleware

This provides a nice way for the developer to quickly register the tenant aware authentication middleware

/// <summary>
/// Use the Teanant Auth to process the authentication handlers
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static IApplicationBuilder UseMultiTenantAuthentication(this IApplicationBuilder builder)
    => builder.UseMiddleware<TenantAuthMiddleware>();

Now we can register the tenant aware authenticaion middleware like this

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...

    app.UseMultiTenancy()
        .UseMultiTenantContainer()
        .UseMultiTenantAuthentication();
}

Wrapping up

In this post we looked at how we can upgrade ASP.NET Core to support tenant specifc authentication, this means each tenant can have different external identify providers registered and connect to different clients for each of those providers.



European ASP.NET Core Hosting :: How to Make Simple Chat Using Asp.net Core SignalR

clock December 12, 2019 07:54 by author Scott

This is tutorial about how to make simple chat with Asp.net Core SignalR. It only takes around 5-10 mins for someone who is familiar with Asp.net Core. Here we go

Creating the projects

We will create a new empty ASP.NET Core Web project. You can either do it with Visual Studio or execute dotnet new web in the command line.

I have Angular CLI installed on my machine. If you don’t either install it or create a new empty Angular application. I am using Angular CLI 1.5 and creating a new project with it – Angular 5 application.

I will just execute ng new CodingBlastChat in the command line, inside of solution folder. And now I have basic working Angular application. To start it, I just type in ng serve and I my application is running on localhost port 4200.

Installing dependencies

We need to install both server-side and client-side libraries for ASP.NET Core SignalR.

To install the server-side library we will use NuGet. You can either use Visual Studio or do it via command line. The package name is Microsoft.AspNetCore.SignalR

dotnet add package Microsoft.AspNetCore.SignalR

We will use npm to add client-side library:

npm install @aspnet/signalr-client

If you are using npm 4 or older you will need to add the –save argument, if you want it to be saved inside of your package.json as well. And that’s it for library dependencies. We are all set and we can now use SignalR.

Setting up server-side

We can now add the simple ChatHub class:

public class ChatHub : Hub
{
    public void SendToAll(string name, string message)
    {
        Clients.All.InvokeAsync("sendToAll", name, message);
    }
}

This will call the sendToAll client method for ALL clients.

For SignalR to work we have to add it to DI Container inside of ConfigureServices method in Startup class:

services.AddSignalR();

Also, we have to tell the middleware pipeline that we will be using SignalR. When the request comes to the /chat endpoint we want our ChatHub to take over and handle it.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseSignalR(routes =>
    {
        routes.MapHub<ChatHub>("chat");
    });
}

Enabling CORS

Since we will be serving the Angular application on a separate port, for it to be able to access the SignalR server we will need to enable CORS on the Server.

Add the following inside of ConfigureServices, just before the code that adds SignalR to DI container.

services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
    {
        builder
        .AllowAnyMethod()
        .AllowAnyHeader()
        .WithOrigins("http://localhost:4200");
    }));

We also have to tell the middleware to use this CORS policy. Add the following inside of Configure method, BEFORE SignalR:

app.UseCors("CorsPolicy");

Now your Configure method should look like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseCors("CorsPolicy");

    app.UseSignalR(routes =>
    {
        routes.MapHub<ChatHub>("chat");
    });
}

Also, make sure to check your Properties/launchSettings.json file so you can know which port is your app running. You can also configure it to use any port you want. I will set it to 5000.

Client-side

You would ideally want to have a separate service for communicating with ChatHub on the server. Also, you would want to store your endpoints in some kind of Angular service for constants. But for the simplicity sake, we will skip that for now and add it after we make the chat functional.

I will use existing AppComponent that Angular CLI created, and extend it.

I will add properties for nick, message and list of messages. Also, I will add a property for HubConnection.

import { Component } from '@angular/core';
import { HubConnection } from '@aspnet/signalr-client';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private hubConnection: HubConnection;
  nick = '';
  message = '';
  messages: string[] = [];
}

HubConnection is part of the signalr-client library built by ASP.NET team. And we will use it to establish the connection with the server and also to send messages and listen for messages from the server.

We will establish the connection before any other code runs in our component. Hence, we will use the OnInit event.

import { Component, OnInit } from '@angular/core';
import { HubConnection } from '@aspnet/signalr-client';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  private hubConnection: HubConnection;
  nick = '';
  message = '';
  messages: string[] = [];

  ngOnInit() {
    this.nick = window.prompt('Your name:', 'John');

    this.hubConnection = new HubConnection('http://localhost:5000/chat');

    this.hubConnection
      .start()
      .then(() => console.log('Connection started!'))
      .catch(err => console.log('Error while establishing connection :('));

    }
}

Notice the ngOnInit method. We are asking the user to enter his name and we store that inside of nick property that we created previously.

After that, we create the HubConnection object and try to establish the connection with the server.

Inside of that method, we will also add the listener for sendToAll event from the server:

this.hubConnection.on('sendToAll', (nick: string, receivedMessage: string) => {
  const text = `${nick}: ${receivedMessage}`;
  this.messages.push(text);
});

After the event is received, we get two parameters: nick and the message itself. Now we form the new string from these two parameters and we add it to our messages array on AppComponent.

Inside of AppComponent we also need a method for sending messages from client TO server. We will use it from our view and here is the code:

  public sendMessage(): void {
    this.hubConnection
      .invoke('sendToAll', this.nick, this.message)
      .catch(err => console.error(err));
  }

View

Now we need to set up the view. Since we plan to use the form element, we will import FormsModule in our AppModule. We will change the app.module.ts file.

We can now add the view to app.component.html:

<div id="main-container" style="text-align:center">
  <h1>
    <a href="https://dotnet4europeanhosting.hostforlife.eu/make-chat-using-as-net-core-signalr/" target="_new">
      Make Chat Using ASP.NET Core SignalR
    </a>
  </h1>

  <div class="container">
    <h2>Hello {{nick}}!</h2>
    <form (ngSubmit)="sendMessage()" #chatForm="ngForm">
      <div>
        <label for="message">Message</label>
        <input type="text" id="message" name="message" [(ngModel)]="message" required>
      </div>
      <button type="submit" id="sendmessage" [disabled]="!chatForm.valid">
        Send
      </button>
    </form>
  </div>

  <div class="container" *ngIf="messages.length > 0">
    <div *ngFor="let message of messages">
      <span>{{message}}</span>
    </div>
  </div>

</div>

The view has two main parts.

 

First is a container for sending messages with a form that consists of input and button for sending the message.

The second part is for listing the messages that we store inside of messages property on AppComponent. We push a new message to this array every time we get an event (message) from the ASP.NET Core SignalR server.

That’s all there is to it!



European ASP.NET Core Hosting :: How to Use AutoMapper in Asp.Net Core Application

clock December 10, 2019 11:46 by author Scott

This is only brief tutorial about how to use AutoMapper in Asp Net Core 3.0 application. Automapper is a very popular Object-to-Object mapping library that can be used to map objects.

How to use automapper in Asp.Net Core 3.0 application

Let’s see how to use automapper in Asp Net Core 3.0 application using a very simple example.

1. First step you need to do is please make sure you install Asp.net Core 3.0 application à Create a new project button à then choose “ASP.NET Core Web Application” template à click “Next” button and then enter your Project name. Please see the image below for further information

 

2. Install AutoMapper in Asp.Net Core 3.0 Application 

Now, in this step, we will install AutoMapper in our project. So, go to visual studio and then go to “Tools” from the menu and then select “NuGet Package Manager” and then choose “Manager NuGet Packages for Solution”. Now, go to “Browse” tab and then install this below package as you do see below in the screenshot.

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

3. Configure AutoMapper in Asp.net Core 3.0 Application

Go to project folder structure, and then go to Startup class and then add some changes as you do see below in the code file’s Line # 11 and Line # 26.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using AutoMapper;
namespace AspNetCore3AutoMapper
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddAutoMapper(typeof(Startup));
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });

        }
    }
}

4. Create a Model Class and Data Transfer Object Class

Now, in this step , we will create two classes. One is Model class and the other one is Dto(Data Transfer Object) class. So, go to Models’ folder and then right click on the folder name and then add a new class with the name of “Employee” and then write some properties as you do see below in the code.

public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
    }

Now, again add a new class with the name of “EmployeeDto” as you do see below in the file.

public class EmployeeDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
    }

5. Add relation of Employee class with EmployeeDto class

Now, in this step, we will see how to add relation between a domain class and a Dto class. So, again add a new class (E.g. AutoMapping.cs) and then write some code as you do see below in the code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;

namespace AspNetCoreAutoMapper.Models
{
    public class AutoMapping : Profile
    {
        public AutoMapping()
        {
            CreateMap<Employee, EmployeeDto>();
        }
    }
}

Let’s understand the above code.

Line # 9: In this line, we are inheriting AutoMapping class from Profile.

Line # 13: In this line, we are mapping our Employee and EmployeeDto Classes.

6. Map Employee class with EmployeeDto Controller

We will see how to map Employee class with EmployeeDto class within the Home Controller. So, go to HomeController and then go to Index method and then write some code as you do see below in the file.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using AspNetCore3AutoMapper.Models;
using AutoMapper;

namespace AspNetCore3AutoMapper.Controllers
{
    public class HomeController : Controller
    {
        private readonly IMapper _mapper;
        public HomeController(IMapper mapper)
        {
            _mapper = mapper;
        }
        public IActionResult Index()
        {
            var empObj = new Employee();
            empObj.Id = 1;
            empObj.Name = "Scott";
            empObj.Department = "MM";
            var employeeDto = _mapper.Map<EmployeeDto>(empObj);
            return View(employeeDto);
        }
    }
}

Let’s understand the above code.

Line # 15 to 19: In this block of code, we are injecting IMapper interface. This will help us to use our configured mappings.

Line # 22 to 25: In this block of code, we are initializing Employee object.

Line # 26: In this line, we are using IMapper interface that we have injected into our constructor to call the Map method. And we are giving the type that we want to map and the object that we want to map from.

Line # 27: In this line, we are returning the EmployeeDto object to the view.

Now, go to Index view and access the returning values from the Index method as you do see below in the file.

@model EmployeeDto
@{
    ViewData["Title"] = "Home Page";
}
<div>
    <h1>ID: @Model.Id</h1>
    <h1>Name: @Model.Name</h1>
    <h1>Department: @Model.Department</h1>
</div>

Now, run your project by pressing f5 and then you will see the output

Or you can install this package by using this below command in Package Manager Console as you do see below in the screenshot.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in