Core Tutorial
Core Tutorial
Core Tutorial
Setp 1:
Open Visual Studio 2017, Select File => New => Project
Step 2:
Select "Web Application" then click "OK"
Step 3:
As we can see the following Asp.Net Core default stricture created
by visual studio. Now let’s understand each folder, files and how
they work.
Any other type of ASP.NET applications we can store any static files
in root, or in any other folder under root, and can be served from
there. This has been changed in ASP.NET Core. Now we can store
any static files under wwwroot folder only, all other files are blocked
on http request.
Appsettings.json in ASP.NET Core
Now for each key you can have a single value or multiple values with
a set of keys. you can write this way “section-key” :{ “key1”:”value1”,
“key2”:”value2”}
Method 2
There is another we can read values using custom class from
appsettings.json, like how we used to read using custom
configuration in earlier .net version
See this code Illustration
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
What is Program.cs ?
Program.cs file is the entry point of the application. This will be executed
first when the application runs, there is a public static void Main method,
Whatever code you write inside that method will be executed in that
related setting and startup.cs file methods" from that Main() method.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}
In public static void Main() of Program class where we can create a
host for the web application, earlier tutorial we have explained
about asp.net core Startup.cs class
var host = new WebHostBuilder();
// Now
IWebHostBuilder host = WebHost.CreateDefaultBuilder(args)
//CreateDefaultBuilder is a static method now create the
new instance
// finally call
host.Run();
BundlerMinifier
BundlerMinifier is the first choice for ASP.NET Core
application for bundling and minification, read more about
this Utility. It has following features
o Bundle CSS, JavaScript or HTML files into a single output
file
o Supports MSBuild for CI scenarios
o Supports Command line
o Minify individual or bundled CSS, JavaScript and HTML files
// in Configure() method
app.UseWebOptimizer();
app.UseStaticFiles();
Gulp
Gulp is a JavaScript task runner which can automate many
common tasks of a website like minification, checking js
errors, bundling of various js and CSS files, optimizes images
etc.
Here is a nice article on How to Use Gulp in ASP.NET Core
services.Configure<DbConnection>(Configuration.GetSection("
DbConnectionConfig"));
}
}
In above example we are try to configure a DbConnectionConfig
class we read information from appSetting.json class, so we want
when service starts, all configuration information to be available in
custom configuration class
Configure Method in Startup.cs
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.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
DbConnectionString =
string.Format("Server={0};Database={1};
User ID={2};Password={3};Trusted_Connection=False;
MultipleActiveResultSets=true;",
Configuration["DbConnectionConfig:ServerName"],
Configuration["DbConnectionConfig:DatabaseName"],
Configuration["DbConnectionConfig:UserName"],
Configuration["DbConnectionConfig:Password"]);
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template:
"{controller=Home}/{action=Index}/{id?}");
});
}
If you have been developing Asp.net application for some long time,
then you may have a question what was the necessity of Kestrel
when there was well established web server IIS!
First reason is, IIS is limited to windows OS only, but now Asp.net
core was designed to be hosted on other platform like LINUX, Mac,
so there was a need for a web server that can run on different OS
apart from windows.
Now if you click on F5, your Kestrel web server will start, and your
web page will open up in default browser.
You will see a black DOS window will open up, the window will
display all hosting related information.
If you want to shut down the Kestrel web server, you can either
close the window or press "control + C" to shut down.
dotnet run
When you create razor page with model, a code behind file is
created
Example.cshtml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace LearnRazorPages.Pages
{
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
}
Once you submit the form, you can access the submitted values in
your codebehind OnPost() method
Example.cshtml.cs:
public void OnPost()
{
var name = Request.Form["name"];
var email = Request.Form["email"];
var mobile = Request.Form["mobile"];
// now you have all submitted values in local variables
}
You should also read the Form in Razor Page to know more about
PageModel, Handler Methods, Leveraging Model Binding, Handler
method parameters etc.
Now while accessing the partial view, you don’t need to provide the
full path like @Html.Partial("shared/_menu"), you can
call @Html.Partial("_menu"), Automatically razor page view engine
will search that particular folder for all views
Step 2:
Create partial view with name "_studentQuery", then add the model
reference, and create a simple form to capture student data.
@model AspNetCoreWebApplication.Models.Student;
<form method="post">
Name: <input asp-for="Name" />
Mobile: <input asp-for="Mobile" />
Email: <input asp-for="Email" />
<input type="submit" value="Join" />
</form>
Step 3:
Now create the main content page about.chtml , and call the partial
view with model reference like @Html.Partial("_studentQuery",
model:Model.Student)
@page
@model AboutModel
@Html.Partial("_studentQuery", model:Model.Student)
Asp.Net Core Razor Page has some methods that are automatically
executed whenever we make a Request . There is some naming
convention used by Razor Pages framework, which helps to select
the appropriate handler method to execute.
Above methods are always executed when we request the page, All
method name follows standard naming convention.
So all verbs are prefixed with "On" are the default methods name,
Like OnGet(), OnPost(), OnPut(), OnDelete() etc.
All Handler methods in razor page also have optional asynchronous
equivalents method like OnGetAsync(), OnPostAsync() etc. Now you
do not need to add the Async suffix
You can have either of these two methods in same razor page codebehind
[chtml.cs]
Note: even if one method takes parameter and other one without
parameter still same exception will be thrown, means if you have
OnGet(string parameter1) and OnGetAsync() still won’t work, it’s
still considered as multiple handlers on same page.
But remember we can't have both methods on same page, even with
different signature, then that will throw an exception for multiple
handlers.
Now in code behind you can write multiple handler method, each
time form is submitted a different method is getting executed, so
based method you can update database, write complex business logic
to decide further action for user.
public void OnPostAspnet(int valuecount)
{
ViewData["ActionMessage"] = $"Aspnet
{valuecount}";
}
public void OnPostAspnetmvc(int valuecount)
{
ViewData["ActionMessage"] = $"AspnetMVC
{valuecount}";
}
public void OnPostAspnetcore(int valuecount)
{
ViewData["ActionMessage"] = $"AspnetCore
{valuecount}";
}
public void OnPostLinq(int valuecount)
{
ViewData["ActionMessage"] = $"LINQ
{valuecount}";
}
public void OnPostHtml(int valuecount)
{
ViewData["ActionMessage"] = $"Html
{valuecount}";
}
Example 1 .cshtml:
here is a simple example of html form tag with Model with three
fields.
Now if you notice I have specified fields in two different ways, first
one Using MVC style and other one using asp-for="propertyname",
both works fine!
<form method="post">
<div>@Html.TextBoxFor(m => m.FullName)</div>
<div>Email: <input asp-for="Email" /> </div>
<div>Mobile: <input asp-for="ContactNumbers" /> </div>
<div> <input type="submit" /> </div>
</form>
Example 2 .cshtml:
Using MVC form syntax with three fields
@using (Html.BeginForm(FormMethod.Post))
{
<div class="s1">
<div>Full Name</div>
@Html.TextBoxFor(m => m.FullName) </div>
<div class="s1">
<div>Contact Numbers</div>
@Html.TextBoxFor(m => m.ContactNumbers) </div>
<div class="s1">
<div>Email</div>
@Html.TextBoxFor(m => m.Email)
</div>
<div>
<input type="submit" value="Contact" />
</div>
}
Example.cshtml.cs:
This example will work in both situations, with Model and without
Model
Still you can access properties using Request.Form["fieldName"]
public void OnPost()
{
var name = Request.Form["FullName"];
var email = Request.Form["Email"];
var mobile = Request.Form["ContactNumbers"];
// now you have all submitted values in local variables
}
handler
There are differ ways you can validate data in Asp.net Razor Form
Razor page framework are built on MVC Framework, so it supports
following input validation framework.
Range
Specify the minimum and maximum values of a range, so
user must provide a value within that range
Compare
Compare the value of two fields, or with a fixed specified
value
StringLength
Sets the maximum number of string characters allowed
MaxLength
Sets the maximum length, number of characters can be
accepted
MinLength
Sets the minimum length, number of characters can be
accepted
RegularExpression
Checks if the value matching against the specified regular
expression
Remote
It helps enabling client-side validation against a server-
side code, like checking database to see if a partial email
id is already in use
If you check how the html look like after rendering, notice data-
val="true", if set data-val="false" then validation won't happen
<form method="post">
Name:<input type="text" data-val="true" data-val-length="5-
60 character" data-val-length-max="60" data-val-length-
min="5" data-val-required="Full Name Required"
id="FullName" name="FullName" value="" />
<span class="field-validation-valid" data-valmsg-
for="FullName" data-valmsg-replace="true"></span>
Make sure you have added following jquery files as reference in your
page
@section scripts
{
<script src="~/lib/jquery.js"></script>
<script src="~/lib/jquery.validate.js"></script>
<script src="~/lib/jquery.validate.unobtrusive.js"></script>
}
other external web services while user entering data in text box, making
an ajax call to server side code to check if the input is valid or else
sports event, so apart from student name and mobile number we are also
accepting a unique code as their choice, but we need to validate the code
with backend server to ensure that the same code has not been taken by
registration only.
Step 1:
validation.
Step 2:
Make sure you have added following jquery file reference, so that
ajax request works properly
@section scripts
{
<script src="~/lib/jquery.js"></script>
<script src="~/lib/jquery.validate.js"> </script>
<script src="~/lib/jquery.validate.unobtrusive.js">
</script>
}
Step 3:
Now we create the model with all above fields, and notice how we are
Message")]
Step 4:
Now we write the method in server side code to interact with
database or any external web service, this is the place where we
check if the code is already exist in database
public IActionResult ValidateCode(string code)
{
string result;
// here you can check the code with database
if (code == "wtr1")
{
result = "Valid code";
}
else
{
result = "Invalid code";
}
return Json(result);
}
Note:
Here we have not connected with database or web service, we simply
checked with a hardcoded value “wtr1”, you can replace that code
with your database call or web service call
Before you learn MVC in Asp.Net Core, We suggest you to have good
understanding about Model View Controller in Asp.net , because in
this article we talk about only what we implement differently in
Asp.net Core.
Here are the steps we perform to create an Asp.Net Core MVC
application with Entity Framework Core as Data Access Layer
View
Now we design view (razor) where we want to capture new student
data and display the student list.
Here are some important tags for designing form in Asp.Net Core
Razor.
Please notice how syntax is different than earlier Asp.net MVC
return list;
}
}
}
Step 2
Now in Configure method call UseSession() method
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseSession();
}
Step 3
Now install Microsoft.AspNetCore.Session utility from Nugget
And three methods for retrieving values from session , which are
Get, GetInt32 and GetString
string _sessionStringvalue =
HttpContext.Session.GetString("sessionKeyString");
int? _sessionIntValue =
HttpContext.Session.GetInt32("sessionKeyInt");
So far we have seen how to use session object to store simple
information, but there is no straight way to store complex object in
asp.net core session.
Now we learn how to store complex object in session
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
public static class SessionHelper
{
public static void SetObjectAsJson(this
ISession session, string key, object value)
{
session.SetString(key,
JsonConvert.SerializeObject(value));
}
public static T GetObjectFromJson<T>(this
ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) :
JsonConvert.DeserializeObject<T>(value);
}
}
Now let's call the above methods to add and retrieve complex object
in session.
In following example we add a student object list in session and
retrieve from session
BundlerMinifier
BundlerMinifier is the first choice for ASP.NET Core
application for bundling and minification, read more about
this Utility. It has following features
o Bundle CSS, JavaScript or HTML files into a single output
file
o Supports MSBuild for CI scenarios
o Supports Command line
o Minify individual or bundled CSS, JavaScript and HTML files
// in Configure() method
app.UseWebOptimizer();
app.UseStaticFiles();
Gulp
Gulp is a JavaScript task runner which can automate many
common tasks of a website like minification, checking js
errors, bundling of various js and CSS files, optimizes images
etc.
Here is a nice article on How to Use Gulp in ASP.NET Core
Instead of
app.UseMvcWithDefaultRoute();
app.UseMvc(routes =>
{
routes.MapRoute(
name:"default",
template: "{controller=Home}/{action=Index}/{id?}");
});
While working with database from razor pages you can use any data
access mechanism like Ado.Net, Entity Framework etc.
Step 2:
Create database connection details in appsettings.json and Entity
Framework class DbContext
"DbConnectionConfig": {
"DatabaseName": "MarketingDB",
"UserName": "masa",
"Password": "mapass",
"ServerName": "USER-PC"
}
Step 3:
Create a DTO class to interact with database using Entity
Framework, in this class we have written four methods AddStudent,
UpdateStudent, GetAllStudents, DeleteStudents, Learn IDisposable
Implementation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AspNetCoreWebApplication.DTO
{
public class StudentDTO : IDisposable
{
public Student AddStudent(Student s)
{
using (EFContext context = new EFContext())
{
context.tbStudent.Add(s);
context.SaveChanges();
}
return s;
}
public Student UpdateStudent(Student student)
{
Student _s = null;
using (EFContext context = new EFContext())
{
_s = context.tbStudent
.Where(s => s.StuId == student.StuId)
.FirstOrDefault<Student>();
if (_s != null)
{
_s.Firstname = student.Firstname;
_s.Lastname = student.Lastname;
_s.Email = student.Email;
_s.ContactNumber = student.ContactNumber;
context.SaveChanges();
}
}
return _s;
}
public List<Student> GetAllStudents()
{
List<Student> list = new List<Student>();
var context = new EFContext();
list = context.tbStudent
.ToList<Student>();
return list;
}
public bool DeleteStudent(int stuid)
{
bool _isDeleted = false;
Student _s = null;
var context = new EFContext();
_s = context.tbStudent
.Where(s => s.StuId == stuid)
.FirstOrDefault<Student>();
if (_s != null)
{
context.tbStudent.Remove(_s);
context.SaveChanges();
_isDeleted = true;
}
return _isDeleted;
}
public Student GetStudent(int sid)
{
Student _s = null;
using (EFContext context = new EFContext())
{
_s = context.tbStudent
.Where(s => s.StuId == sid)
.FirstOrDefault<Student>();
}
return _s;
}
}
}
Step 4:
In PageModel public class studentModel:PageModel {}
[BindProperty]
public int StudentId { get; set; }
[BindProperty]
[Required(ErrorMessage = "Firstname Required")]
[StringLength(50, ErrorMessage = "5 to 50
characters.", MinimumLength = 3)]
public string FirstName { get; set; }
[BindProperty]
[Required(ErrorMessage = "Lastname Required")]
[StringLength(50, ErrorMessage = "5 to 50
characters.", MinimumLength = 3)]
public string LastName { get; set; }
[BindProperty]
[Required(ErrorMessage = "Email Required")]
[EmailAddress(ErrorMessage = "Invalid email")]
public string Email { get; set; }
[BindProperty]
public string Mobile { get; set; }
[BindProperty]
public List<Student> Students { get; set; }
in OnPost() method
The above code will throw error, will see how differently we can
catch the exception and log error details and display user friendly
error message .
}
else
app.UseExceptionHandler("/error");
Use of UseExceptionHandler
app.UseExceptionHandler(
options =>
{
options.Run(
async context =>
{
context.Response.StatusCode =
(int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "text/html";
var ex =
context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
var err = $"<h1>Error:
{ex.Error.Message}</h1>{ex.Error.StackTrace}";
await
context.Response.WriteAsync(err).ConfigureAwait(false);
}
});
}
);
Now we see how to catch error status code like page not found,
internal server error etc.
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseStatusCodePages();
}
Now if try to access some unknown page on browser, you will get
following error message
Above method is good enough to catch error status code and display
the error, but in application development sometimes you may want
to display the error to a different user friendly page with other page
navigation, in such situation you can use
UseStatusCodePagesWithRedirects().
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/Error", "?
statusCode={0}");
}
this method will redirect user to a different error page, where you
can show custom error message based on statusCode, alternatively
you also can create different error page for each code, and redirect
to page based on code.
LogDebug()
LogInformation()
LogWarning()
LogError()
LogCritical()
loggerFactory.AddConsole(Configuration.GetSection("Logging"
));
loggerFactory.AddDebug();
//removed all other code for clarity
}
Now open your controller class and use dependency injection through
Here are the few simple steps to implement Log4Net in your Asp.net
Core application.
Step 1
Install Log4Net utility using NugetPackage
Right Click on your project => Manage NuGet Package =>
Make sure you change the file tag value, mention your file path,
where you want file to be created.
Step 3
Now setup log4net Repository in Program.cs file
public class Program
{
public static void Main(string[] args)
{
var log4netRepository =
log4net.LogManager.GetRepository(Assembly.GetEntryAssembly(
));
log4net.Config.XmlConfigurator.Configure(log4netRepository,
new FileInfo("log4net.config"));
BuildWebHost(args).Run();
}
}
Step 4
Now open your controller class and setup _log4net local object, so
you can access all log4net methods in this controller, for example
we have called _log4net.Info() method in index.
public class HomeController : Controller
{
static readonly log4net.ILog _log4net =
log4net.LogManager.GetLogger(typeof(HomeController));
public IActionResult index()
{
_log4net.Info("Hello logging world log4net!");
return View();
}
}
Now run the application, and to check if log details written properly
in file you mentioned in <file value="D:\example.log" /> tag
Form design in Razor View, Note: If you specify multiple in input file
field, which means it will allow multiple files to be selected and
uploaded.
<form method="post" enctype="multipart/form-data" asp-
controller="FileUpload" asp-action="index">
<div class="form-group">
<div class="col-md-10">
<p>Upload one or more files using this form:</p>
<input type="file" name="files" multiple />
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="Upload" />
</div>
</div>
</form>
Now you need the folder reference where you want to save all
uploaded image files, and to get that you need an instance of
IHostingEnvironment, so in controller constructor we create the
instance using dependency injection
private readonly IHostingEnvironment _hostingEnvironment;
public fileuploadController(IHostingEnvironment
hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
Note: while creating FileStream object pass file name with folder
Path, if you pass only folder Path in FileStream, You may get
UnauthorizedAccessException while uploading file in asp.net core
application.
using Microsoft.Extensions.FileProviders;
using System.IO;
[HttpPost("FileUpload")]
public async Task<IActionResult> index(List<IFormFile>
files)
{
if (files == null || files.Count == 0)
return Content("file not selected");
long size = files.Sum(f => f.Length);
var filePaths = new List<string>();
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
// full path to file in temp location
var filePath =
Path.Combine(_hostingEnvironment.WebRootPath,
"userimages");
filePaths.Add(filePath);
var fileNameWithPath =
string.Concat(filePath,"\\",formFile.FileName);
Now probably you would like to know how to retrieve and display
any uploaded file from any folder under wwwroot in asp.net core !
Retrieve static files in Asp.net Core
Now we learn how to retrieve image files from any folder under
wwwroot, display images on screen and delete image in asp.net core
web application.
Microservices Characteristic
Any microservice is self independent, deployment and
consumption will not depend on anything, so if you have
multiple micro services as a part of any big enterprise
system, there are chances that you may have same data
duplicated in different micro service, as per micro service
design principal that’s not incorrect design.
So while designing any microservices we should try to
minimize the interaction between the internal microservices,
the less interaction between microservices is better, but in
some situation you may need to integrate other
microservices as per business demand, in such cases make
sure all communication are asynchronous.
Microservices Architecture
As explained earlier micro services are small independent service
that can interact with any number of services or different type of
clients, but to understand it in typical enterprise scenario where
probably we can have any number of micro services and any number
of applications, following picture is the representation of one such
scenario .
Difference between Web API and Microservices
At this point you may think what’s the difference between Web API
and Microservices, because there are many similarities.
The main conceptual difference is, Microservices is an architectural
pattern of building small independent services that can work with
multiple systems, so from business point of view, you can build
multiple Microservices rather than building a big system together.
When API is designed for providing a cross platform data
interoperability mechanism, where Microservices is much bigger
picture.
Now if you think of a big enterprise business, where business
demand is constantly changing, and there are so many
interdependency factors, so maintaining everything in one system
become tough, impact analysis takes lots of time, also there are high
risk involved. And that’s where Microservices makes the job much
easier and easy to maintain, that’s the reason Microservices
architecture is becoming so popular
How to build Microservices
Here I will explain you a simple step of building small microservice
from scratch
Select .Net Core framework and “API ” project, if your operating system
supports docker then you can enable docker otherwise ignore , (if you
are developing on windows 10 then probably you have docker support, if
using windows 7, then please ignore )
Globalization and Localization with Asp.Net Core
Learn how to implement Globalization and Localization in
Asp.Net Core application
What is Localization?
Localization is the process of setting up content for local geography,
continuation process of globalization.
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
});
Localization Setup
To setup localization in controller you need to add following code.
Things to notice
Required namespace
Dependency Injection through constructor
Using the instance of IStringLocalizer
Note:
Like earlier version of Asp.net we still can use resource file (.resx) to
too, the disadvantage of keeping information in resx file is, that every
time we add a new key, we need to compile the assembly for that key to
get reflected, on the other hand using JSON file we can add any key and
use them in razor view without compiling the whole assembly again.
Controller Setup
public
welcomeController(IStringLocalizer<welcomeController>
localizer)
{
_localizer = localizer;
}
Step 1
Right click on your project then "Manage NuGet Packages", and then
add following two packages in your solution
Microsoft.AspNetCore.Localization
Microsoft.AspNetCore.Localization.Routing
Step 2
Open your Startup.cs file and add following code in
"ConfigureServices" method.
public void ConfigureServices(IServiceCollection services)
{
#region Localization
services.AddSingleton<IdentityLocalizationService>();
services.AddLocalization(o =>
{
// We will put our translations in a folder called
Resources
o.ResourcesPath = "Resources";
});
services.AddSingleton<IStringLocalizerFactory,
JsonStringLocalizerFactory>();
services.AddSingleton<IStringLocalizer,
JsonStringLocalizer>();
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFo
rmat.Suffix,
opts => { opts.ResourcesPath = "Resources"; })
.AddDataAnnotationsLocalization(options =>
{
});
#endregion
}
Step 3
You need to write following custom classes for localization in Json
format. Let's create a class with name "JsonLocalization"
using Microsoft.Extensions.Localization;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
namespace WebTrainingRoom
{
class JsonLocalization
{
public string Key { get; set; }
public Dictionary<string, string> LocalizedValue =
new Dictionary<string, string>();
}
public class JsonStringLocalizerFactory :
IStringLocalizerFactory
{
public IStringLocalizer Create(Type resourceSource)
{
return new JsonStringLocalizer();
}
public IStringLocalizer Create(string baseName,
string location)
{
return new JsonStringLocalizer();
}
}
public class JsonStringLocalizer : IStringLocalizer
{
List<JsonLocalization> localization = new
List<JsonLocalization>();
public JsonStringLocalizer()
{
//read all json file
JsonSerializer serializer = new
JsonSerializer();
localization =
JsonConvert.DeserializeObject<List<JsonLocalization>>(File.
ReadAllText(@"Resources/localization.json"));
}
public LocalizedString this[string name]
{
get
{
var value = GetString(name);
return new LocalizedString(name, value ??
name, resourceNotFound: value == null);
}
}
public LocalizedString this[string name, params
object[] arguments]
{
get
{
var format = GetString(name);
var value = string.Format(format ?? name,
arguments);
return new LocalizedString(name, value,
resourceNotFound: format == null);
}
}
public IEnumerable<LocalizedString>
GetAllStrings(bool includeParentCultures)
{
return localization.Where(l =>
l.LocalizedValue.Keys.Any(lv => lv ==
CultureInfo.CurrentCulture.Name)).Select(l => new
LocalizedString(l.Key,
l.LocalizedValue[CultureInfo.CurrentCulture.Name], true));
}
public IStringLocalizer WithCulture(CultureInfo
culture)
{
return new JsonStringLocalizer();
}
private string GetString(string name)
{
var query = localization.Where(l =>
l.LocalizedValue.Keys.Any(lv => lv ==
CultureInfo.CurrentCulture.Name));
var value = query.FirstOrDefault(l => l.Key ==
name);
return
value.LocalizedValue[CultureInfo.CurrentCulture.Name];
}
}
}
Step 4
Now create a class with name “IdentityLocalizationService”. Now
create a class with name “IdentityLocalizationService”, in this class
we have methods that will allow us to access localized string based
on key
using Microsoft.Extensions.Localization;
using System.Reflection;
namespace WebTrainingRoom.Resources
{
public class IdentityLocalizationService
{
private readonly IStringLocalizer _localizer;
public
IdentityLocalizationService(IStringLocalizerFactory
factory)
{
var type = typeof(IdentityResource);
var assemblyName = new
AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create("IdentityResource",
assemblyName.Name);
}
public LocalizedString
GetLocalizedHtmlString(string key)
{
return _localizer[key];
}
public LocalizedString
GetLocalizedHtmlString(string key, string parameter)
{
return _localizer[key, parameter];
}
}
Step 5
en-IN.json
{
"WelcomeMessage": "Namaskar! Apne Ghar Ayyea"
}