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

European ASP.NET Core Hosting :: JWT Token Authentication

clock December 17, 2019 11:29 by author Peter

In web applications, security is essential. Say that the user wants to use the resources of our system. For that, we need to authenticate the user. Authentication means need to check whether the user is eligible to use the system or not. Generally, we do authentication via username (in the form of a unique user name or email ID) and a password. If the user is authenticated successfully, then we allow that user to use the resources of our system. But what about subsequent requests? If the user has been already identified then s/he does not need to provide credentials each time. Once authenticated, for a particular period s/he can use the system's resources. In a traditional approach, we used to save Username in Session. This session period is configurable, which means the session is valid for about 15 or 20 minutes. This session is stored in server's memory. After expiration of the session, the user needs to login again.

But here, there are couple of problems.

  1. The session can be hijacked.
  2. If we have multiple instances of server with load balancer, then if the request goes to a server other than the server which has authenticated the earlier request, then it will invalidate that session. Because the session is not distributed among all the servers, we have to use a 'Sticky' session; that is we need to send each subsequent request to the same server only. Here, we can also store session in database instead of the server's memory. In that case, we need to query the database each time, and that's extra work which may increase the overall latency.

To solve this problem, we can do authentication via JWT i.e. JSON web token. After successful authentication, the server will generate a security token and send it back to the client. This token can be generated using a symmetric key algorithm or an asymmetric key algorithm. On each subsequent request after a successful login, the client will send a generated token back to the server. The server will check whether the sent token is valid or not and also checks whether its expired or not. The client will send this token in Authentication Bearer header.

JWT token has a particular format. Header, Payload, and Signature.

  1. Header
    - We need to specify which token system we want to use and also need to specify the algorithm type.
  2. Payload
    - This is a token body. Basically, it contains expiry detail, claims details, issuer detail, etc.
  3. Signature
    - To create the signature part we have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

E.g. HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

Benefits of using JWT

  1. JSON parser is common in programming languages.
  2. Secure. We can use a Symmetric or Asymmetric key algorithm.
  3. Less verbose in comparison to SAML.

I have created an ASP.Net Core web API sample application. JWTAuthService is responsible for the generation and validation of token. Feel free to download and contribute to the code on Github.



European ASP.NET Core Hosting :: How to use AutoWrapper.Server?

clock December 4, 2019 11:16 by author Peter

If you are using AutoWrapper for generating a consistent Http response for your ASP.NET Core API's and you have some server-side applications (.NET Clients) that consume the Response, chances are you are forced to create a schema to properly deserialize the ApiResponse to your Model. The idea behind this project was based on community feedback by dazinator. It occurs to me as well that this might be a common scenario. Big thanks to dazinator!

AutoWrapper.Server is simple library that enables you unwrap the Result property of the AutoWrapper's ApiResponse object in your C# .NET Client code. The goal is to deserialize the Result object directly to your matching Model without having you to create the ApiResponse schema.

Installation
1) Download and Install the latest AutoWrapper.Server from NuGet or via CLI:
PM> Install-Package AutoWrapper.Server -Version 2.0.0 

2) Declare the following namespace in the class where you want to use it.
using AutoWrapper.Server; 

Sample Usage
[HttpGet] 
public async Task<IEnumerable<PersonDTO>> Get()   

    var client = HttpClientFactory.Create(); 
    var httpResponse = await client.GetAsync("https://localhost:5001/api/v1/persons"); 
 
    IEnumerable<PersonDTO> persons = null; 
    if (httpResponse.IsSuccessStatusCode) 
    { 
        var jsonString = await httpResponse.Content.ReadAsStringAsync(); 
        persons = Unwrapper.Unwrap<IEnumerable<PersonDTO>>(jsonString); 
    } 
 
    return persons; 


If you are using the [AutoWrapperPropertyMap] to replace the default Result property to something else like Payload, then you can use the following overload method below and pass the matching property:
Unwrapper.Unwrap<IEnumerable<PersonDTO>>(jsonString, "payload"); 


Using the UnwrappingResponseHandler

Alternatively you can use the UnwrappingResponseHandler like below:
[HttpGet] 
public async Task<IEnumerable<PersonDTO>> Get()   

    var client = HttpClientFactory.Create(new UnwrappingResponseHandler()); 
    var httpResponse = await client.GetAsync("https://localhost:5001/api/v1/persons"); 
 
    IEnumerable<PersonDTO> persons = null; 
    if (httpResponse.IsSuccessStatusCode) 
    { 
        var jsonString = await httpResponse.Content.ReadAsStringAsync(); 
        persons = JsonSerializer.Deserialize<IEnumerable<PersonDTO>>(jsonString); 
    } 
 
    return persons; 


You can also pass the matching property to the handler like in the following:

var client = HttpClientFactory.Create( new UnwrappingResponseHandler("payload")); 

That's it. If you used AutoWrapper or if you find this useful, please give it a star to show your support and share it to others.



European ASP.NET Core Hosting :: PopupBox For Debug Only

clock November 28, 2019 11:38 by author Peter

When debugging I feel a need to popup values from variables. I know that Visual Studio is cool but I feel the need to use it just typing. So I design an extension method to make it easy. You can add your custom objects, or Windows objects, and make a clause to show it or not. The message is shown only in DEBUG time.

