Showing posts with label .Net Core. Show all posts
Showing posts with label .Net Core. Show all posts

Data is Null. This method or property cannot be called on Null values

 Data is Null. This method or property cannot be called on Null values

Issue: 

Data is Null. This method or property cannot be called on Null values


Solution:

For columns that are nullable in your DB tables:

Wrong

 public string Memo { get; set; }

Correct: 

 public string? Memo { get; set; }


Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Enable CORS in ASP.net Core WebAPI

.Net Core : Enable CORS in ASP.net Core WebAPI


Enable CORS in ASP.net Core WebAPI


In ConfigureServices method

  public void ConfigureServices(IServiceCollection services)
        { 
            services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
            {
                builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
            }));

            services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DotNetCoreDB")));
             
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

In Configure method

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            } 
            app.UseAuthentication();

            app.UseCors(
                options => options.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials()
            );
 
            app.UseMvc();
        }


Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Unit Test with NUnit

.Net Core : Unit Test with NUnit


Below example is implemented with Nunit test to test .net core project feature.

Create test class,

namespace DotNetCoreDemo.Test
{
    public class EmployeeServiceTest
    {
        
    }
}

OneTimeSetUp 

 IEmployeeService employeeService;
        public Mock<IEmployeeRepository> mockEmployeeRepository;
        
        [OneTimeSetUp]
        public void Init()
        {
            mockEmployeeRepository = new Mock<IEmployeeRepository>();
            employeeService = new EmployeeService( this.mockEmployeeRepository.Object);
        }

Data Sources for test cases,

static object[] employeeSource =
        {
            new object[]
            {
                new Employee[]
                {
                    new Employee()
                    {
                        Id = 1, Name = "demo1", Email = "demo1@demo.com"
                    },
                    new Employee()
                    {
                        Id = 2, Name = "demo2", Email = "demo2@demo.com"
                    }
                } 
            }
        };

        static object[] employeeSourceNull =
        {
            new object[]
            {
                new Employee[]
                {
                    
                }
            }
        };

Test for get data,

 [Test, TestCaseSource("employeeSource")]
        public void GetEmployeeList_Return_True(Employee[] employees)
        {
            //Init            
            mockEmployeeRepository.Setup(p => p.GetAllEmployee()).Returns(employees.AsQueryable().ToList());
            
            //Act
            List<Employee> result  = employeeService.GetAllEmployee().ToList();

            ////Assert
            Assert.Greater(result.Count, 0);
        }

Test for no data,

[Test, TestCaseSource("employeeSourceNull")]
        public void GetEmployeeList_NoData_Return_True(Employee[] employees)
        {
            //Init            
            mockEmployeeRepository.Setup(p => p.GetAllEmployee()).Returns(employees.AsQueryable().ToList());

            //Act
            List<Employee> result = employeeService.GetAllEmployee().ToList();

            ////Assert
            Assert.AreEqual(result.Count, 0);
        }


Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Host ASP.NET Core on Windows with IIS

.Net Core : Host ASP.NET Core on Windows with IIS



Please follow steps given in document,


Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Token based Authentication in webAPI

.Net Core : Token based Authentication in webAPI



Startup.cs


public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DotNetCoreDB")));

            services.AddIdentity<IdentityUser, IdentityRole>()
                    .AddEntityFrameworkStores<AppDbContext>()
                    .AddDefaultTokenProviders();

            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>
                {
                    options.SaveToken = true;
                    options.RequireHttpsMetadata = false;
                    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidAudience = "http://mydomain.com",
                        ValidIssuer = "http://mydomain.com",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Secret 1234567890 phase"))
                    };
                });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();

            app.UseMvc();
        }

EmployeeController.cs


[Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class EmployeeController : Controller
    {
        private readonly UserManager<IdentityUser> userManager;
        private readonly SignInManager<IdentityUser> signInManager;

        public EmployeeController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
        { 
            this.userManager = userManager;
            this.signInManager = signInManager;
        } 

        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return userManager.Users.Select(u => u.UserName).ToArray();
        }

        [HttpPost]
        [AllowAnonymous]
        [Route("Register")]
        public async Task<JsonResult> Post(VMRegister vmRegister)
        {
            IdentityResult result = new IdentityResult();
            string errorMessage = "success";

            if (ModelState.IsValid)
            {
                var user = new IdentityUser
                {
                    UserName = vmRegister.EmailId,
                    Email = vmRegister.EmailId
                };

                result = await userManager.CreateAsync(user, vmRegister.Password);

                if (result.Succeeded)
                {
                    //to Signin user
                    //signInManager.SignInAsync(user, isPersistent: false).Start();
                }
                else
                {
                    if (result.Errors.Count() > 0)
                    {
                        errorMessage = "";
                        foreach (var error in result.Errors)
                        {
                            errorMessage += error.Description;
                        }
                    }
                }
            }

            return Json(new { id = "1", message = errorMessage });
        } 

        [HttpPost]
        [AllowAnonymous]
        [Route("Login")]
        public async Task<IActionResult> Login(VMLogin vmLogin)
        {
            var user = await userManager.FindByNameAsync(vmLogin.EmailId);
            if (user != null && await userManager.CheckPasswordAsync(user, vmLogin.Password))
            {
                var claims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
                };

                var signinKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Secret 1234567890 phase"));

                var token = new JwtSecurityToken(
                    issuer: "http://mydomain.com",
                    audience: "http://mydomain.com",
                    expires: DateTime.UtcNow.AddHours(1),
                    claims: claims,
                    signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
                    );

                return Ok(
                    new
                    {
                        token = new JwtSecurityTokenHandler().WriteToken(token),
                        expiration = token.ValidTo
                    });
            }
            return Unauthorized();
        }  
    }

Testing












Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Extend Identity User and add custom field in AspNetUsers table

.Net Core : Extend Identity User and add custom field in AspNetUsers table



Create new class and inherit with IdentityUser, here I created "ApplicationUser" and added 

namespace DotNetCodeDemo.Repository.Models
{
    public class ApplicationUser : IdentityUser
    {
        public string  City { get; set; }        
        public string MobileNumber { get; set; }
        public DateTime BirthDate { get; set; }
        public DateTime JoinDate { get; set; }
    }
}

Update dbContext class

namespace DotNetCodeDemo.Repository
{
    public class AppDbContext : IdentityDbContext<ApplicationUser>
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {

        }

        public DbSet<Employee> Employees { get; set; }
        public DbSet<Department> Departments { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Seed();
        }
    }
}

Update ConfigureServices method in startup class

public void ConfigureServices(IServiceCollection services)
{
 services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DotNetCoreDB")));

 services.AddIdentity<ApplicationUser, IdentityRole>(options =>
 {
  options.Password.RequiredLength = 10; // if you want to set your own password strength rule
  options.Password.RequiredUniqueChars = 2;
 }).AddEntityFrameworkStores<AppDbContext>(); 

 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 services.AddScoped<IEmployeeRepository, EmployeeRepository>();
}

Update IdentityUser with ApplicationUser in your controller

namespace DotNetCodeDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : Controller
    {
        private readonly UserManager<ApplicationUser> userManager;
        private readonly SignInManager<ApplicationUser> signInManager;
        
        public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
        {
             
            this.userManager = userManager;
            this.signInManager = signInManager;
        }
         
        [HttpPost]
        [Route("Register")]
        public async Task<JsonResult> Post(VMRegister vmRegister)
        {
            IdentityResult result = new IdentityResult();
            string errorMessage = "success";

            if(ModelState.IsValid)
            {
                var user = new ApplicationUser
                {
                    UserName = vmRegister.Email,
                    Email = vmRegister.Email,
                    City = vmRegister.City
                };

                result = await userManager.CreateAsync(user, vmRegister.Password);

                if(result.Succeeded)
                {
                    //to Signin user
                    //signInManager.SignInAsync(user, isPersistent: false).Start();
                }
                else
                {
                    if(result.Errors.Count() > 0)
                    {
                        errorMessage = "";
                        foreach (var error in result.Errors)
                        {
                            errorMessage += error.Description;
                        }
                    }
                }
            }            

            return Json(new { id = "1", message = errorMessage });
        } 
    }
}

Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : AspNet Membership Login Method

