Enter any website URL to analyze its complete technology stack

Executive Summary for devexpressocom.wordpress.com

524 Response Time (ms)
200 HTTP Status
33 Scripts
167 Images
20 Links
HTTP/1.1 Protocol

SEO & Content Analysis

Basic Information
Page Title
Devexpresso – Where Knowledge Has No Limits
Meta Description
Where Knowledge Has No Limits
HTML Language
en
Robots.txt Present
Sitemap Present
total_urls: 75 blog_posts: 1
SEO Meta Tags
content-type: text/html; charset=UTF-8
Page Content

Devexpresso – Where Knowledge Has No Limits

Migration aspect is a major decision and not always it follows a green field path. There can be numerous reasons for taking up the decision to migrate an application codebase from its legacy form to future state or performing database migration or even infrastructure migration from on-premise to cloud. All migration aspects turns out to be a major disaster if proper strategies are not defined and lack efficient guidelines and resource management.Anyway, this post emphasize on carrying out the migration aspect of our sample ASP.NET Web API solution that we had build earlier to ASP.NET Core. However, as the approach will follow a migration aspect with few basic core changes, I will not emphasize it as one of the green field project. Every migration aspect differ with its own set of issues and options to handle them.Why migrating to .NET CoreDefinitely this one is a good question that we developers bear in our mind knowing the fact that the existing codebase suffice our business needs and is in much stable state. It’s like asking someone who is looking forward to upgrade his four wheeler from a sedan to suv. Well, the relevant answer you might get is to gain more flexibility, power and adaptable features. Same kind of thoughts goes here too when you would like to migrate an application build on .NET framework to .NET core.Few of the parameters that come to my mind for this migration are like better testability of application, ability to run on any platform and not restricted to windows only, easily available for cloud deployment and leveraging configuration management, ability to host anywhere and lightweight with high performance. Having said that, let us look into the migration aspect of the application.Is there any migration tool Honestly, as far as I know we don’t have any specific migration tool that can help you to migrate the whole application to .NET core. This has to follow step-by-step strategic approach. However, my initial approach would be to use .NET Portability Analyzer, that can be used to identify the compatibility of the migration approach. You can either download the tool or add it from visual studio extensions. Let’s look into that first and see what the analyzer gives us.We will first search for .NET Portability Analyzer from Visual Studio extensions and download it.Once installed, right-click the solution and select Portability Analyzer Settings, which will give you the configuration management tool for the Analyzer. In this tool you can define the output directory where the analyzed report will get generated, output format of the report (XLS, HTML or JSON) and the Target Platforms to where you want the codebase to get migrated which for us would be .NET Core 2.1 and .NET Standard.Now, as best practice one thing that I am sure you know is that all class libraries should be converted to .NET Standard instead of .NET Core. The only reason for doing this is because, many external or 3rd party libraries like Newtonsoft.JSON support .NET Standard rather than .NET core. And moreover .NET Standard is lower than .NET core hence it is compatible to .NET Core version.Since I have only one API project in my solution and I want to migrate it to ASP.NET Core, hence I will select on ASP.NET Core as my target framework for portability analysisOnce the settings are done, go ahead and right click the API project and select Analyze Project Portability, to start the analysis.Once the analysis is complete, you can review the output generated in HTML or Excel format like shown here.Based on the report, most highlighting factors or rather assemblies that .NET Core is not supporting are –System.Configuration.ConfigurationManagerSystem.Net.Http.Formatting.MediaTypeFormatterSystem.Net.HttpSystem.Web.HttpSystem.Web.MvcSystem.Web.RoutingSince this was the report generated for Web API, a few non-compatible assemblies are listed. If you have a complex project with various class libraries and 3rd party libraries, you might see a different result altogether. At the end of this post, I will try to provide some of the incompatible libraries that I had encountered in a real time project conversion and the alternate usage in .NET Core.Starting the migration aspectThe portable analysis report will provide only few details to get started. However, it might not cover everything which you might encounter during compilation or execution phase of the converted application.Since we don’t have any migration utility available yet, our first step would be to create a fresh new solution having same number of projects as in .NET framework application but targeting to ASP.NET Core 2.1 and .NET Standard (higher version).What if I have complex structure having multiple class libraries along with API projectWell in this case you need to start step-by-step conversion process by creating related class libraries and dependencies targeting to .NET Standard (higher version). Copy the codebase from original solution to your libraries. Fix all the compatibility issues for .NET Standard. Once this phase is complete, you can add references of these dependencies to your new ASP.NET Core 2.1 project.Structural differences between the API projectThere is a significant structural differences between the API project developed with .NET Framework and .NET Core                      Let us identify some of the significant differences between these two applications.Startup.cs – This class defines the request handling pipeline and services that need to be configuredTypically in ASP.NET MVC, we have the startup class in App_Start, which get triggered when the application is launched and initialize the pipeline. This is only required if you are handling any Katana/OWIN functionality for the MVC or WebAPI app and hence it is optional. But in case of ASP.NET Core, this class is must to have and is generated by default.If you look into this class, there are three major components –Configure method to create application request processing pipeline where IApplicationBuilder used for configuring the request pipeline and IHostingEnvironment used to provide web hosting environment information is injected. If you have Swagger implemented, then this is the place where you are going to configure the Swagger endpoint.ConfigureServices method used to configure the application services by injecting IServiceCollection which specifies the contracts for service descriptors. IServiceCollection is under the namespace Microsoft.Extensions.DependencyInjection which helps services to resolve using inbuild dependency injection.IConfiguration which is followed by constructor injection of the Startup class, used to read the configuration properties represented by key/value pair[csharp]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.AddSingleton<IConfigurationProvider<Employee>, EmployeeProvider>();services.AddSingleton<IConfigurationProvider<Project>, ProjectProvider>();services.AddSingleton<IConfigurationProvider<Department>, DepartmentProvider>();services.AddSingleton<IConfigurationProvider<Client>, ClientProvider>();services.AddSingleton<IConfigurationProvider<Skills>, SkillProvider>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);services.AddSwaggerGen(c =>{c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Title = "EmployeeManagementApi", Version = "v1" });c.IncludeXmlComments(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EmployeeManagement.Api.xml"));c.ResolveConflictingActions(apidescription => apidescription.First());c.DescribeAllEnumsAsStrings();});services.AddMediatR(typeof(Startup));services.AddScoped<IMediator, Mediator>();services.AddMediatorHandlers(typeof(Startup).GetTypeInfo().Assembly);} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();} app.UseSwagger();app.UseStaticFiles();app.UseSwaggerUI(c =>{c.SwaggerEndpoint("/swagger/v1/swagger.json", "Employee Managament Api");c.RoutePrefix = string.Empty;}); app.UseMvc();} }[/csharp]Configuration files for ASP.NET CoreIn ASP.NET MVC, we provide all our application configuration settings in web.config file. However, in case of ASP.NET Core we provide these settings in JSON format in appsettings.json file which is placed to the root of the Api project.[csharp]{"Logging": {"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*","AppSettings": {"endpoint": "https://localhost:8081/&quot;,"authKey": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==","database": "empmanagement","collection": "employee"}}[/csharp]For me, the json file has only few keys like endpoint to Cosmos DB, authKey for Cosmos DB, database and collection key/value pairs.Another file which is important to look into is launchSettings.json file, which contains the information of how and where we are going to run the application. We can configure settings for various environments like Development, Staging and Production along with the information of how to run the application in local IIS express or from IIS Server.  This file is also in JSON format.[csharp]{"iisSettings": {"windowsAuthentication": false,"anonymousAuthentication": true,"iisExpress": {"applicationUrl": "http://localhost:1789&quot;,"sslPort": 0}},"$schema": "http://json.schemastore.org/launchsettings.json&quot;,"profiles": {"IIS Express": {"commandName": "IISExpress","launchBrowser": true,"environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"}},"EmployeeManagement.Api": {"commandName": "Project","launchBrowser": true,"launchUrl": "api/values","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"},"applicationUrl": "http://localhost:5000&quot;},"Docker": {"commandName": "Docker","launchBrowser": true,"launchUrl": "{Scheme}://{ServiceHost}"}}}[/csharp]Implement Exception Error Handling in ASP.NET CoreSystem.Web.Mvc.HandleErrorAttribute which is responsible to handle any exception thrown by an action method in asp.net mvc is not support in asp.net core.In this case we can use create a custom exception filter that is derived from ExceptionFilterAttribute class of Microsoft.AspNetCore.Mvc.Filters namespace which runs asynchronously when an exception is thrown. We can have an ApplicationLogging class which will have an instance of ILoggerFactory from Microsoft.Extensions.Logging namespace, that support API logging using third party logging providers like NLog or Log4Net. This logging class use it in the custom exception filter which tells the appl ication where to log.[csharp]public static class ApplicationLogging{public static ILoggerFactory LoggerFactory { get; } = new LoggerFactory();public static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();}[/csharp][csharp]public class CustomExceptionFilterAttribute : ExceptionFilterAttribute{ILogger Logger { get; } = ApplicationLogging.CreateLogger<CustomExceptionFilterAttribute>();// to tell where we log public override void OnException(ExceptionContext context){using (Logger.BeginScope($"=>{ nameof(OnException) }")) // to tell which method we log{Logger.LogInformation("Log Message"); // to tell what exception we log}}}[/csharp]You then use the custom exception filter attribute created for your controllers.[csharp][Produces("application/json")][Route("api/[controller]/[action]")][ApiController][CustomExceptionFilter]public class SkillController : ControllerBase{private readonly IConfigurationProvider<Skills> _provider;private readonly IMediator _mediator;}[/csharp]You can also use Microsoft.IdentityModel.Logging for implementing logging capabilities by installing the nuget package and overriding the OnException() method in custom exception filter class.[powershell]Install-Package Microsoft.IdentityModel.Logging -Version 5.3.0[/powershell][csharp]public override void OnException(ExceptionContext context){Microsoft.IdentityModel.Logging.LogHelper.LogExceptionMessage(context.Exception);}[/csharp]I am not covering much over here on exception handling as this should be a different post. Just an insight of the issues that we can encounter and the alternatives to fix them.Using Configuration Manager in ASP.NET CoreMostly when we try to retrieve values from configuration files like Web.config or App.config, we generally use ConfigurationManager, to get the values from appSettings. However, since System.Configuration.ConfigurationManager is not supported in .NET Core, we cannot use it. The workaround here is to install the package[powershell]Install-Package System.Configuration.ConfigurationManager -Version 4.5.0[/powershell]Now, in case of .NET Core we are supposed to read the values from appSettings.json file instead of any web.config or app.config file. In order to do that, we can create a static helper class like ConfigurationResolver.[csharp]public static class ConfigurationResolver{ public static IConfiguration Configuration(){string basePath = AppContext.BaseDirectory;var configuration = new ConfigurationBuilder().SetBasePath(basePath).AddJsonFile("AppSettings.json", optional: true, reloadOnChange: true).AddJsonFile("AppSettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true).Build();return configuration;}}[/csharp]And then you can use the helper class like this[csharp]private static IConfiguration Configuration;public static void Main(){Configuration = ConfigurationResolver.Configuration();DatabaseId = Configuration.GetSection("AppSettings").GetSection("database").Value;}[/csharp]Unavailability of System.Web.Http in ASP.NET CoreThis limitation of not having System.Web.Http in .NET Core gives us a lot of issues where most of the code base had been using libraries and references belonging to this namespace.For example, ApiParameterDescription or ApiDescription which belongs to System.Web.Http.Description and which gives metadata description of an input to API.In order to implement this, we need to install the package ApiExplorer[powershell]Install-Package Microsoft.AspNetCore.Mvc.ApiExplorer -Version 2.1.2[/powershell]Once the package has been installed successfully, we can use most of the functionalitiesDefining routes in ASP.NET CoreConfiguring routes using MapHttpRoute is not supported in .NET Core. You can define the default routes in Startup.cs file[csharp]public class Startup{public void ConfigureServices(IServiceCollection services){services.AddMvc();} public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseMvc(routes =>{//New Routeroutes.MapRoute(name: "about-route",template: "about",defaults: new { controller = "Home", action = "About" }); routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");});}}[/csharp]System.Web.Mvc in ASP.NET CoreSystem.Web.Mvc.Controller is not supported in .NET Core. However, you can install the package Microsoft.AspNetCore.Mvc as an alternative to serve your purpose.[powershell]Install-Package Microsoft.AspNetCore.Mvc -Version 2.1.2[/powershell]Enabling Swagger capabilities in ASP.NET CoreSwagger is an elegant way to provide API documentation. For that you need to install the package Swashbuckle.AspNetCore. Once installed, you need to update your Startup.cs file to provide the swagger endpoint and add it to the service collection.[csharp]public class Startup{public void ConfigureServices(IServiceCollection services){services.AddMvc();services.AddSwaggerGen(c =>{c.SwaggerDoc("v1", new Info { Title = "SampleApi", Version = "v1" });c.IncludeXmlComments(GetXmlCommentsPath());c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());c.DescribeAllEnumsAsStrings();});} public void Configure(IApplicationBuilder app, IHostingEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseSwagger();app.UseStaticFiles();app.UseSwaggerUI(c =>{c.SwaggerEndpoint("/swagger/v1/swagger.json", "Sample API V1");c.RoutePrefix = string.Empty;}); app.UseMvc();} private string GetXmlCommentsPath(){return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Sample.Api.xml");}}[/csharp]Change your appSettings.json file to provide the launchUrl to Index.html which will open the endpoint to Swagger[csharp]"profiles": {"IIS Express": {"commandName": "IISExpress","launchBrowser": true,"launchUrl": "index.html","environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"}}[/csharp]In your controller and action methods, you can add the following attributes.[csharp][Produces("application/json")][Route("api/[controller]/[action]")]public class ClientController : Controller{/// Your block of code}[HttpPost()][ActionName("GetClient")][ProducesResponseType(typeof(ClientRequest), 200)][ProducesResponseType(typeof(void), 400)][ProducesResponseType(typeof(void), 404)]public async Task<IActionResult> GetClient(ClientRequest clientRequest){/// Your block of code}[/csharp]Dependency Injection using StructureMap in ASP.NET CoreAs dependency injection is in-build in .NET Core, you don’t need StructureMap here. If you old code has referred to StructureMapDependencyResolver and StructureMapScope, these has been deprecated and cannot be used since .NET Core doesn’t support System.Web.Http and System.Web.Http.Dependencies.You can use IServiceCollection to add all the dependencies required in StartUp.cs file[csharp]public void ConfigureServices(IServiceCollection services){services.AddSingleton<IClientProvider, ClientProvider>();services.AddSingleton<IProjectProvider, ProjectProvider>(); var container = new Container();container.Configure(config =>{config.Populate(services);});}[/csharp]RestSharp library in .NET CoreIf you are using RestSharp library, for .NET Core you need to install the nuget package RestSharp.NetCore and then create an extension to RestClient[csharp]public static class RestClientExtensions{public static async Task<RestResponse> ExecuteAsync(this RestClient client, RestRequest request){TaskCompletionSource<IRestResponse> taskCompletion = new TaskCompletionSource<IRestResponse>();RestRequestAsyncHandle handle = client.ExecuteAsync(request, r => taskCompletion.SetResult(r));return (RestResponse)(await taskCompletion.Task); }}[/csharp]Change the implementation of RestSharp in your helper class or wherever you are using it.[csharp]public static async Task<IRestResponse> ExecuteAsync(string apiUrl, string request){try{var client = new RestClient(apiUrl);var apiRequest = new RestRequest(Method.POST);apiRequest.AddHeader("Content-Type", "application/json");apiRequest.AddHeader("Accept", "application/json");apiRequest.RequestFormat = DataFormat.Json;client.Timeout = 120000;apiRequest.AddParameter("application/json", request, ParameterType.RequestBody);return await client.ExecuteAsync(apiRequest);}catch (Exception ex){throw;}}[/csharp]If you are using StatusCode and Content of Response object, change response.StatusCode == HttpStatusCode.OK to response.Result.StatusCode == HttpStatusCode.OK and response.Content to response.Result.ContentDataAnnotations in .NET CoreSystem.ComponentModel.DataAnnotations has been replaced by System.ComponentModel.Annotations. Add this from the nuget package.Few more unsupported libraries and best practices in .NET CoreInstall the nuget package Microsoft.AspNetCore.Http.Abstractions for using StatusCodes in your action methods[csharp][HttpGet][ActionName("GetAllClients")]public async Task<IActionResult> GetAllClients(){try{var response = await _mediator.Send(new GetAllClientsQuery());return StatusCode(response.ResponseStatusCode, response.Value);}catch (Exception ex){return StatusCode(StatusCodes.Status500InternalServerError, ex);}}[/csharp]Remove JavaScriptSerializer() since System.Web.Script.Serialization under System.Web.Extensions is no longer supported in .NET CoreAdding WCF services built with previous versions of .NET Framework are not supported. You need to modify the services to .NET Core.Also, if you are trying to add the service into a .NET Core 2.1 application, you might encounter issues which states “An unknown error occurred while invoking the service metadata component. Failed to generate service reference.” Modify the application to .NET Core 2.0 version from 2.1 and it will work.Well pretty much, I have covered only few of the issues and workaround during .NET Core migration. Obviously, this is not covering everything but hopefully, these pointers might help you at some stage.I do have a plan to post various methodologies and in-depth programming strategies with .NET Core in my future posts, hence stay tuned.;

Network & Infrastructure

DNS & Hosting
IP Address
192.0.78.13
Reverse DNS
Not detected
SSL/TLS Certificate
Issuer
CN=E8, O=Let's Encrypt, C=US
Protocol Tls13
Expires In 67 days
HSTS Enabled

Technology Stack

Content Management Systems
WordPress WordPress (robots.txt)
Server Technologies
Generator: WordPress.com PHP (inferred from WordPress)

Services & Integrations

Analytics & Tracking
Google Analytics GA4 Google Analytics UA
E-commerce Platforms
PrestaShop

CDN & Media Providers

Media Providers
YouTube
Web Fonts
Font Awesome

Dynamic Analysis & Security

Dynamic JavaScript Analysis
Angular (Data Attributes) Bootstrap (CSS Classes) ES6+ JavaScript Features jQuery (CDN Detection) Web Server: nginx
Security Headers
HSTS
Server Headers
nginx

Resource Analysis

External Resource Hosts
0.gravatar.com
2.gravatar.com
af.pubmine.com
devexpressocom.wordpress.com
gmpg.org
pixel.wp.com
s0.wp.com
s1.wp.com
s2.wp.com
stats.wp.com
wp.me
UI Frameworks & Libraries
Angular Material (Class Names) AOS Bootstrap (Class Names) D3.js Ionic (Class Names) Swiper Vuetify (Class Names)

Analysis Errors

Analysis Warnings & Errors
The following issues occurred during analysis:
  • Reverse DNS failed: No such host is known.
Analysis Complete

Analyzed devexpressocom.wordpress.com with 4 technologies detected across 6 categories

Analysis completed in 524 ms • 2026-03-23 09:32:49 UTC