See this sample,
using System; 
using System.Net.Mail; 
using System.Windows.Forms; 
 
namespace DebugPopup 

    public partial class FrmSample : Form 
    { 
        public FrmSample() => InitializeComponent(); 
 
        private void Form1_Load(object sender, EventArgs e) 
        { 
            var eml = new MailAddress("test@google.com", "test"); 
 
            eml.PopupBox(); 
 
            var n = 0; 
 
            n.PopupBox(); 
 
            Handle.PopupBox(); 
 
            decimal.Zero.PopupBox(n==0, "n is equals zero!"); 
         
        } 
 
        private void button1_Click(object sender, EventArgs e) 
        { 
            ((Button)sender).PopupBox(); 
        } 
    } 


It 's an extension method that you only need to add.PopupBox() from the Visual Studio property menu.
You can add custom types and the message will be shown only in DEBUG mode, I mean that in production there will be no message.

This is the main code,
using System.Windows.Forms; 
using System.Net.Mail; 
using System.Diagnostics; 
 
/// <summary> 
/// Author: Jefferson Saul G. Motta 
/// 10-24-2019 20:50 
/// Uses the System 
/// </summary> 
namespace System 

 
    /// <summary>   
    /// This is my real code that I make to debug easly 
    /// You can copy to .NET Core as Well 
    /// If you are debugging in a local IIS (ASP.NET WebForms) 
    /// The popup will raises too 
    /// C# 7.3 and C# 8.0 
    /// About extensions: http://www.c-sharpcorner.com/blogs/extension-method-in-c-sharp3 
    /// </summary> 
    public static class ExtensionMethodStrings 
    { 
 
         
        /// <summary> 
        /// Popup for int value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this int value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for decimal value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this decimal value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for IntPtr value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this IntPtr value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message);         
         
        /// <summary> 
        /// Popup for double value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this double value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for long value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this long value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
        /// <summary> 
        /// Popup for string value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this string value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
         
         
        /// <summary> 
        /// Popup for string value if contem a string 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="contem"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this string value, in string contem, in string message = "") => PopupIt($"Value: {value}", value.ContemUpper(contem), message);         
         
        /// <summary> 
        /// Popup for bool value 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="showIf"></param> 
        /// <param name="message"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this bool value, in bool showIf = true, in string message = "") => PopupIt($"Value: {value}", showIf, message); 
 
        /// <summary> 
        /// Check if exist comparing uppper text 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="text"></param> 
        /// <returns></returns> 
        private static bool ContemUpper(this string value, string text) => string.IsNullOrEmpty(value) || string.IsNullOrEmpty(text) ? false : value.ToUpper().IndexOf(text.ToUpper()) != -1; 
 
 
        /// <summary> 
        /// Sample 
        /// You can add another controls or objects 
        /// </summary> 
        /// <param name="button"></param> 
        /// <param name="showIf"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this Button button, in bool showIf = true) => PopupIt(button.Text, showIf); 
 
        /// <summary> 
        /// Sample 
        /// You can add another controls or objects 
        /// Test with MailAddress 
        /// </summary> 
        /// <param name="eml"></param> 
        /// <param name="showIf"></param> 
        /// <returns></returns> 
        public static bool PopupBox(this MailAddress eml, in bool showIf = true) => PopupIt(eml.Address, showIf); 
 
        /// <summary> 
        /// Add the label if value not is empty 
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="label"></param> 
        /// <returns></returns> 
        private static string LabelIfNotEmpty(this string value, string label) => string.IsNullOrEmpty(value) ? "" : $"{label}:{value}"; 
 
        /// <summary> 
        /// Show popup only for DEBUG 
        /// </summary> 
        /// <param name="message"></param> 
        /// <param name="showIf"></param> 
        /// <param name="messageExtra"></param> 
        /// <returns></returns> 
        private static bool PopupIt(string message, in bool showIf = true, in string messageExtra = "") 
 
#if (DEBUG) 
        { 
            // Show popup if true 
            if (showIf) 
            { 
                Debug.WriteLine($"{messageExtra.LabelIfNotEmpty("Extra message:")}{message}"); 
             
                // Optional: 
                MessageBox.Show($"{messageExtra.LabelIfNotEmpty("Extra message:")}{message}"); 
             
            } 
            // showIf  
            return showIf; 
        } 
#else 
            // on Releases returns false 
            => false; 
 
#endif 
 
    } 
 
}



European ASP.NET Core Hosting :: AutoWrapper Version 2.1.0 Released

clock November 12, 2019 10:42 by author Peter

AutoWrapper 2.1.0 has been released with newly features added based on community feedback. Here are the newly features added:

  • Added [AutoWrapIgnore] action filter attribute.
  • Added support to override non-success message when using IActionResult return types.
  • Added EnableResponseLogging and EnableExceptionLogging options to turn off auto logging.
  • Added UnAuthorize and BadRequest message for HandleNotSucessAsync() method response.

Using IActionResult Return Types
AutoWrapper now supports IActionResult return types that allows you to return non successful requests such as BadRequest, NotFound, UnAuthorize and etc.
For example:
[Route("{id:long}")] 
[HttpGet] 
public async Task<IActionResult> Get(long id)   

    var person = await _personManager.GetByIdAsync(id); 
    if (person != null) 
    { 
        return Ok(person); 
    } 
    else 
        return NotFound($"Record with id: { id } does not exist."); 