.Net Core : AspNet Membership Login Method



AspNet membership login method code,

[HttpPost]
[Route("Login")]
public async Task<JsonResult> Post(VMLogin vmLogin)
{
Microsoft.AspNetCore.Identity.SignInResult result = new Microsoft.AspNetCore.Identity.SignInResult();
string errorMessage = "success";

if (ModelState.IsValid)
{
  
  result = await signInManager.PasswordSignInAsync(vmLogin.Email, vmLogin.Password, vmLogin.RememberMe, false);

if (!result.Succeeded)                 
{
errorMessage = "fail";
}
}

return Json(new { message = errorMessage });
} 



Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Change Identity password complexity rules

.Net Core : Change Identity password complexity rules



Change Identity password complexity rules,


In ConfigureServices method

services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequiredLength = 10;
options.Password.RequiredUniqueChars = 2;
}).AddEntityFrameworkStores<AppDbContext>();


Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Register User data into Identity table

.Net Core : Register User data into Identity table



Insert record in identity table,

namespace DotNetCoreDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : Controller
    {
        private readonly UserManager<IdentityUser> userManager;
        private readonly SignInManager<IdentityUser> signInManager;
        
        public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
        {
             
            this.userManager = userManager;
            this.signInManager = signInManager;
        }
         
        [HttpPost]
[Route("Register")]
        public async Task<JsonResult> Post(VMRegister vmRegister)
        {
            IdentityResult result = new IdentityResult();
            string errorMessage = "success";

            if(ModelState.IsValid)
            {
                var user = new IdentityUser
                {
                    UserName = vmRegister.Email,
                    Email = vmRegister.Email
                };

                result = await userManager.CreateAsync(user, vmRegister.Password);

                if(result.Succeeded)
                {
                    //to Signin user
                    //signInManager.SignInAsync(user, isPersistent: false).Start();
                }
                else
                {
                    if(result.Errors.Count() > 0)
                    {
                        errorMessage = "";
                        foreach (var error in result.Errors)
                        {
                            errorMessage += error.Description;
                        }
                    }
                }
            }            

            return Json(new { id = "1", message = errorMessage });
        } 
    }
}


Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : ASP.NET Membership - Identity User - Setup

.Net Core : ASP.NET Membership - Identity User - Setup



1. install nuget package - Microsoft.AspNetCore.Identity.EntityFrameworkCore

2. inherit DbContext class with IdentityDbContext
e.g., public class AppDbContext : IdentityDbContext

3.Configure identity in statup file, as below,
public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DotNetCoreDB")));

            services.AddIdentity<IdentityUser, IdentityRole>()
                    .AddEntityFrameworkStores<AppDbContext>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddScoped<IEmployeeRepository, EmployeeRepository>();
        }

4. add "app.UseAuthentication();" in Configure method before "app.UseMvc();".

5. Do datamigration using
Add-Migration "AddIdentity"

6. If you will get error like "The entity type 'IdentityUserLogin<string>' requires a primary key to be defined."
then 
goto appDbContext class and do changes in OnModelCreating method as below,
base.OnModelCreating(modelBuilder);

7. Now run again Add-Migration "AddIdentity"

8. then run Update-Database

9. Finally you can see there are some tables name start with "ASPNet" are added in database.

Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Database Connectivity

.Net Core : Database Connectivity

 

Model


namespace DotNetCodeDemo.Entities
{
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public Department Department { get; set; }
    }
}


namespace DotNetCodeDemo.Entities
{
    public class Department
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Location { get; set; }
    }
}
  

Repository


namespace DotNetCodeDemo.Repository.Contract
{
    public interface IEmployeeRepository
    {
        Employee GetEmployee(int Id);
        IEnumerable<Employee> GetAllEmployee();
        Employee Add(Employee employee);
        Employee Update(Employee employeeChanges);
        Employee Delete(int Id);
    }
}
  



namespace DotNetCodeDemo.Repository.Repositories
{
    public class EmployeeRepository : IEmployeeRepository
    {
        private readonly AppDbContext dbContext;

