@manhng

Welcome to my blog!

Oracle + Net Core

January 17, 2022 14:45

Oracle + Net Core (edit)

  • Clean Architecture
  • CQRS & Mediator in .NET Core
  • MediatR Library
  • DbUp
  • Oracle
  • EF Core
  • Dapper
  • Web API
  • .NET Core
  • Swagger

Clean Architecture CQRS + ORACLE + EF CORE + DAPPER

referbruv/CqrsNinja: CQRS Ninja is a boilerplate solution, built to demonstrate implementing CQRS in ASP.NET Core (.NET 6) via MediatR. (github.com)

Using Entity Framework Core and Dapper in ASP.NET Core - Safe Transactions (codewithmukesh.com)

Dapper in ASP.NET Core with Repository Pattern - Detailed (codewithmukesh.com)

DbUp - @manhng

Mediatr & Mediator - @manhng

ASP.NET Identity

Securing ASP.NET MVC Applications with ASP.NET Identity | CodeGuru

ASP.NET MVC5 - Keeping Users in Oracle Database - Stack Overflow

Script for creating ASP.NET Identity 2.0 tables on OracleDB (github.com)

arichika/AspNet.Identity.Oracle: AspNet.Identity.Oracle for ASP.NET Identity 2.0 with ODP.NET (github.com)

Oracle with EF Core

Oracle (entityframeworkcore.com)

Oracle + Entity Framework Core - @manhng

.NET Core With Oracle Database Using Dapper - @manhng

.NET Core

NuGet Gallery | Microsoft.EntityFrameworkCore 6.0.1

NuGet Gallery | Microsoft.EntityFrameworkCore.Tools 6.0.1

NuGet Gallery | Microsoft.EntityFrameworkCore.Design 6.0.1

NuGet Gallery | Oracle.EntityFrameworkCore 6.21.5

NuGet Gallery | Oracle.ManagedDataAccess.Core 3.21.50

.NET Core 2.1

  • Microsoft.EntityFrameworkCore(2.2.6)
  • Microsoft.EntityFrameworkCore.Design(2.2.6)
  • Microsoft.EntityFrameworkCore.Relational(2.2.6)
  • Microsoft.EntityFrameworkCore.Tools(2.2.6)
  • Oracle.EntityFrameworkCore(2.19.60)
  • Oracle.ManagedDataAccess.Core(2.19.60)

public class DataContext : DbContent {
    public DataContext(DbContextOptions options) : base(options) {}
}

[Table("Test")]
public class TestEntity{
    [Key]
    [Column("id")]
    [MaxLength(36)]
    public string ID{get;set;}
    [Column("text")]
    [MaxLength(50)]
    public string Text{get;set;}
    [Column("count")]
    public int? Count{get;set;}
    ……
}

public class DataContext : DbContent {
    public DataContext(DbContextOptions options) : base(options) {}
    public DbSet<TestEntity> TestEntities {get;set;}
}

  • Microsoft.Extensions.DependencyInjection(6.0.0)
  • Oracle.EntityFrameworkCore(2.19.60)
  • Microsoft.EntityFrameworkCore.Design(2.2.6)

public void ConfigureServices(IServiceCollection Services) {
    ……
    services.AddDbContext<DataContext>(options.UseOracle(Configuration.GetConnectionString("OracleConnectionString")));
    ……
}

  • Add-Migration AddTestEntity
  • Update-Database

.NET Framework

NuGet Gallery | Oracle.ManagedDataAccess 21.5.0

  • Oracle.ManagedDataAccess.Client

Dapper

ASP.NET Core Web API with Oracle Database and Dapper | Mukesh Kumar

.NET Core + EF Core + DbContext

Entity Framework Core creating model from existing Oracle database - Stack Overflow

  • Oracle.EntityFrameworkCore
  • Oracle.ManagedDataaccess.Core
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Tools
PM> Scaffold-DbContext "User Id=test;Password=test;Data Source=localhost:1521/orcl;" 

-Provider Oracle.EntityFrameworkCore

-OutputDir Models 

-Context TestDbContext 

-Tables USER 