Another example such as:
return Unauthorized("Access token is invalid.");   
return BadRequest("SomeField is null.");   


AutoWrapIgnore Attribute
You can now use the [AutoWrapIgnore] filter attribute for enpoints that you don't want to be wrapped.
For example:
[HttpGet] 
[AutoWrapIgnore] 
public async Task<IActionResult> Get()   

    var data = await _personManager.GetAllAsync(); 
    return Ok(data); 


or
[HttpGet] 
[AutoWrapIgnore] 
public async Task<IEnumerable<Person>> Get()   

    return await _personManager.GetAllAsync(); 


Turn-off Default Logging
You can now turn off Logging by setting EnableResponseLogging and EnableExceptionLogging options to false in AutoWrapper options.
For example:
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions {   
              EnableResponseLogging = false,  
              EnableExceptionLogging = false  
}); 


That's it. Feel free to request an issue on github if you find bugs or request a new feature. Your valuable feedback is much appreciated to better improve this project. If you find this useful, please give it a star to show your support for this project.



European ASP.NET Core Hosting :: All About Sessions In ASP.NET Core

clock November 5, 2019 10:53 by author Peter

HTTP is a stateless protocol, so we need some mechanism to maintain our App State. Server Side Session has been a way to maintain our state on the server side. In this article we'll see what differences ASP.NET Core has introduced regarding SESSION.

We'll quickly discuss how we used to use Sessions before ASP.NET Core and then we'll see how to access Sessions in ASP.NET Core.

Session In Pre-ASP.NET Core era
You get Session functionality by default (without adding any package)
Previously, you would have accessed Session by -

    Session variable in your Controllers/Forms
    System.Web.HttpContext.Current.Session in places where you don't have direct access to the Session variable.

Anything you store in session is stored as Object. You store values in Key/Value format.

    Session["mydata"] = 10;  

Or to access on those places where Session is not available (e.g. Non-Controller classes)

    System.Web.HttpContext.Current.Session["mydata"] = 10;  

Quite difficult to mock Session Object for Unit Testing

Session in ASP.NET Core 2.2
Now, Session is not available by default.
You need to add the following package. Meta package by default provides you this.

    <PackageReference Include="Microsoft.AspNetCore.Session" Version="2.2.0" /> 
In Startup.ConfigureServices, you need to add the following to register services with DI Container.
    services.AddDistributedMemoryCache();//To Store session in Memory, This is default implementation of IDistributedCache   
    services.AddSession(); 

In Startup.Configure, you need to add the following (before UseMVC) to add Session Middleware.

    app.UseCookiePolicy();     
    app.UseSession();     
    app.UseMvc(routes =>   

Make sure the following is also there (It is added by default when you use ASP.NET Core MVC Template).

    app.UseCookiePolicy();  

ASP.NET Core 2.2 onwards adds Cookie Consent (true) in the Startup file. When an application runs, the user needs to accept Cookie Consent on screen. When the user accepts the policy on the page, it creates a consent cookie. It is to follow GDPR and to give control to the user if the user wants to store cookies from a site or not. If the user doesn't accept that, Session does not work because Session requires a cookie to send/receive session Id. You may face this issue while working with ASP.NET Core MVC default template.

How to access Session in Controller?

You will notice that you don't have "Session" variable available now. Controller now has a property "HttpContext" which has "Session" variable. So, you can access session in controller by using the following code.

var a = this.HttpContext.Session.GetString("login");   
HttpContext.Session.SetString("login", dto.Login); 


How to access Session in Non-Controller class?

Now, you don't have System.Web.HttpContext.Current.Session in ASP.NET Core. To access session in non-controller class -

First, register the following service in Startup.ConfigureServices;

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 

Now, register a class (example - TestManager) where you want to access the Session in Startup.ConfigureServices;
    services.AddScoped<TestManager>(); 
Note
You may use AddTransient or AddSingleton according to your logic.

Now, in TestManager class, add the following code.
    private readonly IHttpContextAccessor _httpContextAccessor;   
    private readonly ISession _session;   
    public TestManager(IHttpContextAccessor httpContextAccessor)   
       {   
            _httpContextAccessor = httpContextAccessor;   
            _session = _httpContextAccessor.HttpContext.Session;   
        } 


The above code is receiving IHttpContextAccessor object through dependency injection and then, it is storing Sessions in a local variable.

How to access Session in View file?

Add the following at the top of your View file.
@using Microsoft.AspNetCore.Http   
@inject IHttpContextAccessor httpContextAccessor  


Then, you may access the Session variable in your View like following.
@httpContextAccessor.HttpContext.Session.GetString("login")  

What else is changed regarding Session?

Session is non-locking now.
A session is not created until you have at least one value in it
You need to use functions to get & set data. Array syntax is not supported now.
Now, ISession only provides Get & Set method which takes & returns data in Byte Array format.
If you want to store data in the String format, you may add the following in your file and use extension methods.
    using Microsoft.AspNetCore.Http;  
It exposes the new extension methods.
    SetInt32   
    GetInt32   
    SetString   
    GetString   
Under the hood, these covert the data into bytes.

You may also write your own extension methods. For example, the following Extension Methods help you store & retrieve any complex type.
    public static class SessionExtensions       
        {       
            public static void Set<T>(this ISession session, string key, T value)       
            {       
                session.Set<(key, JsonConvert.SerializeObject(value));       
            }       
           
            public static T GetObject<T>(this ISession session, string key)       
            {       
                var value = session.GetString(key);       
                return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);       
            }       
        }  