        public EmployeeRepository(AppDbContext dbContext)
        {
            this.dbContext = dbContext;
        }
        public Employee Add(Employee employee)
        {
            dbContext.Employees.Add(employee);
            dbContext.SaveChanges();
            return employee;
        }

        public Employee Delete(int Id)
        {
            var employee = dbContext.Employees.Find(Id);
            if(employee != null)
            {
                dbContext.Employees.Remove(employee);
                dbContext.SaveChanges();
            }            
            return employee;
        }

        public IEnumerable<Employee> GetAllEmployee()
        {
            return dbContext.Employees;
        }

        public Employee GetEmployee(int Id)
        {
            return dbContext.Employees.Find(Id);
        }

        public Employee Update(Employee employeeChanges)
        {
            var employee = dbContext.Employees.Attach(employeeChanges);
            employee.State = Microsoft.EntityFrameworkCore.EntityState.Modified;
            dbContext.SaveChanges();
            return employeeChanges;

        }
    }
}

   
namespace DotNetCodeDemo.Repository.Helper
{
    public static class ModelBuilderExtension
    {
        public static void Seed(this ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Employee>().HasData(
               new Employee
               {
                   Id = 1,
                   Name = "Demo1",
                   Email = "demo1@demo.com"
               },
               new Employee
               {
                   Id = 2,
                   Name = "Demo2",
                   Email = "demo2@demo.com"
               }
            );
        }
    }
}


namespace DotNetCodeDemo.Repository
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {

        }

        public DbSet<Employee> Employees { get; set; }
        public DbSet<Department> Departments { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Seed();
        }
    }
}

appsettings.json


{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DotNetCoreDB" :  "data source=localhost; initial catalog=dotnetCoreDb; user id=sa; password=sa"
  }
}

Startup.cs


namespace DotNetCodeDemo
{
    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.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DotNetCoreDB")));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddScoped<IEmployeeRepository, EmployeeRepository>();
        }

        // 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();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

API Controller


namespace DotNetCodeDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        private readonly IEmployeeRepository employeeRepository;

        public EmployeeController(IEmployeeRepository employeeRepository)
        {
            this.employeeRepository = employeeRepository;
        }

        [HttpGet]
        public ActionResult<IEnumerable<Employee>> Get()
        {
            return employeeRepository.GetAllEmployee().ToList();
        }
    }
}
  





Hope this will help you and save your time.

Enjoy !!!

:)

.Net Core : Logging system

.Net Core : Logging system


 Log messages in .net core.

Step 1

Create custom logger class 

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace CoreDemo.Middleware
{
    public class MyLoggerMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public MyLoggerMiddleware(RequestDelegate next, ILoggerFactory logFactory)
        {
            _next = next;
            _logger = logFactory.CreateLogger("MyLogger");
        }

        public async Task Invoke(HttpContext httpContext)
        {
            _logger.LogInformation("test log");
            //await _next(httpContext);

            var bodyStream = httpContext.Response.Body;
            var responseBodyStream = new MemoryStream();
            httpContext.Response.Body = responseBodyStream;

            await _next(httpContext);
            responseBodyStream.Seek(0, SeekOrigin.Begin);
            var responseBody = new StreamReader(responseBodyStream).ReadToEnd();

            var responseCode = httpContext.Response.StatusCode;
            var requestPath = httpContext.Request.Path;
            var requestMethod = httpContext.Request.Method;

            _logger.LogInformation($"@timeStamp = {DateTime.Now}, site = {"CoreDemo"}, Level = info, ThreadId = {Thread.CurrentThread.ManagedThreadId}, Message = logger Middleware response {responseBody}, request path = {requestPath}, request method = { requestMethod}");
                
            responseBodyStream.Seek(0, SeekOrigin.Begin);
            await responseBodyStream.CopyToAsync(bodyStream);
        }
    }

    public static class MyLoggerMiddlewareExtension
    {
        public static  IApplicationBuilder UseMyLoggerMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyLoggerMiddleware>();
        }
    }
}

  

Step 2

startup.cs

  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseMyLoggerMiddleware();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            
            app.UseMvc();
        }