sql - How to create id with AUTO_INCREMENT on Oracle? - Stack Overflow

c# - How to connect to an Oracle database Connection from .Net Core - Stack Overflow

using Oracle.ManagedDataAccess.Client;

public void Execute(string queryString, string connectionString)
{
    using (OracleConnection connection = new OracleConnection(connectionString))
    {
        OracleCommand command = new OracleCommand(queryString, connection);
        command.Connection.Open();
        command.ExecuteNonQuery();
    }
}

ORACLE ID AUTO INCREMENT

I've used sequences and triggers - it was the only solution that seemed to work.

sql - How to create id with AUTO_INCREMENT on Oracle? - Stack Overflow

ovidiubuligan/EntityFramework_Oracle_sample: A minimal sample project with c# ,entity framework, and oracle 11g (github.com)

ASP.NET Core Web API with Oracle Database and Dapper

This article will focus on how to create Asp.Net Core Web API to get data from Oracle database using Dapper ORM. First thing, here we are not using SQL, because of so many articles available on Internet where mostly SQL server is using for demonstration. So, we think, let write one article where we will use Oracle as a database. To reduce the complexity of database access logic we are using Dapper ORM. So, let's move to practical demonstration.

Create Asp.Net Core Web API Project

To create a new project in Asp.Net Core Web API. Just open Visual Studio 2017 version 15.3 and we have to follow below steps.

  1. Go to File menu and click to New and then choose Project.
  2. From the New Project window, first, you have to choose .Net Framework 4.6 or above version and then from the left panel, choose Visual C# and then .Net Core.
  3. From the right panel, choose “Asp.Net Core Web Application” and provide the save location where you want to save project and click OK.
  4. From the next windows, which will provide you different kinds of the template, you have to choose Web API.

Now click to OK. It will take few minutes to configure Asp.Net Core Web API project.

Setup Oracle Table and Stored Procedures

To create database and tables for this demonstration, we are using Oracle Developer Tools. It is very lightweight and flexible which help us to work with database smoothly.  

As per Oracle

Oracle SQL Developer is a free, integrated development environment that simplifies the development and management of Oracle Database in both traditional and Cloud deployments. SQL Developer offers complete end-to-end development of your PL/SQL applications, a worksheet for running queries and scripts, a DBA console for managing the database, a reports interface, a complete data modeling solution, and a migration platform for moving your 3rd party databases to Oracle. 

 

Create a database name call it "TEST_DB" and inside that create a table name as "EMPLOYEE". You can use the following syntax to create the table inside "TEST_DB" database.

  CREATE TABLE "TEST_DB"."EMPLOYEE" 
   (	
    "ID" NUMBER(10,0) GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 100 CACHE 20 NOORDER  NOCYCLE , 
	"NAME" VARCHAR2(255 BYTE), 
	"SALARY" NUMBER(10,0), 
	"ADDRESS" VARCHAR2(500 BYTE)
   ) SEGMENT CREATION IMMEDIATE 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "TEST_DATA" ;

Need to add some dummy records inside the tables, so that we can directly get the data from PostMan. So, we are adding four records here as follows.

Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (100,'Mukesh',20000,'India');
Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (101,'Rion',28000,'US');
Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (102,'Mahesh',10000,'India');
Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (103,'Banky',20000,'India');

Now its time to create one SP which will bring the list of employees records. Here we are using Cursor for returning list of data as an output parameter.

CREATE OR REPLACE PROCEDURE "TEST_DB"."USP_GETEMPLOYEES" (
    EMPCURSOR OUT SYS_REFCURSOR
)
AS
Begin
Open EMPCURSOR For
SELECT ID, NAME, SALARY,ADDRESS FROM Employee;
End;

Now going to create one SP which will get the individual record for an employee based on their employee id. 

CREATE OR REPLACE PROCEDURE "TEST_DB"."USP_GETEMPLOYEEDETAILS" 
(
  EMP_ID IN INT,
  EMP_DETAIL_CURSOR OUT SYS_REFCURSOR  
) AS 
BEGIN
    OPEN EMP_DETAIL_CURSOR FOR
    SELECT ID, NAME, SALARY,ADDRESS FROM Employee WHERE ID = EMP_ID;
