Friday 6 December 2019

Host two websites under same domain, which has different versions of Entity Framework package installed

We do have two websites which we need to host it under a same domain name , So for this we normally create a website and inside that we will be creating a new application for the child



This is not a big deal , but if we have packages with different versions installed in the websites then we will be getting a version conflict error. 

Example in our OLDProject we do have EF version 4x and NewProject has EF version 6x 
Then we will be getting an exception like 

Since we have an EF section in the OLDProject we dont need to add the EF section in NewProject 

What we need to do is remove the EF section from NewProject(Child) Then add a Assembly Redirect 

Comment below line ( Version may differ in your case 
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
Then Add an assembly redirect like below 
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="6.0.0.0" />
      </dependentAssembly>
       </assemblyBinding>
 </runtime>

Thursday 5 December 2019

How to to use IHostingEnvironment in .net core class library?

Normally IHostingEnvironment will not be available in the class library. But its available in the Nuget as a package .

IHostingEnvironment  is part of Microsoft.AspNetCore.Hosting.Abstractions.dll

Install IHostingEnvironment  from Nuget package

Install-Package Microsoft.AspNetCore.Hosting

Then we are free to use the IHostingEnvironment  in class libraries also.


Warning
This API is now obsolete.
This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.AspNetCore.Hosting.IWebHostEnvironment.

Monday 2 December 2019

Configure Swagger UI in Web API


Swagger UI

Swagger is the largest framework for designing APIs using a common language and enabling the development across the whole API lifecycle, including documentation, design, testing, and deployment.
The framework provides a set of tools that help programmers generate client or server code and install self-generated documentation for web services.
However, there are many other frameworks like RAML, API Blueprint, Summation, etc. So, how to explain the huge popularity of Swagger? The answer is that it offers a lot of advantages and besides creating clear documentation provides other great things.
Swagger -Advantages


Ø  Swagger uses a common language that everyone can understand, it’s easily comprehensible for both developers and non-developers.
Ø  Swagger is easily adjustable, it can be successfully used for API testing and bug fixing

Ø  Swagger provides a set of great tools for designing APIs and improving the work with web services:

Ø  Generate Beautiful and Interactive Documentation

             Publish and Market your API



Different swagger tools

Ø    Swagger Editor – enables to write API documentation, design and describe new APIs, and edit the existing ones. The first open-source editor visually renders OAS/Swagger definition with error handling and real-time feedback.
Ø    Swagger Codegen – allows developers to generate client library code for different platforms. As the tool helps facilitate the dev process by generating server stubs and client SDKs, software engineers get the ability to faster build your API and better focus on its adoption.
Ø   Swagger UI – allows engineers to get self-generated documentation for different platforms. Swagger UI is a fully customizable tool that can be hosted in any environment. A great plus is that it enables developers to save a lot of time for API documentation.
Ø   Swagger Inspector – a tool for testing and auto-generating OpenAPI documentation for any API. Swagger Inspector allows to easily validate and test APIs with no limits on what you test. Tests are automatically saved in the cloud with a simple access.


Swagger UI Configuration:


Step 1: Create a web api project (Preferably you can opt template provided by Microsoft-scaffolding).



Step 2: Add swagger from Nuget package



Step 3: Check your solution you can see a SwaggerConfig.cs file inside App_Start folder.




Step 4: Open the SwaggerConfig file and uncomment below line

c.IncludeXmlComments(GetXmlCommentsPath());

Step 5: Include the method GetXmlCommentsPath in the file
 
private static string GetXmlCommentsPath()
        {
            return String.Format(@"{0}\App_Data/XmlDocument.xml", System.AppDomain.CurrentDomain.BaseDirectory);
        }

Note: There any many configuration changes you can do with swagger config look into the commented lines or swagger config or visit https://swagger.io/ for better understanding.

Step 6: Enable summary comments for the project



Uncomment below line from Areas->App_Start->HelpPageConfig.cs

config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));

Step 7: Add the summary comment xml file path in the project properties



Note: If you are using a project without scaffolding template, or if you need more idea on the help page summary comments then visit

https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/creating-api-help-pages

Step 8: Add a link for swagger UI







Step 9: Run your project and click on the Swagger link you can see the swagger UI

