[.NET] Sử dụng Papercut-SMTP để test email trong khi develop

Trong quá trình phát triển phần mềm sẽ có rất nhiều tasks liên quan đến việc bạn phải gửi một email ra ngoài. Ví dụ: đang ký tài khoản cần gửi email để kích hoạt, hay khách hàng đặt hàng trên website của bạn.

Bạn có thể test thử quá trình này bằng cách gửi vào email của bạn, hoặc email được thiết lập trước… Tuy nhiên trong quá trình develop, rất có thể gửi nhầm vào email khách hàng, hoặc tốn thời gian setup mail server để test.

https://github.com/ChangemakerStudios/Papercut-SMTP

Papercut-SMTP tool cho phép bạn giả lập email server ngay tại máy của mình, để test xem có nhận được email hay chưa, email có đúng nội dung hay không.

Cách sử dụng khá đơn giản. Chỉ cần cấu hình trong app.config hoặc web.config

Khi bạn sử dụng SMTP trong .NET để gửi email, Papercut-SMTP sẽ đọc được nội dung đó để kiểm tra.

Chúc các bạn thành công.

C# Làm sao thoát khỏi if / switch case quá nhiều?

Câu lệnh điều kiện if hay switch case là thường gặp trong lập trinh. Tuy nhiên khi mà if quá nhiều trong một block code, hay switch case quá nhiều thì nó sẽ gây phức tạp và dễ xảy ra bug. Cũng như khó khăn khi viết Unit Tests. Clean code khuyên rằng không nên dùng quá 4 câu lệnh if trong 1 block code.
Vậy đâu là giải pháp để tránh vấn đề này. Trong .NET có hỗ trợ một kiểu dữ liệu đó là Dictionary. Bạn sẽ gặp đâu đó nói rằng Dictionary còn phức tạp hơn, khó tiếp cận hơn if condition nữa. Điều đó là đúng, tuy nhiên qua các ví dụ dưới đây sẽ giúp bạn thấy dễ dàng làm chủ Dictionary hơn, và tránh phải if else, hay switch case quá nhiều.

Vậy Dictionary là gì?

Dictionary is a data structure for storing a group of objects. Objects are stored as key/value pairs collection which is useful and generic in different object oriented programming languages.

Dictionary can be used for mappings, in-memory cache, tables etc.

Dictionary’s key and value are generic types. In this way delegates can be set as key or value.

Hiểu đơn giản, Dictionary trong C# là một Collections lưu trữ dữ liệu dưới dạng cặp Key – Value. Key đại diện cho 1 khoá giống như chỉ số phần tử của mảng và Value chính là giá trị tương ứng của khoá đó. Ta sẽ dử dụng Key để truy cập đến Value tương ứng.

Chúng ta có bài toán cho phép ứng dụng có thể kết nối đến nhiều loại data source khác nhau. MySql, SqlServer, MongoDb, Redis, Xml…

ConnectionDataHelper.cs

public class ConnectionDataHelper
    {
        public static void ConnectToMySql()
        {
            Console.WriteLine("Connect to MySql");
        }

        public static void ConnectToSqlServer()
        {
            Console.WriteLine("Connect to Sql Server");
        }

        public static void ConnectToMongoDb()
        {
            Console.WriteLine("Connect to MongdoDb");
        }

        public static void ConnectToRedis()
        {
            Console.WriteLine("Connect to Redis");
        }

        public static void ConnectToXml()
        {
            Console.WriteLine("Connect to Xml");
        }
    }

Ví dụ dùng if else.

    
internal class Program
    {
        private static void Main(string[] args)
        {
            DataSource dataSource = DataSource.MySql;
            Console.WriteLine("Connection to DB Source: " + dataSource.ToString());
            if (dataSource == DataSource.MySql)
            {
                ConnectionDataHelper.ConnectToMySql();
            }
            else if (dataSource == DataSource.SqlServer)
            {
                ConnectionDataHelper.ConnectToSqlServer();
            }
            else if (dataSource == DataSource.MongoDb)
            {
                ConnectionDataHelper.ConnectToMongoDb();
            }
            else if (dataSource == DataSource.Redis)
            {
                ConnectionDataHelper.ConnectToRedis();
            }
            else if (dataSource == DataSource.Xml)
            {
                ConnectionDataHelper.ConnectToXml();
            }

            Console.ReadKey();
        }

        private enum DataSource
        {
            MySql,
            SqlServer,
            MongoDb,
            Redis,
            Xml
        }
    }