END;

Install Dapper ORM

Open "Package Manager Console" from the "Nuget Package Manager" of Tools menu and type following command and press enter to install dapper and its dependencies if have.

Install-Package Dapper -Version 1.50.5

After installation, you can check with references section of the project. One reference as "Dapper" has added inside that.

Install Oracle Manage Data Access for Core

As we are using Asp.Net Core Web API application with Oracle and need to access Oracle database from the Core application. To use Oracle database with .Net Core application, we have Oracle library which will help us to manage logic of database access. So, we have to install following package that is beta version. 

Install-Package Oracle.ManagedDataAccess.Core -Version 2.12.0-beta2

Add Oracle Connection

Now we have everything ready related to the database like the database, tables, and SPs etc. To access the database from Web API, we have to create connection string as usual inside the "appsettings.json" file. 

{
  "Logging": {
    "IncludeScopes": false,
    "Debug": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning"
      }
    }
  },
  "ConnectionStrings": {
    "EmployeeConnection": "data source=mukesh:1531;password=**********;user id=mukesh;Incr Pool Size=5;Decr Pool Size=2;"
  }
}

Create Repositories

To keep the separation of concern in mind, we are using Repository here. Create a new folder as "Repositories" inside the Web API project and create an interface as "IEmployeeRepository" and a class as "EmployeeRepository" which will implement to IEmployeeRepository. 

namespace Core2API.Repositories
{
    public interface IEmployeeRepository
    {
        object GetEmployeeList();

        object GetEmployeeDetails(int empId);
        
    }
}

Following is the EmployeeRepository class which is implementing IEmployeeRepository. To access configuration, we are injecting IConfiguration in the constructor. So, we have configuration object is ready to use. Apart from that we have GetConnection() method which will get the connection string from the appsettings.json and provide it to OracleConnection to create a connection and finally return connection. As we have implemented "IEmployeeRepository" which have two methods as GetEmployeeDetails and GetEmployeeList.

using Core2API.Oracle;
using Dapper;
using Microsoft.Extensions.Configuration;
using Oracle.ManagedDataAccess.Client;
using System;
using System.Data;


namespace Core2API.Repositories
{
    public class EmployeeRepository : IEmployeeRepository
    {
        IConfiguration configuration;
        public EmployeeRepository(IConfiguration _configuration)
        {
            configuration = _configuration;
        }
        public object GetEmployeeDetails(int empId)
        {
            object result = null;
            try
            {
                var dyParam = new OracleDynamicParameters();
                dyParam.Add("EMP_ID", OracleDbType.Int32, ParameterDirection.Input, empId);
                dyParam.Add("EMP_DETAIL_CURSOR", OracleDbType.RefCursor, ParameterDirection.Output);

                var conn = this.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    conn.Open();
                }

                if (conn.State == ConnectionState.Open)
                {
                    var query = "USP_GETEMPLOYEEDETAILS";

                    result = SqlMapper.Query(conn, query, param: dyParam, commandType: CommandType.StoredProcedure);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return result;
        }

        public object GetEmployeeList()
        {
            object result = null;
            try
            {
                var dyParam = new OracleDynamicParameters();

                dyParam.Add("EMPCURSOR", OracleDbType.RefCursor, ParameterDirection.Output);

                var conn = this.GetConnection();
                if(conn.State == ConnectionState.Closed)
                {
                    conn.Open();
                }

                if (conn.State == ConnectionState.Open)
                {
                    var query = "USP_GETEMPLOYEES";

                    result = SqlMapper.Query(conn, query, param: dyParam, commandType: CommandType.StoredProcedure);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return result;
        }

        public IDbConnection GetConnection()
        {
            var connectionString = configuration.GetSection("ConnectionStrings").GetSection("EmployeeConnection").Value;
            var conn = new OracleConnection(connectionString);           
            return conn;
        }
    }
}
public IDbConnection GetConnection()
{
     var connectionString = configuration.GetSection("ConnectionStrings").GetSection("EmployeeConnection").Value;
     var conn = new OracleConnection(connectionString);           
     return conn;
}

To use Oracle datatypes with .Net Core, we are using OracleDyamicParameters class which will provide the list of function to manage Oracle parameters behaviors. 

using Dapper;
using Oracle.ManagedDataAccess.Client;
using System.Collections.Generic;
using System.Data;

namespace Core2API.Oracle
{
    public class OracleDynamicParameters : SqlMapper.IDynamicParameters
    {
        private readonly DynamicParameters dynamicParameters = new DynamicParameters();
        private readonly List<OracleParameter> oracleParameters = new List<OracleParameter>();