Note: If you want to enable custom headers are authentication headers in the Swagger UI then you create a filter like below for doing the same
public class AddAuthorizationHeaderParameterOperationFilter : IOperationFilter
    {
        public void Apply(Swashbuckle.Swagger.Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            if (operation.parameters != null)
            {
                operation.parameters.Add(new Parameter
                {
                    name = "Authorization",
                    @in = "header",
                    description = "access token",
                    required = false,
                    type = "string"
                });
                operation.parameters.Add(new Parameter
                {
                    name = "currentLanguage",
                    @in = "header",
                    description = "Current language",
                    required = false,
                    type = "string"
                });
            }
        }
    }

You can check the JWT reusable component (The one available in the reusable component factory) for working demo

  

Global Response Wrapper for Web API


When working with ASP.Net Web API, it is important to return a consistent response for all the requests that are processed by your API regardless of success or failure.
When retrieving data with a GET, your response body will contain data. This may be an array for multiple records (e.g. GET /products) or a single object (e.g. GET /products/42). A POST may not return a response body at all and instead use an HTTP Header to point the user to the newly created resource. If your service needs to return an error then the in-built error handling will return an object with a message property exposing the error message. In each of these cases, we are returning very different data to the client. Depending on your client, this can make it very difficult to consume your service. 

Delegating handlers are extremely useful for situations like above. They hook into the very early and very late stages of the request-response pipeline making them ideal for manipulating the response right before it is sent back to the client. 

Implementation:

Step 1: Create a Webapi project.

Step 2: Create a generic class for response.

Example:

namespace Core.Model.Common
{
    using System.Net;
    using System.Runtime.Serialization;
    /// <summary>
    /// APi global response wrapper template
    /// </summary>
    [DataContract]
    public class ApiResponse
    {
        /// <summary>
        /// Version number
        /// </summary>
        [DataMember]
        public string Version { get { return "1.0.0"; } }
        /// <summary>
        /// Status code
        /// </summary>
        [DataMember]
        public int StatusCode { get; set; }
        /// <summary>
        /// Error message
        /// </summary>
        [DataMember(EmitDefaultValue = false)]
        public string ErrorMessage { get; set; }
        /// <summary>
        /// Result
        /// </summary>
        [DataMember(EmitDefaultValue = false)]
        public object Result { get; set; }
        /// <summary>
        /// The Response constructor
        /// </summary>
        /// <param name="statusCode"></param>
        /// <param name="result"></param>
        /// <param name="errorMessage"></param>
        public ApiResponse(HttpStatusCode statusCode, object result = null, string errorMessage = null)
        {
            StatusCode = (int)statusCode;
            Result = result;
            ErrorMessage = errorMessage;
        }
    }
}

Step 3: Create a message handler and override SendAsync method.


    public class GlobalResponseWrappingHandler : DelegatingHandler
    {
        /// <summary>
        /// Send async overiride for message handler
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            //Bypass if request is from swagger ui
            if (request.RequestUri.AbsolutePath.ToLower().Contains("swagger"))
            {
                return await base.SendAsync(request, cancellationToken);
            }
            else
            {
                var response = await base.SendAsync(request, cancellationToken);

                return BuildApiResponse(request, response);
            }
        }
        /// <summary>
        /// Build api response with custom response class
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        private static HttpResponseMessage BuildApiResponse(HttpRequestMessage request, HttpResponseMessage response)
        {
            object content;
            string errorMessage = null;

            if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode)
            {
                HttpError error = content as HttpError;

                if (error != null)
                {
                    content = null;
                    errorMessage = error.Message;

#if DEBUG
                    errorMessage = string.Concat(errorMessage, error.ExceptionMessage, error.StackTrace);
#endif
                }
            }

            var newResponse = request.CreateResponse(response.StatusCode, new ApiResponse(response.StatusCode, content, errorMessage));

            foreach (var header in response.Headers)
            {
                newResponse.Headers.Add(header.Key, header.Value);
            }

            return newResponse;
        }

    }

Step 4: Register the message handler in webapi config

var config = GlobalConfiguration.Configuration;
            config.MessageHandlers.Add(new GlobalResponseWrappingHandler());


Step 5: Add the below lines in Application_Start


var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

Step 6: Run the project.