Cách viết switch case dễ đọc hơn một chút, nhưng vẫn còn dài

internal class Program
    {
        private static void Main(string[] args)
        {
            DataSource dataSource = DataSource.MySql;
            Console.WriteLine("Connection to DB Source: " + dataSource.ToString());
            switch (dataSource)
            {
                case DataSource.MySql:
                    ConnectionDataHelper.ConnectToMySql();
                    break;

                case DataSource.SqlServer:
                    ConnectionDataHelper.ConnectToSqlServer();
                    break;

                case DataSource.MongoDb:
                    ConnectionDataHelper.ConnectToMongoDb();
                    break;

                case DataSource.Redis:
                    ConnectionDataHelper.ConnectToRedis();
                    break;

                case DataSource.Xml:
                    ConnectionDataHelper.ConnectToXml();
                    break;
            }

            Console.ReadKey();
        }

        private enum DataSource
        {
            MySql,
            SqlServer,
            MongoDb,
            Redis,
            Xml
        }
    }

Bây giờ chúng ta thử chuyển sang sử dụng Dictionary.

internal class Program
    {
        private static void Main(string[] args)
        {
            var actionMap = new Dictionary()
            {
                {DataSource.MySql, ConnectionDataHelper.ConnectToMySql},
                {DataSource.SqlServer, ConnectionDataHelper.ConnectToSqlServer},
                {DataSource.MongoDb, ConnectionDataHelper.ConnectToMongoDb},
                {DataSource.Redis, ConnectionDataHelper.ConnectToRedis},
                {DataSource.Xml, ConnectionDataHelper.ConnectToXml},
            };
            DataSource dataSource = DataSource.SqlServer;
            Console.WriteLine("Connection to DB Source: " + dataSource.ToString());
            if (actionMap.ContainsKey(dataSource))
            {
                actionMap[dataSource]();
            }

            Console.ReadKey();
        }

        private enum DataSource
        {
            MySql,
            SqlServer,
            MongoDb,
            Redis,
            Xml
        }
    }

Rõ ràng code đã ngắn gọn hơn rất nhiều. Tất nhiên thực tế các function của chúng ta sẽ phức tạp hơn một chút, có input, output. Bây giờ sửa lại ConnectionDataHelper để nhận vào một connectionString, và return về một trạng thái true/false. IsConnected.

ConnectionDataHelper.cs

    public class ConnectionDataHelper
    {
        public static bool ConnectToMySql(string connectionString)
        {
            Console.WriteLine("Connect to MySql: " + connectionString);
            return true;
        }

        public static bool ConnectToSqlServer(string connectionString)
        {
            Console.WriteLine("Connect to Sql Server: " + connectionString);
            return true;
        }

        public static bool ConnectToMongoDb(string connectionString)
        {
            Console.WriteLine("Connect to MongdoDb: " + connectionString);
            return true;
        }

        public static bool ConnectToRedis(string connectionString)
        {
            Console.WriteLine("Connect to Redis: " + connectionString);
            return true;
        }

        public static bool ConnectToXml(string connectionString)
        {
            Console.WriteLine("Connect to Xml: " + connectionString);
            return true;
        }
    }
internal class Program
    {
        private static void Main(string[] args)
        {
            var actionMap = new Dictionary>()
            {
                {DataSource.MySql, ConnectionDataHelper.ConnectToMySql},
                {DataSource.SqlServer, ConnectionDataHelper.ConnectToSqlServer},
                {DataSource.MongoDb, ConnectionDataHelper.ConnectToMongoDb},
                {DataSource.Redis, ConnectionDataHelper.ConnectToRedis},
                {DataSource.Xml, ConnectionDataHelper.ConnectToXml},
            };
            DataSource dataSource = DataSource.SqlServer;
            Console.WriteLine("Connection to DB Source: " + dataSource.ToString());
            var connectionString = "DataSource=; UserId=; Password=";
            bool isConnected = false;
            if (actionMap.ContainsKey(dataSource))
            {
                isConnected = actionMap[dataSource](connectionString);
            }
            Console.WriteLine("Is Connected" + isConnected);
            Console.ReadKey();
        }

        private enum DataSource
        {
            MySql,
            SqlServer,
            MongoDb,
            Redis,
            Xml
        }
    }