        public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction, object value = null, int? size = null)
        {
            OracleParameter oracleParameter;
            if (size.HasValue)
            {
                oracleParameter = new OracleParameter(name, oracleDbType, size.Value, value, direction);
            }
            else
            {
                oracleParameter = new OracleParameter(name, oracleDbType, value, direction);
            }

            oracleParameters.Add(oracleParameter);
        }

        public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction)
        {
            var oracleParameter = new OracleParameter(name, oracleDbType, direction);
            oracleParameters.Add(oracleParameter);
        }

        public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
        {
            ((SqlMapper.IDynamicParameters)dynamicParameters).AddParameters(command, identity);

            var oracleCommand = command as OracleCommand;

            if (oracleCommand != null)
            {
                oracleCommand.Parameters.AddRange(oracleParameters.ToArray());
            }
        }
    }
}

Configure Dependencies in Startup.cs

To access the dependencies on the controller or repository classes, we have to configure or we can say register our dependency classes with interfaces inside the ConfigureServices method of Startup class. 

using Core2API.Repositories;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Core2API
{
    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.AddTransient<IEmployeeRepository, EmployeeRepository>();
            services.AddSingleton<IConfiguration>(Configuration);
            services.AddMvc();
        }

        // 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.UseMvc();
        }
    }
}

Add EmployeeController

Now its time to finally create API call in EmployeeControler. First, we have added IEmployeeRepository inside the constructor to use dependencies. Secondly, we have to create API call with Route attribute for both methods.

using Core2API.Repositories;
using Microsoft.AspNetCore.Mvc;

namespace CoreAPI.Controllers
{
    [Produces("application/json")]    
    public class EmployeeController : Controller
    {
        IEmployeeRepository employeeRepository;
        public EmployeeController(IEmployeeRepository _employeeRepository)
        {
            employeeRepository = _employeeRepository;
        }

        [Route("api/GetEmployeeList")]
        public ActionResult GetEmployeeList()
        {
            var result = employeeRepository.GetEmployeeList();
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);            
        }

        [Route("api/GetEmployeeDetails/{empId}")]
        public ActionResult GetEmployeeDetails(int empId)
        {
            var result = employeeRepository.GetEmployeeDetails(empId);
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);
        }
    }
}

Now we have ready everything like repository is ready, connection with Oracle database is ready and finally, API call is also ready inside the controller. So, its time to run the API and see the result in PostMan. Just press F5 to run the Web API and open PostMan to test the result.

To test in PostMan, first, choose "Get" as a method and provide the URL to get the list of employee records and click to SEND button which will make a request to our API and get the list of employees which we have added at the beginning while creating the database scripts.

To get the single employee record, just pass the following URL as you can see in the image. You can see here, we want to see the record for employee id 103. Once you send the request, you can see the output something like as below.

Conclusion

So, today we have learned how to create Asp.Net Core Web API project and use Dapper with Oracle database.

I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends.

ASP.NET Core Web API with Oracle Database and Dapper | Mukesh Kumar

Getting Started with ODP.Net Core (oracle.com) (Source Code)

Entity Framework Code First and Code First Migrations for Oracle Database (Source Code)

Entity Framework Core Database-First Tutorial for .NET Core for Oracle (devart.com)

Connect to Oracle database from .NET core application. – taithienbo

CRUD Operations In ASP.NET Core-3.1 Using Oracle Database (c-sharpcorner.com)

CKEditor

May 24, 2020 09:16

CKEditor (edit)

https://vkhangyang.wordpress.com/2012/07/14/su-dung-ckeditor-vo-ung-dung-asp-net-mvc-3/

