Saturday, September 22, 2018

JetBrains Rider, MacOS and ASP.NET Core Web Application Permission Denied on localhost Port 80

At work, I am on MacOS and using JetBrains Rider as the primary IDE. Switching to MacOS and Rider was not at all easy, still struggling most of the time. Switching between Windows and MacOS is more harder.

I wanted to run ASP.NET Core Web Application in localhost port 80, but it kept giving me permission denied error.
image
Permission Denied
Using the following command, I checked for any processes that use port 80, but unfortunately, there wasn’t any.
sudo lsof -i ':80'
Checked the firewall as well, and it was switched off. Then I realized, I was not running Rider as admin (sudo in MacOS). Just googled how to start a program as sudo, and there wasn't any straightforward option just like Windows has as Run as administrator. But using the terminal, did able to get to Rider run as sudo.
sudo /Applications/Rider\ 2018.2.app/Contents/MacOS/rider 
image
run as sudo
But once it's started running as sudo, it is a fresh instance, meaning the IDE doesn't have any imported settings which is kind of bad. But it did solve the permission issue, web application successfully started running on port 80.

Thought this might help someone.

Happy Coding.

Regards,
Jaliya

Friday, September 7, 2018

Installing Redis on Windows

Recently I started working on a new project and we use Mac there. I wanted to have the development environment set up in my Windows machine and one of the requirements is I wanted to have a Redis instance there. Went to the Redis download page and surprisingly I couldn’t find any installer for Windows. I was looking for options.

I found this, MicrosoftArchive/redis on GitHub, a repository of Redis Windows port developed by Microsoft Open Tech. But unfortunately, that doesn’t seem to be maintained, the last Redis version available for download is Redis 3.2.1 while Redis 4.0.11 is the latest stable version.

I wasn’t quite convinced whether I should go with that, but then suddenly I remembered we have Docker. I should be able to get it up and running with just one command.
docker run --name redis -p 6379:6379 redis

image
docker run

The image got downloaded without any issue, but it didn’t start, failed with the error "Error response from daemon: driver failed programming external connectivity on endpoint redis".

Another bump, checked whether the image and container is present, it is.
image
Image
image
Container
Deleted the container named “redis”, restarted Docker and ran the command again. This time the image won't get downloaded since it's already present, will only create and start the container.

image
docker run
Redis container just started. Anyway, I wanted to make sure it's up and running.

image
docker ps
That is wonderful. It’s up. With very little steps, I have Redis running on Windows.

Happy Coding.

Regards,
Jaliya

Wednesday, September 5, 2018

Wrote a post on Wiki Life at Official Blog of TechNet Wiki

Wrote a post in Wiki Ninjas - Official Blog of TechNet Wiki. The title of the post is TNWiki Article Spotlight – ASP.NET Core Blazor Master/Detail CRUD with Filtering and Sorting using EF and Web API.
image
TNWiki Article Spotlight – ASP.NET Core Blazor Master/Detail CRUD with Filtering and Sorting using EF and Web API

Happy Coding.

Regards,
Jaliya

Sunday, September 2, 2018

ASP.NET Core: Transient/Scoped Instances Inside Middleware

I have faced this scenario where when requesting a Transient or Scoped instance from a constructor in a Custom Middleware it wasn’t giving me a Transient/Scoped instance, instead, it was giving me a singleton.

Let’s examine the problem in detail. Say I have the following interface, it’s implementation and a custom middleware.

IMyService.cs
public interface IMyService
{
    Guid GetGuid();
}
MyService.cs
public class MyService : IMyService
{
    private readonly Guid guid;
 
    public MyService()
    {
        guid = Guid.NewGuid();
    }
 
    public Guid GetGuid()
    {
        return guid;
    }
}
HelloWorldMiddleware.cs
public class HelloWorldMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMyService _myService;
 
    public HelloWorldMiddleware(RequestDelegate next,
        IMyService myService)
    {
        _next = next;
        _myService = myService;
    }
 
    public async Task Invoke(HttpContext httpContext)
    {
        await httpContext.Response.WriteAsync($"Hello World with {_myService.GetGuid()}");
    }
}
Now in my Startup.cs, I am registering IMyService and MyService as Transient and plugging in the HelloWorldMiddleware to the application pipeline.

Startup.cs
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
 
    public IConfiguration Configuration { get; }
 
    public void ConfigureServices(IServiceCollection services)
    {
        // Rest of the code ignored for brevity
 
        // Registering IMyService as Transient
        // Meaning a new instance is created each time it’s requested
        services.AddTransient<IMyService, MyService>();
    }
 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Rest of the code ignored for brevity
 
        // Setting the custom middleware to the pipeline
        app.Map("/api/helloworld", configuration =>
        {
            configuration.UseMiddleware<HelloWorldMiddleware>();
        });
    }
}
So the idea is, each time I get navigated to “http://something/api/helloworld”, I get a response “Hello World” and that is with a new Guid. Because MyService constructor always creates a new Guid.

But no matter how many times I sent the request to “../api/helloworld”, I will get the same Guid. The reason is even though I have registered MyService as a Transient, the Middleware constructor will only get triggered once, and that is when the application is starting up. So here the constructor injection doesn’t work.

The workaround would be removing the constructor injection and request the service directly from context’s services.
public class HelloWorldMiddleware
{
    private readonly RequestDelegate _next;
 
    public HelloWorldMiddleware(RequestDelegate next)
    {
        _next = next;
    }
 
    public async Task Invoke(HttpContext httpContext)
    {
        IMyService _myService = httpContext.RequestServices.GetService<IMyService>();
        await httpContext.Response.WriteAsync($"Hello World with {_myService.GetGuid()}");
    }
}
Now when I navigated to “../api/helloworld”, I will get an instance of MyService, if it was registered as Transient, I will get a Transient and if it was registered as Scoped or Singleton, I will get a Scoped or Singleton instance respectfully.

Hope this helps.

Happy Coding.

Regards,
Jaliya