Kết quả:

Chúc các bạn thành công.

Dãy số Fibonacci trong C#

Quy luật của dãy số Fibonacci: số tiếp theo bằng tổng của 2 số trước, 2 số đầu tiên của dãy số là 0, 1. Ví dụ: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …

Sử dụng yield trong C# để trả về dãy số Fibonacci

static void Main()
{
 foreach(var value in Fibonacci())
 {
 Console.Write(value + " ");
 if(value > 1000) 
 {
 break;
 }
 }
}

static IEnumerable<int>  Fibonacci()
{
 int current = 0;
 int next = 1;
 while(true)
 {
 yield return current;
 int oldCurrent = current;
 current = next;
 next = next + oldCurrent;
 } 
}

Kết quả:

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Download Or Save Image File From URL

Hướng dẫn này cho phép bạn có thể download một file ((image,video,zip,pdf,doc,xls,ect) từ một đường dẫn url trên website khác, lưu vào ổ cứng hoặc server của bạn. Demo dưới đây viết bằng ASP.NET C#, sẽ lấy ảnh theo đường dẫn http://tuanitpro.com/wp-content/uploads/2014/09/cardvisit.jpg sau đó lưu và thư mục được chỉ định (thư mục Uploads)

Code

void GetFileFromUrl(string fileName, string url)
    {
        byte[] content;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        WebResponse response = request.GetResponse();

        Stream stream = response.GetResponseStream();
        using (BinaryReader reader = new BinaryReader(stream))
        {
            content = reader.ReadBytes(500000);
            reader.Close();
        }
        response.Close();
        FileStream fs = new FileStream(fileName, FileMode.Create);
        BinaryWriter bw = new BinaryWriter(fs);
        try
        {
            bw.Write(content);

        }
        finally
        {
            bw.Close();
            fs.Close();
        }
    }

Code Button Download

 protected void Button1_Click(object sender, EventArgs e)
    {
        string url = "http://tuanitpro.com/wp-content/uploads/2014/09/cardvisit.jpg";
        string fileName = Server.MapPath("~/Uploads") + "\\mylogo.jpg";
        GetFileFromUrl(fileName, url);

        Response.Write("The file has been saved at: " + fileName);
    }

Entity framework update modified fields only

Coding

 public virtual int Update(T entity, params Expression<func<t, object="">>[] properties)
        {
            if (entity.Id < 1)
            {
                return Insert(entity).Id;
            }
            if (properties?.Any() == true)
            {
                _dbContext.Attach(entity);
                foreach (var prop in properties)
                {
                    _dbContext.Entry(entity).Property(prop).IsModified = true;
                }
            }
            else
            {
                _dbContext.Entry(entity).State = EntityState.Modified;
            }

            return _dbContext.SaveChanges();
        }

        public virtual int Update(T entity, object replaceBy)
        {
            if (entity.Id < 1)
            {
                return Insert(entity).Id;
            }
            if (replaceBy == null)
            {
                return _dbContext.SaveChanges();
            }

            var properties = replaceBy.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);            
            if (properties?.Any() == true)
            {
                foreach (var prop in properties)
                {
                    var valueOfProp = prop.GetValue(replaceBy, null);
                    var propOfEntity = entity.GetType().GetProperty(prop.Name);
                    propOfEntity.SetValue(entity, Convert.ChangeType(valueOfProp, propOfEntity.PropertyType), null);

                    _dbContext.Entry(entity).Property(propOfEntity.Name).IsModified = true;
                }
            }
            else
            {
                _dbContext.Entry(entity).State = EntityState.Modified;
            }

            return _dbContext.SaveChanges();
        }
</func<t,>

Using

var contact = new Contact { Id = 1, FullName = "Le Thanh Tuan" };