In the next article, we'll learn about SESSION Wrapper Design Pattern.

Summary

Session concepts are similar to what we've seen in earlier .NET Frameworks. The real difference is that now, it is cleaner & more flexible to use.

 



European ASP.NET Core 3.1 Hosting - HostForLIFE.eu :: .NET Core Implementing .NET Core Health Checks

clock October 29, 2019 12:16 by author Peter

Generally, when we are using any uptime monitoring systems or load balancers, these systems will keep monitoring the health of the application and based on its health condition it will decide to send the request to serve it. For this earlier, we use to create a special endpoint where it will return any error message or code to indicate the health of the API/service.
 

Following is the sample, an endpoint /health where it verifying the database connection and returns the result accordingly.
    [Route("health")] 
    public ActionResult Health() 
    { 
        using (var connection = new SqlConnection(_connectionString)) 
        { 
            try 
            { 
                connection.Open(); 
            } 
            catch (SqlException) 
            { 
                return new HttpStatusCodeResult(503, "Database connection is unhealthy"); 
            } 
        } 
     
        return new EmptyResult(); 
    } 

When we ran the application with endpoint /health, it will display an empty message with 200 status code and 503 status code when there is any connectivity issue while connecting to the database.

Now, based on these resulted status codes, monitoring systems can take appropriate actions like removing this particular services instance from its list of healthy services so that no requests will be redirected to it until it becomes healthy (in our case, when database connectivity issue resolves).
 
We need to keep adding more external resource health checks accordingly.
 
Since .NET Core 2.2, we no need to add a special controller for health check endpoint, instead, the framework itself providing Health Check services as follows.
 
NuGet Package
You have to install following NuGet package
 
Install-Package Microsoft.Extensions.Diagnostics.HealthChecks
 
Once the package is installed, we need to add the following lines at ConfigureServices() and Configure() methods in Startup.cs file.
    public void ConfigureServices(IServiceCollection services) 
    { 
        services.AddHealthChecks(); 
    } 
      
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 
    { 
        app.UseHealthChecks("/Health"); 
    } 


As observed, we are providing the endpoint name in Configure() method. These lines of code will enable a dynamic endpoint "/Health" and display either Healthy/UnHealthy results based on its health state.
 
But, where can we write our custom logic to replicate the above? Yes, we have many features to customize our needs from logic to display results.
 
Adding Custom Logic
 
We can perform in two ways the following are those.
 
Option 1
 
In ConfigureServices method,
    public void ConfigureServices(IServiceCollection services) { 
     services.AddHealthChecks() 
      .AddCheck("sql", () => { 
     
       using(var connection = new SqlConnection(_connectionString)) { 
        try { 
         connection.Open(); 
        } catch (SqlException) { 
         return HealthCheckResult.Unhealthy(); 
        } 
       } 
     
       return HealthCheckResult.Healthy(); 
     
      }); 
    } 


Here, we can use an anonymous method to write the custom logic using AddCheck() method. This will expect a HealthCheckResult object as a result. This object will contain 3 options,
    Healthy
    Unhealthy
    Degraded

Based on the result we need to return appropriately so that runtime will return the status code accordingly. For example, in the above code, if database connection passes it will return a 200 status code (Healthy) and 503 status code (Unhealthy) if failed.
 
Option 2 - In a separate class
The class should implement an IHealthCheck interface and implement CheckHealthAsync() method as follows,
    public class DatabaseHealthCheck: IHealthCheck { 
     public Task < HealthCheckResult > CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = 
      default) { 
      using(var connection = new SqlConnection(_connectionString)) { 
       try { 
        connection.Open(); 
       } catch (SqlException) { 
        return HealthCheckResult.Healthy(); 
       } 
      } 
     
      return HealthCheckResult.Healthy(); 
     
     } 
    } 


Once we created the class, we need to mention this class in ConfigureServices() method using AddTask<T> method as follows by giving some valid unique names.
    public void ConfigureServices(IServiceCollection services) 
    { 
         services.AddControllers(); 
     
         services.AddHealthChecks() 
              .AddCheck<DatabaseHealthCheck>("sql"); 
    } 


Now, our code is clean and we can add any number of Health Tasks as above and it will be run in the order how we declared here.
 
Custom Status Code

As discussed above, by default it will send 200 status code if we return Healthy and 503 for Unhealthy. The Healthcheck service even provides scope for us to change this default behavior by providing custom status code using its options object as follows.
    var options = new HealthCheckOptions(); 
    options.ResultStatusCodes[HealthStatus.Unhealthy] = 420; 
    app.UseHealthChecks("/Health", options); 


In this example, I replace the status code for the Unhealthy state with 420.
 
Custom Response
The beauty of this tool is, we can even customize our output for more clear detailed information about each Health check task. This will be very useful in case we have multiple health check tasks to analyze which task made the complete service heath status to Unhealthy.
 