https://vkhangyang.wordpress.com/2012/07/09/thm-xa-sua-nhanh-chng-voi-asp-net-mvc-3/

https://vkhangyang.wordpress.com/2016/12/31/su-dung-ckeditor-vao-ung-dung-asp-net-core/

Upload Files in ASP.NET Core Web API

November 11, 2019 23:07

Upload Files in ASP.NET Core Web API (edit)

https://ilclubdellesei.blog/2018/02/14/how-to-upload-images-to-an-asp-net-core-rest-service-with-xamarin-forms/

https://github.com/phenixita/IC6.Xamarin.PictureUpload

https://dotnetthoughts.net/attribute-routing-in-aspnet-core/

Controller in ASP.NET Core Web API

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

namespace AspNetCoreWebApi.Controllers
{
/// <summary>
///
/// </summary>
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ILogger<ValuesController> _logger;

public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;

_logger.LogInformation("ValuesController called.");
}

[HttpGet]
[Route("api/Values/")]
public IActionResult Get()
{
return Ok("Success");
}

/// <summary>
///
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost]
[Route("/Values/PostFile")]
public IActionResult PostFile(IFormFile file)
{
_logger.LogInformation("ValuesController.PostFile method called.");

var inputStream = file.OpenReadStream();

string fileName = file.FileName;

string filePath = Utils.GenerateFilePathInDesktop(fileName);

if (!string.IsNullOrWhiteSpace(filePath))
{
using (FileStream outputFileStream = new FileStream(filePath, FileMode.Create))
{
inputStream.CopyTo(outputFileStream);

return Ok("OK");
}
}

return Ok("Error.");
}

/// <summary>
///
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost]
[Route("/Values/UploadFile")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
byte[] byteArray;

using (var ms = new MemoryStream())
{
await file.CopyToAsync(ms);

byteArray = ms.ToArray();

string fileName = file.FileName;

string filePath = Utils.GenerateFilePathInDesktop(fileName);

if (!string.IsNullOrWhiteSpace(filePath))
{
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(byteArray, 0, byteArray.Length);

return Ok("OK");
}
}

return Ok("Error.");
}
}
}

public static class Utils
{
public static string GenerateFilePathInDesktop(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName)) return string.Empty;

if (!fileName.Contains(".")) return string.Empty;

var arr = fileName.Split(new char[] { '.' });

var fileNameWithoutExt = arr[0];

var fileExtension = arr[1];

string filePath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) +
@"\" + string.Format("{0}_{1}.{2}", fileNameWithoutExt, System.DateTime.Now.ToString("yyyyMMddhhmmss"), fileExtension);

return filePath;
}
}
}

Test

using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

namespace AspNetCoreWebApi.Test
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine(System.DateTime.Now.ToString("yyyyMMddhhmmss"));

UploadFiles();
}

private static void UploadFiles()
{
string endpoint = "https://localhost:44306/Values/PostFile/";

string filePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\" + "DATA.xlsx";

string fileName = System.IO.Path.GetFileName(filePath);

bool isSuccessUpload = false;

using (FileStream stream = File.Open(filePath, FileMode.Open))
{
IApiService apiService = new ApiService();

Task<bool> task = apiService.UploadImageAsync(endpoint, stream, fileName);

task.Wait();

isSuccessUpload = task.Result;
}

Console.WriteLine(isSuccessUpload ? "Done!" : "Failed.");
}
}

public interface IApiService
{
Task<bool> UploadImageAsync(string uri, Stream image, string fileName);
}

public class ApiService : IApiService
{
public async Task<bool> UploadImageAsync(string uri, Stream image, string fileName)
{
HttpContent fileStreamContent = new StreamContent(image);
fileStreamContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name = "file", FileName = fileName };
fileStreamContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileStreamContent);
var response = await client.PostAsync(uri, formData);
return response.IsSuccessStatusCode;
}
}
}
}

Scaffolding engine for .NET Core built in C#

January 3, 2019 17:21

CatFactory.SqlServer (edit)

CatFactory it's a scaffolding engine for .NET Core built in C#.

