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 :: 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 Hosting :: Simple Steps to Migrate Your ASP.NET Core 2 to ASP.NET Core 3

clock October 25, 2019 07:18 by author Scott

.NET Core always interesting. In the past few months, we have just launched ASP.NET Core 2.2 on our hosting environment, and now Microsoft has support latest ASP.NET Core 3. This post will be taking the Contacts project used in the ASP.NET Basics series and migrating it from .NET Core 2.2 to .NET Core 3.0.

Installation

If you are a Visual Studio user you can get .NET Core 3.0 by installing at least Visual Studio 16.3. For those not using Visual Studio, you can download and install .NET Core 3.0 SDK from here. As with previous versions, the SDK is available for Windows, Linux, and Mac.

After installation is complete you can runt the following command from a command prompt to see all the versions of the .NET Core SDK you have installed.

dotnet --list-sdks

You should see 3.0.100 listed. If you are like me you might also see a few preview versions of the SDK that can be uninstalled at this point.

Project File Changes

Right-click on the project and select Edit projectName.csproj.

Change the TargetFramework to netcoreapp3.0.

Before:
<TargetFramework>netcoreapp2.2</TargetFramework>

After:
<TargetFramework>netcoreapp3.0</TargetFramework>

The packages section has a lot of changes. Microsoft.AspNetCore.App is now gone and part of .NET Core without needing a specific reference. The other thing to note is that Entity Framework Core is no longer “in the box” so you will see a lot of references add to make Entity Framework Core usable.

Before:
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />

After:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" PrivateAssets="All" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />

The last thing to note is that Swashbuckle doesn’t have a final version ready for .NET Core 3 so you will have to make sure you are using version 5 rc2 at a minimum.

The following is my full project file for reference.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
    <UserSecretsId>aspnet-Contacts-cd2c7b27-e79c-43c7-b3ef-1ecb04374b70</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" PrivateAssets="All" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
  </ItemGroup>
</Project>

Program Changes

In Program.cs some changes to the way the host is constructed. The over version may or may not have worked, but I created a new app and pulled this out of it just to make sure I’m using the current set up.

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Contacts
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                                          {
                                              webBuilder.UseStartup<Startup>();
                                          });
    }
}

Startup Changes

In Startup.cs we have quite a few changes to make. As long as you haven’t do any customization in the constructor you can replace it with the following.

public Startup(IConfiguration configuration)
{
        Configuration = configuration;
}

Next, they type on the configuration property changed from IConfigurationRoot to IConfiguration.

Before:
public IConfigurationRoot Configuration { get; }

After:
public IConfiguration Configuration { get; }

Moving on to the ConfigureServices function has a couple of changes to make. The first is a result of updating to the newer version of the Swagger package where the Info class has been replaced with OpenApiInfo.

Before:
services.AddSwaggerGen(c =>
{
        c.SwaggerDoc("v1", new Info { Title = "Contacts API", Version = "v1"});
});

After:
services.AddSwaggerGen(c =>
{
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "Contacts API", Version = "v1" })
});

Next, we are going to move from using UserMvc to the new AddControllersWithViews which is one of the new more targeted ways to add just the bits of the framework you need.

Before:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

After:
services.AddControllersWithViews();

Now in the Configure function, the function signature needs to be updated and the logging factory bits removed. If you do need to configure logging that should be handled as part of the HostBuilder.

Before:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
      loggerFactory.AddDebug();

After:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{

For the next set of changes, I’m just going to show the result and not the before. The UseCors may or may not apply but the addition of UserRouting and the replacement of UseMvc with UserEndpoint will if you want to use the new endpoint routing features.

app.UseStaticFiles();
app.UseRouting();
app.UseCors(builder =>
            {
                builder.AllowAnyHeader();
                builder.AllowAnyMethod();
                builder.AllowAnyOrigin();
            }
           );
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
                 {
                     endpoints.MapControllerRoute(
                                                  name: "default",
                                                  pattern: "{controller=Home}/{action=Index}/{id?}");
                     endpoints.MapRazorPages();
                 });

Other Miscellaneous Changes

The only other change I had was the removal of @using Microsoft.AspNetCore.Http.Authentication in a few cshtml files related to login.

 



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