We can achieve this via HealthCheckOptions ResponseWriter property.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { 
     app.UseHealthChecks("/Health", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions() { 
      ResponseWriter = CustomResponseWriter 
     }); 
    } 
     
    private static Task CustomResponseWriter(HttpContext context, HealthReport healthReport) { 
     context.Response.ContentType = "application/json"; 
     
     var result = JsonConvert.SerializeObject(new { 
      status = healthReport.Status.ToString(), 
       errors = healthReport.Entries.Select(e => new { 
        key = e.Key, value = e.Value.Status.ToString() 
       }) 
     }); 
     return context.Response.WriteAsync(result); 
     
    } 


Now, the above code will display the result in JSON format will all the tasks information. Here, Key represents the Task name we have given (in our case "sql") and value is either Healthy/Unhealthy.
 
Health Check UI
We can even see the health check results on-screen visually by installing the following NuGet package
Install-Package AspNetCore.HealthChecks.UI
 
Once installed need to call respective service methods in ConfigureServices() and Configure() methods accordingly.
    public void ConfigureServices(IServiceCollection services) 
    { 
        services.AddHealthChecksUI(); 
    } 
     
    public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
    { 
        app.UseHealthChecksUI(); 
    } 

Once configured, you can run the application and point to /healthchecks-ui endpoint which display a UI as follows,



European ASP.NET Core 3 Hosting - HostForLIFE.eu :: ASP.NET Core Denial of Service Vulnerability

clock October 22, 2019 12:09 by author Peter

In this blog, we are going to discuss vulnerable versions of .Net Core. Microsoft releases the information about security breaches in ASP.Net Core. It informs developers which version they need to update to remove this vulnerability. Microsoft is aware of DOS Attack in the OData library. If you are using OData library in your application in the sense attacker can exploit.

We have two types of dependencies in .net core,

  • Direct dependencies
  • transitive dependencies

Direct dependencies are dependencies where you specifically add a package to your project, transitive dependencies occur when you add a package to your project that in turn relies on another package.

Mitigation policy
Open your application through visual studio and go to package manager console and run the below command.
command :-  dotnet --info 

By running the above command you will come to know which package we need to update as per Microsoft security guidelines.
 
Direct dependencies
By editing your Cs.proj file we can fix the issue or we can update Nuget Package manager.
 
Transitive dependencies
Transitive dependencies occur when any vulnerable package is referring or relies on another package. By examining the project.asset.json file you can fix the issue.

In this blog, we have discussed vulnerable versions of .Net Core. As per Microsoft security advice it is better to update packages which are in your application.



European ASP.NET Core Hosting :: Paging Using Repeater Control In ASP.NET With And Without Stored Procedure

clock October 16, 2019 11:06 by author Peter

By default, pagination is not enabled in a Repeater control. We have to write custom pager control to use paging in a Repeater control. Here, I will explain how to implement paging in Repeater control in ASP.NET with and without a stored procedure. I am using Visual Studio 2019 to create the application.