Hope this will help you and save your time.

Enjoy !!!

:)

Host .Net Core Web API on IIS - ISSUE

Host .Net Core Web API on IIS - ISSUE

After uploaded .Net Core web API on IIS server, I faced below issue , but I found solution after some trial and error.


Issue

<div class = "content-container">
 <h3> HTTP Error 502.5 - Process Failure </h3>
</div>
<div class = "content-container">
 <fieldset>
  <h4> Common causes of this issue: </h4>
  <ul>
   <li> The application process failed to start </li>
   <li> The application process started but then stopped </li>
   <li> The application process started but failed to listen on the configured port </li>
  </ul>
 </fieldset>
</div>

Solution

Open web.config file and make some changes as below

Existing Configuration

<aspNetCore processPath="dotnet" arguments=".\CoreApp.dll -argFile IISExeLauncherArgs.txt" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />

Working Configuration:

<aspNetCore processPath="dotnet" arguments=".\CoreApp.dll -argFile IISExeLauncherArgs.txt" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />

 1. I had removed ".\" before dll name, as I hosted my application on root folder on server.

2. Removed -argFile IISExeLauncherArgs.txt

I hope that you also resolve your issue by using this solution.


Enjoy !!!

:)

Code First Migration in ASP.Net Core

Code First Migration in ASP.Net Core

Generally we create database first and then we create data model classes in project, and while we publish application we need to take care about database creation and table.

Code first, its approach that we first create data model classes and code itself create database and while publishing application, we don't need to take care about database and its tables, code automatically manage.

While executing code first migration command in .Net Core C#, we are facing some issues sometimes, here I faced some issues and found some solutions as below.

Issue 1

Getting error, while executing command 

Add-Migration -Context "DatabaseContext" 

 Unable to create an object of type 'DatabaseContext'. Add an implementation of 'IDesignTimeDbContextFactory<DatabaseContext>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

Solution 

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<DatabaseContext>
{
 public DatabaseContext CreateDbContext(string[] args)
 {
  IConfigurationRoot configuration = new ConfigurationBuilder()
   .SetBasePath(Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json")
   .Build();
  var builder = new DbContextOptionsBuilder<DatabaseContext>();
  var connectionString = configuration.GetConnectionString("dbConStr");
  builder.UseSqlServer(connectionString);
  return new DatabaseContext(builder.Options);
 }
}

Issue 2

Getting error, while executing below command

Add-Migration -Name "Migration Name" -Context "DatabaseContext"

GenericArguments[0], 'SampleWebAPI.Migrations.DatabaseContext', on 'Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory`1[TContext]' violates the constraint of type 'TContext'.

Solution 

1. First remove migration folder (if any) from project which was created by above command

Issue 3

Getting error, while executing command 

Update-Database 

More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.

Solution 

Update-Database -Context "DatabaseContext"

Finally

Use below migration commands for .Net Core


1. Add-Migration -Name "Migration Name" -Context "DatabaseContext"

2. Update-Database -Context "DatabaseContext"



Enjoy !!!

:)

Swagger with ASP.Net Core 2.0 Web API


Swagger with ASP.Net Core 2.0 Web API

Swagger is a open source framework, which helps to create API documentation.

Using swagger, developer does not need to mention to developer who want to consume API, its straight forward to visualization.

Here, we will see that how to use swagger with ASP.Net core 2.0 web API.
First install "Swashbuckle.AspNetCore" using nuget package manager.

Add swagger service to application services, Open startup.cs and do following changes.

public void ConfigureServices(IServiceCollection services)
{
 services.AddMvc();

 services.Configure<IISOptions>(options =>
 {
  options.ForwardClientCertificate = false;
 });

 services.AddSwaggerGen(c =>
 {
  c.SwaggerDoc("v1", new Info
  {
   Version = "v1",
   Title = "Demo Service",
   Description = "Demo Service Description",
   TermsOfService = "None",
   Contact = new Contact() { Name = "Rohit Rathod", Email = "anrorathod@gmail.com", Url = "www.mywebsite.com" }
  });
 });
}