var rs1 = contactService.Update(contact, x => x.FullName);

var rs2 = contactService.Update(contact, new
{
	Id = 1,
	Phone = "0976060432",
	UserName = "tuanitpro",                
	FullName = "Le Thanh Tuan"                             
});

Handle errors in ASP.NET Core

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
if (env.IsProduction() || env.IsStaging())
{
app.UseExceptionHandler(options =>
{
options.Run(async context =>
{
context.Response.StatusCode = 500;
context.Response.ContentType = “text/plain”;
await context.Response.WriteAsync(“CONTACT: 097 6060 432”);

var exceptionHandlerPathFeature =
context.Features.Get();
var now = System.DateTime.Now;
var eventLog = new EventLog
{
DateCreated = now,
RequestPath = exceptionHandlerPathFeature?.Path,
IPAddress = context.Request.HttpContext.Connection.RemoteIpAddress.ToString(),
Message = exceptionHandlerPathFeature?.Error.Source
};
string eventLogString = JsonConvert.SerializeObject(eventLog);

eventLogString += exceptionHandlerPathFeature?.Error.StackTrace + “\n\r”;

File.AppendAllText(“log.txt”, eventLogString);

ColorLife.Core.Helpers.IEmailProvider emailProvider = new ColorLife.Core.Helpers.EmailProvider(“[Urgent] Bug “, “[email protected]”);
emailProvider.Send(eventLogString, null);
});
});
app.UseHsts();
}

Sử dụng cache trong ASP.NET MVC với Redis Cache, Memory Cache

Khi lập trình ứng dụng chúng ta hay gặp vấn đề làm sao cho tối ưu tài nguyên của hệ thống, tăng tốc độ trải nghiệm từ phía end user. Đặc biệt là các ứng dụng web.

Cache là gì ? 
Lý thuyết: Cache là tên gọi của bộ nhớ đệm – nơi lưu trữ các dữ liệu nằm chờ các ứng dụng hay phần cứng xử lý. Mục đích của nó  để tăng tốc độ xử lý (có sẵn xài liền không cần tốn thời gian đi lùng sục tìm kéo về).

Thực tế: Cache là các dữ liệu trong phiên làm việc trước của các ứng dụng, chương trình mà hệ điều hành lưu lại nhằm giúp việc tải data trong các phiên làm việc sau được nhanh hơn.

Tip này hướng dẫn các bạn cách implement cache vào ứng dụng, sử dụng thư viện đã được wrap lại từ Memery Cache & Redis Cache

Đầu tiên tải về thư viện tại Nuget: https://www.nuget.org/packages/colorlife.tuanitpro.com/

Hoặc cài đặt trực tiếp trong Visual Studio

Tạo class Customer để test

public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

Sử dụng Memory Cache

  private static void MemoryCache_Customer_Test()
        {
            ICacheProviderFactory cacheProvideractory = new CacheProviderFactory();
            IDataCacheProvider dataCacheProvider = cacheProvideractory.CreateFactory();
            Customer customer = new Customer
            {
                FirstName = "Tuan",
                LastName = "Le"
            };
            string cacheKey = "Memory_Cache_Customer";
            dataCacheProvider.Set(cacheKey, customer);
            Console.WriteLine("Before cache: " + customer.FirstName + " " + customer.LastName);
             
            Console.WriteLine("After Update: " + customer.FirstName + " " + customer.LastName);

            var customerInCache = dataCacheProvider.Get(cacheKey);

            Console.WriteLine("Get Customer In MemoryCache: " + customerInCache.FirstName + " " + customerInCache.LastName);
        }

Sử dụng Radis Cache
Đầu tiên tải Redis cho Windows & cài đặt tại: https://github.com/MicrosoftArchive/redis/releases