Step 1
First, we have to create a table “tblCustomers” to test the paging in the repeater control.
CREATE TABLE [dbo].[tblCustomers]( 
[Id] [int] NOT NULL, 
[Name] [nvarchar](50) NULL, 
[Company] [nvarchar](50) NULL, 
[Phone] [nvarchar](50) NULL, 
[Address] [nvarchar](50) NULL, 
[Country] [nvarchar](50) NULL, 
[Email] [nvarchar](50) NULL 


After creating the table, add some record to the table.

Step 2
Open Visual Studio and click on "Create a new project".
Select ASP.NET Web Application from templates and click on “Next”.
Then, give the project name as “AspRepeater” and then click “Create”.
Now, choose “Web Forms” from the template and click on “Create”.

ASP.NET Repeater Control without Stored Procedure

Step 3
Now, create a new weborm “RepeaterControl” and write the code following code in your “RepeaterControl.aspx” page.
Code for RepeaterControl.aspx page.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RepeaterControl.aspx.cs" Inherits=" AspRepeater.RepeaterControl" %> 

<!DOCTYPE html> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
<title>Repeater Control without Stored Procedure</title> 
</head> 
<body> 
<form id="form1" runat="server"> 
    <div> 
        <asp:Repeater ID="Repeater2" runat="server"> 
            <HeaderTemplate> 
                <table id="tbDetails" style="width: 100%; border-collapse: collapse;" border="1" cellpadding="5" cellspacing="0"> 
                    <tr style="background-color: lightgray; height: 30px; color: black; text-align: center"> 
                        <th>Id</th> 
                        <th>Customer Name</th> 
                        <th>Company Name</th> 
                        <th>Phone</th> 
                        <th>Address</th> 
                        <th>E-Mail</th> 
                    </tr> 
            </HeaderTemplate> 
            <ItemTemplate> 
                <tr style="height: 25px;"> 
                    <td> 
                        <%#Eval("Id").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Name").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Company").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Phone").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Address").ToString()%>, <%#Eval("Country").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Email").ToString()%> 
                    </td>                         
                </tr> 
            </ItemTemplate> 
            <FooterTemplate> 
                </table> 
            </FooterTemplate> 
        </asp:Repeater> 
    </div> 
    <br /> 
    <div style="text-align:center"> 
        <asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand"> 
            <ItemTemplate> 
                <asp:LinkButton ID="lnkPage" 
                    Style="padding: 8px; margin: 2px; background: lightgray; border: solid 1px #666; color: black; font-weight: bold" 
                    CommandName="Page" CommandArgument="<%# Container.DataItem %>" runat="server" Font-Bold="True"><%# Container.DataItem %> 
                </asp:LinkButton> 
            </ItemTemplate> 
        </asp:Repeater> 
    </div> 
</form> 
</body> 
</html> 


Code for RepeaterControl.aspx.cs,
using System; 
using System.Collections; 
using System.Configuration; 
using System.Data; 
using System.Data.SqlClient; 
using System.Web.UI.WebControls; 

namespace AspRepeater 

public partial class RepeaterControl : System.Web.UI.Page 
{  
    private int iPageSize = 15; 

    protected void Page_Load(object sender, EventArgs e) 
    { 
        if (!IsPostBack) 
        { 
            GetCustomers(); 
        } 
    } 

    private void GetCustomers() 
    { 
        DataTable dtData = new DataTable(); 
        string conString = ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString; 
        SqlConnection sqlCon = new SqlConnection(conString); 
        sqlCon.Open(); 
        SqlCommand sqlCmd = new SqlCommand("Select * From tblCustomers", sqlCon); 
        SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd); 
        sqlDa.Fill(dtData); 
        sqlCon.Close(); 

        PagedDataSource pdsData = new PagedDataSource(); 
        DataView dv = new DataView(dtData); 
        pdsData.DataSource = dv; 
        pdsData.AllowPaging = true; 
        pdsData.PageSize = iPageSize; 
        if (ViewState["PageNumber"] != null) 
            pdsData.CurrentPageIndex = Convert.ToInt32(ViewState["PageNumber"]); 
        else 
            pdsData.CurrentPageIndex = 0; 
        if (pdsData.PageCount > 1) 
        { 
            Repeater1.Visible = true; 
            ArrayList alPages = new ArrayList(); 
            for (int i = 1; i <= pdsData.PageCount; i++) 
                alPages.Add((i).ToString()); 
            Repeater1.DataSource = alPages; 
            Repeater1.DataBind(); 
        } 
        else 
        { 
            Repeater1.Visible = false; 
        } 
        Repeater2.DataSource = pdsData; 
        Repeater2.DataBind(); 
    } 
     
    protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e) 
    { 
        ViewState["PageNumber"] = Convert.ToInt32(e.CommandArgument); 
        GetCustomers(); 
    } 



ASP.NET Repeater Control with Stored Procedure

Step 4
By using a Stored Procedure, we can fetch only one-page records from the available records based on the page index. For example, if our table has 300 records and we need to display only 15 records per page, then we will fetch only 15 records based on the page index.

Script for the Stored Procedure,
CREATE PROCEDURE GetCustomer 
@PageIndex INT = 1, 
@PageSize INT = 15, 
@RecordCount INT OUTPUT 
AS 
BEGIN 
SET NOCOUNT ON; 
SELECT ROW_NUMBER() OVER(ORDER BY Id ASC)AS RowNumber,ID, 
Name,Company,Phone,Address,Country,Email 
INTO #Results FROM tblCustomers 
  
SELECT @RecordCount = COUNT(*) FROM #Results 
        
SELECT * FROM #Results WHERE RowNumber BETWEEN(@PageIndex -1) * @PageSize + 1  
AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1 
  
DROP TABLE #Results 
END 

Step 5
Now, create a new webform “RepeaterControl1” and write the following code in your “RepeaterControl1.aspx” page.

Code for RepeaterControl.aspx page.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RepeaterControl1.aspx.cs" Inherits="AspRepeater.RepeaterControl1" %> 

<!DOCTYPE html> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
<title>Repeater Control with Stored Procedure</title> 
</head> 
<body> 
<form id="form1" runat="server"> 
    <div> 
        <asp:Repeater ID="Repeater1" runat="server"> 
            <HeaderTemplate> 
                <table id="tbDetails" style="width: 100%; border-collapse: collapse;" border="1" cellpadding="5" cellspacing="0"> 
                    <tr style="background-color: lightgray; height: 30px; color: black; text-align: center"> 
                        <th>Id</th> 
                        <th>Customer Name</th> 
                        <th>Company Name</th> 
                        <th>Phone</th> 
                        <th>Address</th> 
                        <th>E-Mail</th> 
                    </tr> 
            </HeaderTemplate> 
            <ItemTemplate> 
                <tr style="height: 25px;"> 
                    <td> 
                        <%#Eval("Id").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Name").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Company").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Phone").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Address").ToString()%>, <%#Eval("Country").ToString()%> 
                    </td> 
                    <td> 
                        <%#Eval("Email").ToString()%> 
                    </td> 
                </tr> 
            </ItemTemplate> 
            <FooterTemplate> 
                </table> 
            </FooterTemplate> 
        </asp:Repeater> 
    </div> 
    <br /> 
    <div style="text-align:center"> 
        <asp:Repeater ID="Repeater2" runat="server" OnItemCommand="Repeater2_ItemCommand"> 
            <ItemTemplate> 
                <asp:LinkButton ID="lnkPage" 
                    Style="padding: 8px; margin: 2px; background: lightgray; border: solid 1px #666; color: black; font-weight: bold" 
                    CommandName="Page" CommandArgument="<%# Container.DataItem %>" runat="server" Font-Bold="True"><%# Container.DataItem %> 
                </asp:LinkButton> 
            </ItemTemplate> 
        </asp:Repeater> 
    </div> 