Here, SwaggerDoc Info properties are optional (Version, Title, Description, TermsOfService and Contact).


Now, write below code to enable swagger UI,

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
 if (env.IsDevelopment())
 {
  app.UseDeveloperExceptionPage();
 }

 app.UseMvc();

 string appPath = "/DemoService.WebAPI/";
 app.UseSwagger();
 app.UseSwaggerUI(c =>
 {
  c.SwaggerEndpoint(appPath + "swagger/v1/swagger.json", "Demo Service");
 });
} 

Now, build web API application, open web browser and run application and you will see API documentation.

http://localhost/DemoService.WebAPI/swagger/

I hope that this will helpful in your web API project.

Enjoy !!!



:)

ASP.Net Core API - HTTP Error 405.0 - Method Not Allowed

ASP.Net Core API - HTTP Error 405.0 - Method Not Allowed

I have created web api for delete in ASP.Net core C#, while I execute delete method in Postman (with method = DELETE ), I got below error...

HTTP Error 405.0 - Method Not Allowed

<ul>
 <li>The request sent to the Web server used an HTTP verb that is not allowed by the module configured to handle the request.</li>
 <li>A request was sent to the server that contained an invalid HTTP verb.</li>
 <li>The request is for static content and contains an HTTP verb other than GET or HEAD.</li>
 <li>A request was sent to a virtual directory using the HTTP verb POST and the default document is a static file that does not support HTTP verbs other than GET or HEAD.</li>
</ul>

I found below solution after searching on internet and it is working fine for me.

I added below configuration in web.config file.

  <system.webServer>
     <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/>
   </modules>    
  </system.webServer

Hope, this will help to resolve your issue...

Enjoy !!!

:)

Azure Service Bus - Send & Receive Message - Topic in .Net Core

Azure Service Bus - Send & Receive Message - Topic in .Net Core




I have seen many examples to send and receive message of Azure Service Bus Topic in normal .Net framework, but I couldn't find correct code for .Net Core for the same to send and receive Azure Service Bus Topic.

Finally, I got solution and here is code for .Net Core C#.

Send Message

1. Create web api project with .Net core
2. Add Service Bus NuGet package, search for "Microsoft.Azure.ServiceBus"
3. Add NuGet package for "Newtonsoft.Json"
4. Create Test API controller
5. Write below code

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; 
using Microsoft.Azure.ServiceBus;
using Newtonsoft.Json; 
using System.Collections.Generic; 
using System.Text; 

namespace Demo.WebAPI.Controllers
{
    [Produces("application/json")]
    [Route("api/Test")]
    public class TestController : Controller
    {
        [HttpPost]
        public async Task<IActionResult> Post(dynamic model)
        {
            try
            {
                await Task.Run(() =>
                {
                    MessageFactory.SendMessagesAsync("TestTopic",
                           "testLable", 60, model);
                });
            }
            catch (Exception ex)
            {

                return Ok(ex.Message);
            }

            return Ok("Request submitted. ");
        }
        public static async Task SendMessagesAsync(string topicName, string lable, int minsTimeToLive, dynamic model, Dictionary<string, string> properties = null)
        {
            try
            {
                ITopicClient topicClient = new TopicClient(Config.ConnectionString, topicName);

                Message message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(model)))
                {
                    ContentType = "application/json",
                    Label = "test",
                    TimeToLive = TimeSpan.FromMinutes(minsTimeToLive)
                };

                await topicClient.SendAsync(message);
            }
            catch (Exception exception)
            {

            }
        }
    } 
}


Test Web API 

1. Open Postman or restclient to test web api
2. URL :http://localhost/Demo.WebAPI/api/Test
2. Content-Type = application/json
3. Type: POST
4. Body as below,

 {
  "OrderDate":"02/22/2018",
  "CustomerId": 28,
  "Amount":35.23,
  "PaymentType":"Online",
  "Products":[
   {
    "ProductId":1,
    "Quantity":2,
    "Amount":10
   },
   {
    "ProductId":3,
    "Quantity":1,
    "Amount":15
   }
   ],
   "ShippingAddress":
   {
    "ShippingBy":"BlueDart",
    "CustomerName":"Test Customer",
    "Address":"Address 1",
  "Email":"test@test.com",
  "Phone":"1234567890"
   }
}