https://github.com/hherzl/CatFactory.SqlServer

https://www.codeproject.com/Tips/1162346/Scaffolding-Stored-Procedures-with-CatFactory-SqlS

 

Hệ sinh thái .NET

December 28, 2018 14:54

Hệ sinh thái .NET (edit)

https://goatysite.wordpress.com/2016/07/09/gioi-thieu-net-core-va-asp-net-corephan-1-lam-quen-va-thiet-lap-moi-truong/

https://goatysite.wordpress.com/2016/07/09/gioi-thieu-net-core-va-asp-net-corephan-2-phan-biet-net-framework-net-core-va-mono/

1. Lời nói đầu

.NET core được xác định là phiên bản tương lai của .NET nên trong những năm tới Microsoft (và cộng đồng .NET nói chung) sẽ dành đầu tư chủ yếu vào nền tảng này. Mặc dù .NET Framework truyền thống vẫn sẽ được hỗ trợ (trong thời gian dài), việc tìm hiểu về nền tảng mới này rất có ích cho bạn dù bạn có đang cần sử dụng nó hay không.

Nếu như những công nghệ mà bạn đang sử dụng vẫn phục vụ tốt nhu cầu của bạn thì bạn nên tiếp tục sử dụng chúng. Tuy nhiên, việc tìm hiểu những công nghệ khác để mở rộng hiểu biết luôn là điều tốt.

Mình đã từng gặp rất nhiều những người đã làm việc với .NET lâu năm nhưng vẫn mù mờ về những khái niệm, định nghĩa của Framework. Điều này rất nguy hiểm vì nó gây ra việc hiểu sai về nền tảng, dẫn đến việc sản sinh ra những phần mềm chất lượng không cao. Do đó hiểu rõ về framework của mình là trách nhiệm của bất cứ lập trình viên nào.

2. Các thành phần cơ bản của .NET:

  • Runtime (môi trường hoạt động)
  • Libraries (thư viện)
  • Toolings (công cụ phát triển)

3. Cần hiểu được làm thế nào .NET có thể chạy được đoạn code C# (hay VB, F#) mà bạn viết ra?

dot_net_application_compilation-707676

4. Phân biệt .NET Framework, .NET Core, và Mono

aspnetcoretoday