</form> 
</body> 
</html> 

Code for RepeaterControl1.aspx.cs.
using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Data; 
using System.Data.SqlClient; 
using System.Web.UI.WebControls; 

namespace AspRepeater 

public partial class RepeaterControl1 : System.Web.UI.Page 

    private int iPageSize = 15; 
    protected void Page_Load(object sender, EventArgs e) 
    { 
        if (!IsPostBack) 
        { 
            this.GetCustomers(1); 
        } 
    } 

    private void GetCustomers(int iPageIndex) 
    { 
        string conString = ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString; 
        SqlConnection sqlCon = new SqlConnection(conString); 
        sqlCon.Open(); 
        SqlCommand sqlCmd = new SqlCommand("GetCustomer", sqlCon); 
        sqlCmd.CommandType = CommandType.StoredProcedure; 
        sqlCmd.Parameters.AddWithValue("@PageIndex", iPageIndex); 
        sqlCmd.Parameters.AddWithValue("@PageSize", iPageSize); 
        sqlCmd.Parameters.Add("@RecordCount", SqlDbType.Int, 4); 
        sqlCmd.Parameters["@RecordCount"].Direction = ParameterDirection.Output; 
        IDataReader iDr = sqlCmd.ExecuteReader(); 
        Repeater1.DataSource = iDr; 
        Repeater1.DataBind(); 
        iDr.Close(); 
        sqlCon.Close(); 
        int iRecordCount = Convert.ToInt32(sqlCmd.Parameters["@RecordCount"].Value); 

        double dPageCount = (double)((decimal)iRecordCount / Convert.ToDecimal(iPageSize)); 
        int iPageCount = (int)Math.Ceiling(dPageCount); 
        List<ListItem> lPages = new List<ListItem>(); 
        if (iPageCount > 0) 
        { 
            for (int i = 1; i <= iPageCount; i++) 
                lPages.Add(new ListItem(i.ToString(), i.ToString(), i != iPageIndex)); 
        } 
        Repeater2.DataSource = lPages; 
        Repeater2.DataBind(); 
    } 

    protected void Repeater2_ItemCommand(object source, RepeaterCommandEventArgs e) 
    { 
        int iPageIndex = Convert.ToInt32(e.CommandArgument); 
        GetCustomers(iPageIndex); 
    } 

 



European ASP.NET Core Hosting :: TextBox Autocomplete with .NET Core 3.0

clock October 11, 2019 11:56 by author Peter

.NET Core 3.0 is the latest version of .NET Core and now supports WinForms and WPF. This sample shows how you can perform fill data to Autocomplete TextBox in another thread without slow down the main UI (User Interface). With this sample, you can do a better user experience for the end-user.

TextBox Autocomplete
Autocomplete helps the user to search/type from a know list. In my application, I build a list to Autocomplete with > 10.000 items and is very fast even on slow computers.

Autocomplete is an old feature, but this POST will demonstrate how to perform his use to load data fastly already in NET Core 3.0.

When you fill a Collection, if you have a huge suggestion list, this will make the UI (User Interface) freezes. But if you process in another thread the UI will not have any issues.

More technical information you can have here.

How it works

Like the other POST what uses a delegate, here, we use another thread to load data and delegate to bind the Autocomplete Collection in the current UI thread.
using System;  
using System.Data.SqlClient;  
using System.Drawing;  
using System.Windows.Forms;  
 
namespace TextBoxWithAutoComplete  
{  
 
    /// <summary>  
    /// 10-10-2019  
    /// </summary>  
    public partial class Form1 : Form  
    {  
 
        private TextBox textBox1;  
        public Form1()  
        {  
            InitializeComponent();  
 
            textBox1 = new TextBox  
            {  
                Location = new Point(0, 0),  
                Size = new Size(100, 32),  
                Visible = true,  
                TabIndex = 0  
            };  
            Controls.Add(textBox1);  
 
            Load += Form1_Load;  
        }  
 
        public void Form1_Load(object sender, EventArgs e)  
        {  
            Show(); // You need to show the form to avoid a thread error  
 
            LoadData(); // Start to load Data  
        }  
 
        private SqlConnection GetConnection()  
        {  
            // Init your connection  
            var oCnn = new SqlConnection  
            {  
                ConnectionString = "YOUR_CONNECTION_STRING"  
            };  
            oCnn.Open();  
            return oCnn;  
        }  
 
 
        #region TreadSafeLoading  
        private delegate void UpdateUIDelegate(AutoCompleteStringCollection myCollection);  
 
        /// <summary>  
        /// Load Data - You can make public to load as you need  
        /// </summary>  
        private void LoadData()  
        => // Start this process in a new thread  
            new System.Threading.Thread(() => OutOfThreadProcess()).Start();  
        // You can start others, every one in a new thread!  
 