Code:

  private static void RedisCache_Customer_Test()
        {
            ICacheProviderFactory cacheProvideractory = new CacheProviderFactory(new CacheProviderOptions
            {
                SlidingExpiration = TimeSpan.FromSeconds(30),
                ConnectionString = "localhost:6379" // mặc định
            }, CacheType.Redis);
            IDataCacheProvider dataCacheProvider = cacheProvideractory.CreateFactory();
            Customer customer = new Customer
            {
                FirstName = "Tuan",
                LastName = "Le"
            };
            string cacheKey = "RedisCache_Customer";
            dataCacheProvider.Set(cacheKey, customer);
            Console.WriteLine("Before cache: " + customer.FirstName + " " + customer.LastName);
            Thread.Sleep(5000);
            customer.LastName = "Le_Updated";
            Console.WriteLine("After Update: " + customer.FirstName + " " + customer.LastName);

            var customerInCache = dataCacheProvider.Get(cacheKey);

            Console.WriteLine("Customer In RedisCache: " + customerInCache.FirstName + " " + customerInCache.LastName);
        }

Thư viện còn hỗ trợ một số chức năng nho nhỏ khác, sẽ nói trong bài viết khác. Chúc các bạn thành công 🙂

Utilities javascript, angualr js

Hướng dẫn convert một Json object về List Object trong javascript JSON. Trường hợp backend trả về 1 object, ví dụ Dictionary…

const jsonObject = {'key1':'value1', 'key2':'value2', 'key3':'value3'};
console.log(jsonObject);
const list = [];
for (const key in jsonObject) {
  if (jsonObject.hasOwnProperty(key)) {
    const temp = {
      Id: key,
      Name: jsonObject[key]
    };
    list.push(temp);
  }
}
console.log(list);

Merge(trộn) 2 object thành 1 object thứ 3, có tất cả thuộc tính & giá trị của 1 & 2.

const resources  = {
  search: 'Search',
  reset: 'Reset',
  save: 'Save change',
  cancel: 'Cancel',
  edit: 'Edit',
  remove: 'Remove',
  add_new: 'Add new',
  tools: 'Tools',        
}
console.log(resources);
const resources_setting = {        
  key: 'Key',
  value: 'Value'        
};
console.log(resources_setting);
function adapter(itemA) {
  for (const key in resources) {
    if (resources.hasOwnProperty(key)) {
      itemA[key] = resources[key];
    }
  }
  return itemA;
}
const resourcesOutput = adapter(resources_setting);
console.log(resourcesOutput);

Cascading Dropdown Ajax

Chào các bạn

Khi lập trình các bạn hay gặp vấn đề khó khăn khi lấy dữ liệu giữa các Dropdown List khác nhau. Ví dụ: Từ tỉnh thành -> quận huyện -> Xã phường…

Đây là khó khăn của rất nhiều bạn sinh viên khi mới bắt đầu học lập trình. Video dưới đây sẽ hướng dẫn bạn cách giải quyết, khá là đơn giản. Hoàn toàn có thể áp dụng nhiều trường hợp khác nhau.

Video không có tiếng, do mình làm trong lúc ngẫu hứng ngoài quán cafe. Các bạn có thể theo dõi, hoặc tải mã nguồn về phân tích thêm.

Slide giới thiệuhttps://docs.google.com/presentation/d/1soxUWN7Xa6Z89Az-PNCtiyGgMVdVSgmqzp1bf7hdi50/edit?usp=sharing

Tài nguyên

SQL Data:

CSDL tên Quốc gia, tỉnh thành phố thị xã quận huyện, xã phường Việt Nam

Demo

Cascading Dropdown Ajax