Điểm mới trong .NET Core (C#)

July 27, 2018 10:25

Điểm mới trong .NET Core (C#) (edit)

Hôm nay mình sẽ giới thiệu từ mới để các bạn tự khám phá trong ASP.NET Core 2.1

  • Span<T>
  • Memory<T>
  • ReadOnlySpan<T>

Properties

// Normal way
public string FullName
{
    get { return string.Format("{0} {1}", FirstName, LastName); }
}
 
// Using Expression (C# 6.0)
public string FullName => string.Format("{0} {1}", FirstName, LastName);
 
// Above code can be more consize using string interpolation
public string FullName =>$"{FirstName} {LastName}";

Methods

// Normal way
public string GetFullName(string firstname, string middleName, string lastName)
{
    return middleName == null ? $"{firstname} {lastName}" : $"{firstname} {middleName} {lastName}";
}
 
// Using Expessions
public string GetFullName(string firstname, string middleName, string lastName) => middleName == null ?
             $"{firstname} {lastName}" : $"{firstname} {middleName} {lastName}";

Auto properties

public string Name { get; set; }

Constructor (hàm tạo)

// Earlier
public Person(string name)
{
    this.Name = name;
}
 
// With C# 7.0
public Person(string name) => this.Name = name;

Destructor (hàm hủy)

// Earlier
~Person()
{
    Console.WriteLine("Person's destructor");
}
 
// Using Expressions
~Person() => Console.WriteLine("Person's destructor");

Readonly struct

public readonly struct Person
{
    public string FirstName { get; }
 
    public string LastName { get; }
 
    public int Age { get; }
 
    public Person(string firstName, string lastName, int age)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.Age = age;
    }
 
}

Ôn lại lý thuyết về Const, ReadOnly, Static và Struct

Const là một hằng số phải gán giá trị khi khai báo (complie-time constant). Mặc định const là static nên không thể thêm static trước hoặc sau const

ReadOnly là một biến được khởi tạo giá trị khi khai báo và có thể thay đổi giá trị ở hàm tạo (run-time constant).

Static đưa vào trước biến để mọi đối tượng đều có thể truy xuất vào. Chỉ áp dụng cho class, fields, properties, operators, events, constructor, không áp dụng được cho destructor và index

Struct:

Kinh nghiệm xử lý try catch throw exception

Đơn giản chỉ cần "throw;" try { ... } catch (Exception ex) { throw; }

Nếu sử dụng "throw ex;" sẽ mất stack trace dẫn đến việc debug lỗi gặp khó khăn.

Kinh nghiệm xử lý Concurrency Conflickts trong EF Core

https://docs.microsoft.com/en-us/ef/core/saving/concurrency

Kinh nghiệm xử lý Concurrency Conflicts trong EF 6

https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application

Làm thế nào để kiểm soát optimistic concurrency.

Bạn cần có một cột rowversion là một kiểu dữ liệu timestamp.

SQL Server tự động khởi tạo số nhị phân duy nhất bất cứ khi nào thao tác insert hoặc update được thực hiện trong một bảng.

https://www.codeproject.com/Articles/817432/Optimistic-Concurrency-in-Entity-Framework-Code-Fi

Technical Stack là gì?

Stack là gì? Stack là một nền tảng hệ điều hành và những phần mềm đi kèm

ELK Stack là gì?

ELK Stack là tập hợp 3 phần mềm đi chung với nhau, phục vụ cho công việc logging. Ba phần mềm này lần lượt là:

  • Elasticsearch: Cơ sở dữ liệu để lưu trữ, tìm kiếm và query log
  • Logstash: Tiếp nhận log từ nhiều nguồn, sau đó xử lý log và ghi dữ liệu và Elasticsearch
  • Kibana: Giao diện để quản lý, thống kê log. Đọc thông tin từ Elasticsearch

SQL tiếng Việt

https://www.mastercode.vn/blog/sql-server/

Xóa log file của SQL Server

https://www.mastercode.vn/blog/web-development/giam-dung-luong-tren-he-thong-server-xoa-cac-file-khong-can-thiet.97

Caching

Các loại Local Cache Store

  • In-process
  • Out-of-process

Các loại Remote Cache

  • Memcached
  • Azure
  • DiskCache
  • Redis

Top 10 OWASP (link tiếng Việt)

  1. Injection
  2. Cross-Site Scripting (XSS)
  3. Broken Authentication and Session Management
  4. Insecure Direct Object References
  5. Cross-Site Request Forgery (CSRF)
  6. Security Misconfiguration
  7. Insecure Cryptographic Storage
  8. Failure to Restrict URL Access
  9. Insufficient Transport Layer Protection
  10. Unvalidated Redirects and Forwards

Tìm hiểu thêm

C# 6.0 features

C# 7.X features

Học .NET Core qua các ví dụ

January 26, 2018 16:11

Học ASP.NET Core qua các ví dụ

Định nghĩa môi trường (QA, DEV, UAT) cho ứng dụng ASP.NET Core MVC

http://www.talkingdotnet.com/define-a-custom-environment-in-asp-net-core/

Sử dụng HttpClient trong ứng dụng ASP.NET Core MVC

https://www.stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore

https://www.stevejgordon.co.uk/httpclientfactory-named-typed-clients-aspnetcore

Sử dụng EF Core trong .NET Core

http://www.thereformedprogrammer.net/a-library-to-run-your-business-logic-when-using-entity-framework-core/

Sử dụng Dapper trong .NET Core

https://www.davepaquette.com/archive/2018/01/22/loading-an-object-graph-with-dapper.aspx

https://github.com/AspNetMonsters/DapperSeries

Học ASP.NET MVC qua các ví dụ

Using ASP.NET Membership Provider for authentication desktop/mobile app

https://github.com/tungnt185/ServerDemoApp

Web API Demo Download Upload Image using jQuery AJAX

https://github.com/tungnt185/WebAPIImageDemo

Categories

Recent posts