        /// <summary>  
        /// Start fill in another Thread  
        /// </summary>  
        private void OutOfThreadProcess()  
        {  
            // inialize the collection  
            var myCollection = new AutoCompleteStringCollection();  
            using var oCnn = GetConnection();  
 
            // Start your SQL Query  
            var cmd = new SqlCommand($"Select [FirstName] + ' ' + [LastName] as [contactName] From [AdventureWorks].[Person].[Contact] Order By [FirstName], [LastName]", oCnn);  
 
            // Read and fill the collection  
            using var reader = cmd.ExecuteReader();  
            while (reader.Read())  
                myCollection.Add(reader.GetString(0));  
 
            // Invoke in a UI thread  
            _ = Invoke(new UpdateUIDelegate(UpdateUIInvoke), myCollection);  
        }  
 
        /// <summary>  
        /// Current UI Thread threatment  
        /// </summary>  
        /// <param name="myCollection"></param>  
        private void UpdateUIInvoke(AutoCompleteStringCollection myCollection)  
        {  
            // Setup up in corrent UI Thread  
            textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;  
            textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;  
            textBox1.AutoCompleteCustomSource = myCollection;  
#if (IS_TELERIK_RadTextBoxControl)  
            // If you use Telerik  
            // I found an issue in Telerik by Progress, without fix.  
            if (ParentForm != null)  
                ParentForm.FormClosing += new FormClosingEventHandler(UIFormClosing);  
#endif  
        }  
#if (IS_TELERIK_RadTextBoxControl)  
        private void UIFormClosing(object sender, FormClosingEventArgs e) => textBox1.AutoCompleteCustomSource = null;  
 
#endif  
        #endregion  
 
    }  
}  

Observation

When you use this technic may you receive errors if you run the new thread without fire the Show() method from the form, this occurs because the current window(form) hasn't the Handle initialized.

Conclusion
I design this technic when I upgrade to .NET Core 3 and develop a fix for the FileSystemWatcher event that fires in a new thread, so I took the same idea to make Autocomplete load collection works in a new thread.



ASP.NET 4.8 Hosting - HostForLIFE.eu :: Display SiteMap Links On ASP.NET Page

clock September 17, 2019 12:33 by author Peter

Create a sitemap sml based file and save it with sitemap.config name. Here is an example.
    <?xml version="1.0" encoding="utf-8" ?> 
    <siteMap> 
    <siteMapNode title="Home" controller="Home" action="Overview"> 
    <siteMapNode title="Dashboard" nopResource="Admin.Dashboard" controller="Home" action="Index" ImageUrl="~/Administration/Content/images/ico-dashboard.png" /> 
    <siteMapNode title="Catalog" nopResource="Admin.Catalog" PermissionNames="ManageCatalog" ImageUrl="~/Administration/Content/images/ico-catalog.png" > 
    <siteMapNode title="Categories" nopResource="Admin.Catalog.Categories"> 
    <siteMapNode title="List" nopResource="Admin.Common.List" controller="Category" action="List"/> 
    <siteMapNode title="Tree view" nopResource="Admin.Common.Treeview" controller="Category" action="Tree"/> 
    </siteMapNode> 
    </siteMap> 


If you're new to sitemap, learn here how to create a site map in Visual Studio.
 
To bind above sitemap and display on a page, please follow the below code example.
    @using System.Data; 
    @using System; 
    <div class="page-title"> 
    <h2>"Sitemap"</h2> 
    </div> 
    @{ 
    string fileName = System.Web.HttpContext.Current.Server.MapPath("~/sitemap.config"); 
    DataSet ds = new DataSet(); 
    ds.ReadXml(fileName); 
    <table> 
    <tr> 
    <td width="20%"></td> 
    <td style="border: 2px double #CCCCCC; padding-left: 50px;" width="30%"> 
    @for(int i=1;i<ds.Tables[0].Rows.Count/2;i++) 
    { 
    if(ds.Tables[0].Rows[i]["action"].ToString()=="") 
    { 
    <h4>@ds.Tables[0].Rows[i]["title"].ToString()</h4> 
    } 
    else 
    { 
    string url = "../" + @ds.Tables[0].Rows[i]["controller"].ToString() + "/" + @ds.Tables[0].Rows[i]["action"].ToString(); 
    <ul class="top-menu"><li><a href="@url" temp_href="@url">@ds.Tables[0].Rows[i]["title"].ToString()</a></li></ul> 
    } 
    } 
    </td> 
    <td style="border: 2px double #CCCCCC; padding-left: 50px;" width="30%"> 
    @for (int i = ds.Tables[0].Rows.Count / 2; i < ds.Tables[0].Rows.Count; i++) 
    { 
    if(ds.Tables[0].Rows[i]["action"].ToString()=="") 
    { 
    <h4>@ds.Tables[0].Rows[i]["title"].ToString()</h4> 
    } 
    else 
    { 
    string url = "../" + @ds.Tables[0].Rows[i]["controller"].ToString() + "/" + @ds.Tables[0].Rows[i]["action"].ToString(); 
    <ul class="top-menu"><li><a href="@url" temp_href="@url">@ds.Tables[0].Rows[i]["title"].ToString()</a></li></ul> 
    } 
    } 
    </td> 
    </tr> 
    </table> 
    } 


Run application and you'll see a page with sitemap links.

HostForLIFE.eu ASP.NET 4.8 Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



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