Code C#

 public class MyDbContext:DbContext
    {
        // Ở đây các bạn có thể khai báo trong Web.config.
        private const string sqlConnection = @"Data Source=.\SQLExpress; Initial Catalog = CountryDb; User Id=sa; Password = sa";

        public MyDbContext() : base(sqlConnection)
        {

        }
      
        public DbSet<Country> Countries { get; set; }
        public DbSet<Province> Provinces { get; set; }
        public DbSet<District> Districts { get; set; }
        public DbSet<Ward> Wards { get; set; }

    }

 

  public JsonResult GetAllCountries()
        {
            using(var db = new MyDbContext())
            {
                var data = db.Countries.OrderBy(x=>x.Name).ToList();
                return Json(data, JsonRequestBehavior.AllowGet);
            }
        }
        /// <summary>
        /// Hàm lấy danh sách tỉnh thành theo CountryId. 
        /// Id = 237 là của Việt Nam. Do database mình quy định vậy
        /// Test OK
        /// </summary>
        /// <param name="id">Id của country</param>
        /// <returns></returns>
        public JsonResult GetAllProvinceByCountryId(int? id=237) 
        {
            using (var db = new MyDbContext())
            {               
                var data = db.Provinces.Where(x=>x.CountryId== id).OrderBy(x=>x.Name).ToList();
                return Json(data, JsonRequestBehavior.AllowGet);
            }
        }
        /// <summary>
        /// Hàm lấy tất cả danh sách quận huyện
        /// Id = 1 là Hà Nội, do database mình quy định vậy
        /// Test OK
        /// </summary>
        /// <param name="id">Id = ProvinceId</param>
        /// <returns></returns>
        public JsonResult GetAllDistrictByProvinceId(int? id = 1)
        {
            using (var db = new MyDbContext())
            {
                var data = db.Districts.Where(x => x.ProvinceId == id).OrderBy(x=>x.Name).ToList();
                return Json(data, JsonRequestBehavior.AllowGet);
            }
        }
        /// <summary>
        /// Hàm lấy danh sách xã phường theo quận huyện
        /// Id= 1 là Ba Đình. Do database quy định
        /// Test OK
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public JsonResult GetAllWardByDistrictId(int? id = 1)
        {
            using (var db = new MyDbContext())
            {
                var data = db.Wards.Where(x => x.DistrictId == id).OrderBy(x=>x.Name).ToList();
                return Json(data, JsonRequestBehavior.AllowGet);
            }
        }

Code js

// File javascript để lấy dữ liệu

// Khai báo URL service của bạn ở đây
var baseService = "/Service";
var countryUrl = baseService + "/GetAllCountries";
var provinceUrl = baseService + "/GetAllProvinceByCountryId";
var districtUrl = baseService + "/GetAllDistrictByProvinceId";
var wardUrl = baseService + "/GetAllWardByDistrictId";
$(document).ready(function () {
    // load danh sách country
    _getCountries();
    $("#ddlCountry").on('change', function () {
        var id = $(this).val();
        if (id != undefined && id != '') {
            _getProvince(id);
        }
    });

    $("#ddlProvince").on('change', function () {
        var id = $(this).val();
        if (id != undefined && id != '') {
            _getDistrict(id);
        }
    });
    $("#ddlDistrict").on('change', function () {
        var id = $(this).val();
        if (id != undefined && id != '') {
            _getWard(id);
        }
    });
    $("#ddlWard").on('change', function () {
        var countryText = $("#ddlCountry option:selected").text();
        var provinceText = $("#ddlProvince option:selected").text();
        var districtText = $("#ddlDistrict option:selected").text();
        var wardText = $("#ddlWard option:selected").text();
        var html = "Quốc gia: " + countryText + " Tỉnh thành: " + provinceText + " " + "Quận huyện: " + districtText + " " + "Xã phường: " + wardText;
        html += "</br>Quê bạn thật là đẹp. Chúc mừng bạn!!!";
        $("#divResult").html(html);
    });
});
function _getCountries() {
    $.get(countryUrl, function (data) {
        if (data != null && data != undefined && data.length) {
            var html = '';
            html += '<option value="">--Không chọn--</option>';
            $.each(data, function (key, item) {
                html += '<option value=' + item.Id + '>' + item.Name + '</option>';
            });
            $("#ddlCountry").html(html);
        }
    });
}
// truyền id của country vào
function _getProvince(id) {
    $.get(provinceUrl + "/"+id, function (data) {
        if (data != null && data != undefined && data.length) {
            var html = '';
            html += '<option value="">--Không chọn--</option>';
            $.each(data, function (key, item) {
                html += '<option value=' + item.Id + '>' + item.Name + '</option>';
            });
            $("#ddlProvince").html(html);
        }
    });
}
// truyền id của province vào
function _getDistrict(id) {
    $.get(districtUrl + "/" + id, function (data) {
        if (data != null && data != undefined && data.length) {
            var html = '';
            html += '<option value="">--Không chọn--</option>';
            $.each(data, function (key, item) {
                html += '<option value=' + item.Id + '>' + item.Name + '</option>';
            });
            $("#ddlDistrict").html(html);
        }
    });
}
// truyền id của district vào
function _getWard(id) {
    $.get(wardUrl + "/" + id, function (data) {
        if (data != null && data != undefined && data.length) {
            var html = '';
            html += '<option value="">--Không chọn--</option>';
            $.each(data, function (key, item) {
                html += '<option value=' + item.Id + '>' + item.Name + '</option>';
            });
            $("#ddlWard").html(html);
        }
    });
}