After posting request, you should get Status = 200 OK


Receive Message

1. Create .Net Core console application
2. Add reference using nuget for "Microsoft.Azure.ServiceBus" and "Newtonsoft.Json"
3. Write below code to receive azure service bus topic message

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
using Newtonsoft.Json; 

namespace Demo.Service
{
    class Program
    {
        const string ServiceBusConnectionString = "Endpoint=sb://[NameSpace].servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[SharedAccessKey]=";
        const string TopicName = "TestTopic";
        const string SubscriptionName = "TestSubscriber";
        static ISubscriptionClient subscriptionClient;

        static void Main(string[] args)
        {
            Console.WriteLine("Service started...");

            while (true)
            {
                MainAsync().GetAwaiter().GetResult();
            }

        }

        static async Task MainAsync()
        {
            subscriptionClient = new SubscriptionClient(ServiceBusConnectionString, TopicName, SubscriptionName);

            RegisterOnMessageHandlerAndReceiveMessages();

            await subscriptionClient.CloseAsync();
        }

        static void RegisterOnMessageHandlerAndReceiveMessages()
        {
            // Configure the message handler options in terms of exception handling, number of concurrent messages to deliver, etc.
            var messageHandlerOptions = new MessageHandlerOptions(ExceptionHandler)
            {
                // Maximum number of concurrent calls to the callback ProcessMessagesAsync(), set to 1 for simplicity.
                // Set it according to how many messages the application wants to process in parallel.
                MaxConcurrentCalls = 1,

                // Indicates whether MessagePump should automatically complete the messages after returning from User Callback.
                // False below indicates the Complete will be handled by the User Callback as in `ProcessMessagesAsync` below.
                AutoComplete = false
            };

            // Register the function that processes messages.
            subscriptionClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
        }

        static async Task ProcessMessagesAsync(Message message, CancellationToken token)
        {
            var a = new MemoryStream(message.Body);

            var body = Encoding.UTF8.GetString(message.Body);

            Order order = JsonConvert.DeserializeObject<Order>(body);

            // Process the message.
            Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
            // Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Id = { order.OrderId}");
            // Complete the message so that it is not received again.
            // This can be done only if the subscriptionClient is created in ReceiveMode.PeekLock mode (which is the default).
            await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);

            // Note: Use the cancellationToken passed as necessary to determine if the subscriptionClient has already been closed.
            // If subscriptionClient has already been closed, you can choose to not call CompleteAsync() or AbandonAsync() etc.
            // to avoid unnecessary exceptions.
        }

        static Task ExceptionHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
        {
            Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
            var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
            Console.WriteLine("Exception context for troubleshooting:");
            Console.WriteLine($"- Endpoint: {context.Endpoint}");
            Console.WriteLine($"- Entity Path: {context.EntityPath}");
            Console.WriteLine($"- Executing Action: {context.Action}");
            return Task.CompletedTask;
        }
    }
}



Add classes to do business process....

public class Order
{
 public Guid OrderId { get; set; }
 public int CustomerId { get; set; }
 public string InvoiceNo { get; set; }
 public DateTime OrderDate { get; set; }
 public bool Payment { get; set; }
 public string OrderStatus { get; set; }
 public string PaymentType { get; set; }
 public decimal Amount { get; set; }

 public List<OrderItems> Products { get; set; }
 public ShippingAddress ShippingAddress { get; set; }
}
public class OrderItems
{
 public int ProductId { get; set; }
 public int Quantity { get; set; }
 public decimal Amount { get; set; }
}
public class ShippingAddress
{
 public Int64 ShippingId { get; set; }
 public Guid OrderId { get; set; }
 public DateTime ShippingDate { get; set; }
 public string ShippingBy { get; set; }
 public string CustomerName { get; set; }
 public string Address { get; set; }
 public string Email { get; set; }
 public string Phone { get; set; }
 public string ShippingStatus { get; set; }

}


Run console application and you will receive azure service bus message.



Enjoy !!!

:)