Chúc các bạn thành công.

Download  GitHub

How to Upload file in Angular

Backend:

Link demo: http://angular.tuanitpro.com/#/uploader

  • Username: tuanitpro
  • Password: 123456

 

uploader.component.css

input[type='file']{
    display: none;
}
#uploader{
    width:100%; color:#fff; 
    font-family:Verdana, Geneva, Tahoma, sans-serif; 
     background:#0094ff;
      text-align:center;
       padding:50px;
        cursor:pointer;
}

uploader.component.html

<div class="container body">
  <div class="main_container">

    <div class="right_col" role="main">


      <div class="">
        <div class="clearfix"></div>
        <div class="row">
          <div class="col-md-12">
            <h2>Angular 4 - Upload file</h2>
          </div>

          <div class="col-md-12 col-sm-12 col-xs-12">
            <div class="x_panel" style="height: auto;">

              <div class="x_content">

                <input type="file" id="fileUploadInput" accept="images/*" (change)="fileChange($event)" />
                <div id="uploader"                    (click)="doUploadFile()">
                 <i class="fa fa-picture-o"></i> {{uploadResult.uploadingText}}
                </div>
                <div class="progress progress-striped" *ngIf="uploadResult.progress > 0">
                  <div class="progress-bar progress-bar-success"  [ngStyle]="{'width':  uploadResult.progress+'%'}">{{uploadResult.progress}}%</div>
                </div>
                <img  *ngIf="uploadResult.fileUrl" src="{{uploadResult.fileUrl}}" style="width:100%;" class="img-response">
              </div>
            </div>
          </div>
        </div>
      </div>





    </div>

  </div>
</div>

uploader.component.ts

import { Component, OnInit } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Http } from '@angular/http';

import $ from 'jquery/dist/jquery.min';

@Component({
  selector: 'app-uploader',
  templateUrl: './uploader.component.html',
  styleUrls: ['./uploader.component.css']
})
export class UploaderComponent implements OnInit {
  uploadingText = 'Chọn file (chỉ chấp nhận file ảnh)';
  uploadResult: any = {
    progress: 0,
    uploadingText: this.uploadingText,
    fileUrl: null
  }
  constructor(private title: Title) { }
  ngOnInit() {
    this.title.setTitle("Angular 4 - Upload file"); 
  }
  doUploadFile() {
    this.uploadResult.progress = 0;
    this.uploadResult.fileUrl = null;
    this.uploadResult.uploadingText = this.uploadingText;
    $("#fileUploadInput").trigger("click");
  }
  fileChange(event) {
    let fileList: FileList = event.target.files;
    if (fileList.length > 0) {
      let file: File = fileList[0];
      let formData: FormData = new FormData();
      formData.append('uploadFile', file);
      let xhr: XMLHttpRequest = new XMLHttpRequest();
      xhr.withCredentials = false;
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            let json = JSON.parse(xhr.response);
            let fileUrl = 'http://minhquandalat.com/uploads/' + json.Name;
            this.uploadResult.progress = 100;
            this.uploadResult.fileUrl = fileUrl;
            this.uploadResult.uploadingText = "Hoàn thành";

          } else {
            console.log(xhr.response);
          }
        }
      };
      xhr.upload.onprogress = (event) => {
        this.uploadResult.uploadingText = "Đang tải ảnh lên...";
        let percentVal = Math.round(event.loaded / event.total * 100);
        this.uploadResult.progress = percentVal;
      };
      xhr.open('POST', "http://minhquandalat.com/api/FileUpload", true);
      xhr.send(formData);
    }
  }
}

Happy coding