Azure Cloud Service Worker Role ile Sql Db’den Kurlara Göre TL Karşılığını Bulma Part2
Selamlar;
Bir önceki makalede bir şirketin farklı kurlardaki ürün kayıtlarına, azure cloud service kullanarak belirli bir zaman aralığı ile baktık. Eğer işlem yapılmamış kayıt var ise o an ki güncel kur değerlerini bulup ilgili fiyat ile çarptık. Böylece ürünlerin TL karşılıklarını bulduk. Bugün ilgili ürün giriş ekranını, listelenmesini ve kaydedilmesini Mvc6.0, AngularJS ve Code First kullanarak yapacağız. Daha sonra güncellenen ürünleri tüm clientlara signalR websocet teknolojisini kullanarak göndereceğiz.
Öncelikle var olan solution’a boş bir mvc web projesi ekliyoruz. HomeController.cs ve Index.cshtml :
Angular.js’i nuget’den projemize ekliyoruz. Ben AngularJS v1.3.8 versiyonunu indirdim.
Öncelikle ExportProductDetail database tablomuzun View Model karşılığını AngularJS’de $scope.Product olarak yaratıyoruz. $scope.ProductList[] ise kaydettiğimiz her bir product’ı ekleyeceğimiz liste. İlerde bu ProductList[]’i sıralayarak ürün listesini göstereceğiz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@{ ViewBag.Title = "Index"; } <script src="~/Scripts/angular.min.js"></script> <script> (function (angular) { function MainController($scope, $http) { $scope.ProductList = []; $scope.Product = function () { ProductName, Price, ExchangeType, ExchangeRate, PriceTL, CreatedDate, UpdateDate }; }; var app = angular.module("app", []); app.controller("MainController", ["$scope", "$http", MainController]); })(angular); </script> |
Aşağıda ürün giriş kısmının yazıldığı html kodlamayı görmektesiniz. Veri girişi yapılan Input alanlar ng-model ile ilgili ViewModel’in propertylerine bağlanmaktadır. Kur tipleri için yine <select> html elementi ViewModel’de ilgili olan Product.ExchangeType’a bağlanmıştır. Ve en sona Save button’u konmuştur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<h2>Ürün Giriş</h2> <hr /> <div class="Main" ng-app="app" ng-controller="MainController"> <table> <tr><td>Product Name:</td><td><input type="text" ng-model="Product.ProductName" class="name"></td></tr> <tr><td>Price:</td><td><input type="text" ng-model="Product.Price"></td></tr> <tr> <td>ExchangeType:</td> <td> <select ng-model="Product.ExchangeType"> <option value=1>$</option> <option value=2>€</option> <option value=3>£</option> </select> </td> </tr> <tr><td><input type="button" value="Save" ng-click="Save(Product)" /></td><td></td></tr> </table> <hr /> |
Save Button’u click işleminde ng-click=”Save(Product)” function’ı girilen yeni product’ı parametre olarak göndererek $scope.ProductList = []‘e aşağıdaki gibi eklemektedir. Daha sonra Product model null’a atanıp yeni kayıt girişi için ProductName’e class’ı ile erişilip odaklanılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$scope.Save = function (_product) { $scope.Show = true; $scope.ProductList.push({ ProductName: _product.ProductName, Price: _product.Price, ExchangeType: _product.ExchangeType, ExchangeRate: _product.ExchangeRate, PriceTL: _product.PriceTL, CreatedDate: getDateTime(), UpdateDate: _product.UpdateDate }); $scope.Product = null; $('.name').focus(); }; |
Şimdi sıra geldi girilen ürünlerin sıralanmasına. Aşağıda table içine ilgili ExportProductDetail tablosunun kolonları başlık olarak konmuştur. Tüm liste ProductList’den tek tek ng-repeat directive ile alınıp prod’a atılmakta ve tüm kolonlar sayfaya basılmaktadır. Önemli bir konu ExchangeType kolonu için ‘prod.ExchangeType | moneyType’ custom filter’ı kullanılmıştır. Amaç 1,2,3 şekilinde gelen döviz tiplerini ‘$’,’€’,’£’ şeklinde göstermektir. İlgili kodlar aşağıdadır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<div class="productList" ng-show="Show"> <h2>Ürün Listesi</h2> <input type="button" value="Save All Product" ng-click="SaveAll(ProductList)"><table> <tr> <th>ProductName |</th> <th>Price |</th> <th>ExchangeType |</th> <th>ExchangeRate |</th> <th>PriceTL |</th> <th>CreatedDate |</th> <th>UpdateDate</th> </tr> <tr ng-repeat="prod in ProductList"> <td>{{prod.ProductName}}</td> <td>{{prod.Price}}</td> <td>{{prod.ExchangeType | moneyType}}</td> <td>{{prod.ExchangeRate}}</td> <td>{{prod.PriceTL}}</td> <td>{{prod.CreatedDate}}</td> <td>{{prod.UpdateDate}}</td> </tr> </table> </div> |
[moneyType] Custom Filter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
app.filter("moneyType", function () { return function (input) { switch (input) { case '1': return '$'; break; case '2': return '€'; break; case '3': return '£'; break; }; }; }); |
Örnek ekran görüntüsü aşağıdadır.
Save All Product button’una basılınca ng-click=”SaveAll(ProductList)” function’ı çalıştırılır. Eklenmiş olan tüm productlar Controller.cs’in SaveProduct methoduna gönderilir.
1 2 3 4 5 6 7 8 9 |
$scope.SaveAll = function (_productList) { $http({ method: 'POST', url: "/Home/SaveProdut", data: _productList }).success(function (result) { alert(result); }) conso |
Yeni eklenen tüm productlar database’e önceki makalede hazırlanan CodeFirst ile AddRange() methodu kullanılarak eklenir ve kaydedilir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using DAL; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace ProductList.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } public string SaveProdut(List<ExportProductDetail> productList) { try { using (ProductContext dbContext=new ProductContext()) { dbContext.ExportProductDetail.AddRange(productList); dbContext.SaveChanges(); } return "All data Saved!"; } catch (Exception ex) { return ex.Message; } } } } |
Bundan sonra önceki makalede Azure Cloud Service ile yazılan uygulama her 30sn de bir database’i kontrol edip, yeni eklenen ürünlerin TL karşılıklarını bulacaktır. Database’e eklenen ürünlerin sorgu sonucu aşağıdadır.
Service çalıştıktan sonraki kayıt durumu:
Şimdi sıra geldi TL karşılıkları bulunan bu dataların o an bağlı olan tüm clientlara bildirmesine. Burda signalR websocket kullanılacaktır.
Öncelikle nuget’den aşağıdaki paketler indirilir.
SignalR’ın çalışması için Startup.cs’e alttaki kodlar konur:
1 2 3 4 5 6 7 |
class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } |
Client’ın product sayfasına gelince, var olan kayıtlı ürünlerin listelenmesi için ilgili data db’den çekilip sadece gelen client’a signalR ile basılır. İlgili kodlar aşağıdaki gibi dir. Ürünler code first ile çekildikten sonra product list’e doldurulur. Daha sonra ilgili product list o an bağlanan client’ın sayfasındaki getAllProducts() functionına parametre olarak gönderilir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class GetProducts : Hub { public override async Task OnConnected() { List<ExportProductDetail> productList = new List<ExportProductDetail>(); using (ProductContext dbContext = new ProductContext()) { foreach (var item in dbContext.ExportProductDetail.ToList()) { ExportProductDetail model = new ExportProductDetail(); model.CreatedDate = item.CreatedDate; model.ID = item.ID; model.ExchangeRate = item.ExchangeRate; model.ExchangeType = item.ExchangeType; model.Price = item.Price; model.PriceTL = item.PriceTL; model.ProductName = item.ProductName; model.UpdateDate = item.UpdateDate; productList.Add(model); } } await Clients.Caller.getAllProducts(productList); } } |
Şimdi sıra geldi client side Index.cstml’de ilgili productları listelemeye. Öncelikle aşağıdaki scriptler sayfaya eklenir.
1 2 3 4 |
<script src="~/Scripts/angular.min.js"></script> <script src="~/Scripts/jquery-2.1.3.min.js"></script> <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> <script src="~/signalr/hubs"></script> |
Client side tarafındaki getAllProducts() sayesinde sayfa ilk yüklendiğinde yani client signalR’a connect olduğunda databasedeki tüm ürünler aşağıda görülen function ile listelenir. $.connection.getProducts, server side’daki Hub classındaki GetProducts’a karşılık gelmektedir. Tüm çekilen liste önceki makalede bahsedilen $scope.ProductList’e eklenir. Böylece bunu kullanan table ilgili ürünleri listeler. $scope.$apply() kodunun eklenmesi bu modeli kullanan nesnelerin rebind’ı için önemlidir. $scope.Show, gizlenen table’ın yeni data gelmesinden dolayı gösterilmesini sağlar.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//signalR var hubProxy = $.connection.getProducts; hubProxy.client.getAllProducts = function (productList) { console.log("client.getAllProducts (" + JSON.stringify(productList) + ")"); $scope.ProductList = []; for (var i = 0; i < productList.length; i++) { $scope.ProductList.push(productList[i]); } if (productList.length > 0) { $scope.Show = true; $scope.$apply(); } } |
Client side’da signalR class’ına aşağıdaki gibi bağlanılır.
1 2 3 4 5 6 |
$.connection.hub.logging = true; $.connection.hub.start().done(function () { console.log("hub.start.done"); }).fail(function (error) { console.log(error); }); |
Şimdi yeni ürün ekleme işlemi tamamlandığı zaman yani Save All Product buttonuna basılıp tüm yeni eklenen ürünler kaydedildiği zaman bunu diğer clientlarada bildirmeye geldi. Server side tarafında GetProducts Hub class’ı altına aşağıdaki gibi ReloadProducts() adında bir method yaratılır. Amaç tüm dataları tekrardan çekip clientlara push etmektir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public void ReloadProducts() { List<ExportProductDetail> productList = new List<ExportProductDetail>(); using (ProductContext dbContext = new ProductContext()) { foreach (var item in dbContext.ExportProductDetail.ToList()) { ExportProductDetail model = new ExportProductDetail(); model.CreatedDate = item.CreatedDate; model.ID = item.ID; model.ExchangeRate = item.ExchangeRate; model.ExchangeType = item.ExchangeType; model.Price = item.Price; model.PriceTL = item.PriceTL; model.ProductName = item.ProductName; model.UpdateDate = item.UpdateDate; productList.Add(model); } } Clients.All.reloadProducts(productList); } |
Yukarıdaki örnekde görüldüğü gibi tüm data çekildikten sonra client side tarafındaki reloadProducts() function’ı çekilen tüm productlar ile birlikte server side tarafından tetiklenmiştir. Sıra geldi client side tarafındaki bu signalR function’ını aşağıdaki gibi kodlamaya:
1 2 3 4 5 6 7 8 9 10 11 |
hubProxy.client.reloadProducts = function (productList) { console.log("client.reloadProducts (" + JSON.stringify(productList) + ")"); $scope.ProductList = []; for (var i = 0; i < productList.length; i++) { $scope.ProductList.push(productList[i]); } if (productList.length > 0) { $scope.Show = true; $scope.$apply(); } } |
Save All Product buttonuna basılıp girilen tüm datalar kaydedilmek istenince HomeControl.cs’deki SaveProduct() methoduna gidilir. Kaydetme işlemi bitince datanın son halini tüm clientlara push etmek için yukarıda belirtilen GetProducts Hub class’ı altında yazılan ReloadProducts() methodu tetiklenir. İlgili kod aşağıdaki gibi değiştirilir. Kodda da görüldüğü gibi kaydedilen en az bir yeni kayıt var ise tetikleme işlemi gerçekleşmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public async Task<string> SaveProdut(List<ExportProductDetail> productList) { try { using (ProductContext dbContext = new ProductContext()) { var list = (from prod in productList where prod.ID == 0 select prod).ToList(); if (list.Count > 0) { dbContext.ExportProductDetail.AddRange(list); dbContext.SaveChanges(); //Triger SignalR HubConnection hubConnection = new HubConnection("http://localhost:35669/"); IHubProxy hubProxy = hubConnection.CreateHubProxy("GetProducts"); await hubConnection.Start(new LongPollingTransport()); hubProxy.Invoke("ReloadProducts"); return "All data Saved!"; } else return "No Data Saved!"; } } catch (Exception ex) { return ex.Message; } } |
Yukarıdaki //Triger SignalR kısmındaki kod önceki makalede Azure Cloud Services olarak yazılan WorkerRole1 projesinde de kullanılıp, ilgli ürünlerin TL karşılıkları bulunduğu zaman buna bağlı datanın son hali tüm clientlara bildirilmelidir. İlgili kod aşağıdaki gibi değiştirilir ve //Triger SignalR altındaki kısm eklenir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
private async Task RunAsync(CancellationToken cancellationToken) { // TODO: Replace the following with your own logic. while (!cancellationToken.IsCancellationRequested) { Trace.TraceInformation("Working"); using (ProductContext dbcontext = new ProductContext()) { IEnumerable<ExportProductDetail> data = (from products in dbcontext.ExportProductDetail where products.ExchangeRate ==null select products).ToList(); string USD = string.Empty; string EURO = string.Empty; string POUND= string.Empty; if (data.Any()) { var m_strFilePath = " http://www.tcmb.gov.tr/kurlar/today.xml"; string xmlStr; using (var wc = new WebClient()) { xmlStr = wc.DownloadString(m_strFilePath); } var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlStr); USD = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='USD']/BanknoteSelling").InnerXml.Replace(",","").Replace(".",","); EURO = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='EUR']/BanknoteSelling").InnerXml.Replace(",", "").Replace(".", ","); POUND = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='GBP']/BanknoteSelling").InnerXml.Replace(",", "").Replace(".", ","); } foreach(ExportProductDetail product in data) { switch(product.ExchangeType) { case (int)Exchange.Dollar: { product.ExchangeRate = decimal.Parse(USD); product.PriceTL=product.Price* decimal.Parse(USD); product.UpdateDate = DateTime.Now; dbcontext.SaveChanges(); break; } case (int)Exchange.Euro: { product.ExchangeRate = decimal.Parse(EURO); product.PriceTL = product.Price * decimal.Parse(EURO); product.UpdateDate = DateTime.Now; dbcontext.SaveChanges(); break; } case (int)Exchange.Pound: { product.ExchangeRate = decimal.Parse(POUND); product.PriceTL = product.Price * decimal.Parse(POUND); product.UpdateDate = DateTime.Now; dbcontext.SaveChanges(); break; } }; } //Triger SignalR if (data.Any()) { HubConnection hubConnection = new HubConnection("http://localhost:35669/"); IHubProxy hubProxy = hubConnection.CreateHubProxy("GetProducts"); await hubConnection.Start(new LongPollingTransport()); hubProxy.Invoke("ReloadProducts"); } } await Task.Delay(30000); } } } |
Yukarıdaki kodun //Triger SignalR kısmının Cloud Services’de çalışılabilmesi için Nuget’den Microsoft.AspNet.SignalR.Client‘ın indirilmesi gerekmektedir.
WorkerRoler1/WorkerRole.cs(Tümü):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.Diagnostics; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.Storage; using DAL; using System.Xml; using Microsoft.AspNet.SignalR.Client; using Microsoft.AspNet.SignalR.Client.Transports; namespace WorkerRole1 { public class WorkerRole : RoleEntryPoint { private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false); public override void Run() { Trace.TraceInformation("WorkerRole1 is running"); try { this.RunAsync(this.cancellationTokenSource.Token).Wait(); } finally { this.runCompleteEvent.Set(); } } public override bool OnStart() { // Set the maximum number of concurrent connections ServicePointManager.DefaultConnectionLimit = 12; // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. bool result = base.OnStart(); Trace.TraceInformation("WorkerRole1 has been started"); return result; } public override void OnStop() { Trace.TraceInformation("WorkerRole1 is stopping"); this.cancellationTokenSource.Cancel(); this.runCompleteEvent.WaitOne(); base.OnStop(); Trace.TraceInformation("WorkerRole1 has stopped"); } private async Task RunAsync(CancellationToken cancellationToken) { // TODO: Replace the following with your own logic. while (!cancellationToken.IsCancellationRequested) { Trace.TraceInformation("Working"); using (ProductContext dbcontext = new ProductContext()) { IEnumerable<ExportProductDetail> data = (from products in dbcontext.ExportProductDetail where products.ExchangeRate ==null select products).ToList(); string USD = string.Empty; string EURO = string.Empty; string POUND= string.Empty; if (data.Any()) { var m_strFilePath = " http://www.tcmb.gov.tr/kurlar/today.xml"; string xmlStr; using (var wc = new WebClient()) { xmlStr = wc.DownloadString(m_strFilePath); } var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlStr); USD = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='USD']/BanknoteSelling").InnerXml.Replace(",","").Replace(".",","); EURO = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='EUR']/BanknoteSelling").InnerXml.Replace(",", "").Replace(".", ","); POUND = xmlDoc.SelectSingleNode("Tarih_Date/Currency[@Kod='GBP']/BanknoteSelling").InnerXml.Replace(",", "").Replace(".", ","); } foreach(ExportProductDetail product in data) { switch(product.ExchangeType) { case (int)Exchange.Dollar: { product.ExchangeRate = decimal.Parse(USD); product.PriceTL=product.Price* decimal.Parse(USD); product.UpdateDate = DateTime.Now; dbcontext.SaveChanges(); break; } case (int)Exchange.Euro: { product.ExchangeRate = decimal.Parse(EURO); product.PriceTL = product.Price * decimal.Parse(EURO); product.UpdateDate = DateTime.Now; dbcontext.SaveChanges(); break; } case (int)Exchange.Pound: { product.ExchangeRate = decimal.Parse(POUND); product.PriceTL = product.Price * decimal.Parse(POUND); product.UpdateDate = DateTime.Now; dbcontext.SaveChanges(); break; } }; } //Triger SignalR if (data.Any()) { HubConnection hubConnection = new HubConnection("http://localhost:35669/"); IHubProxy hubProxy = hubConnection.CreateHubProxy("GetProducts"); await hubConnection.Start(new LongPollingTransport()); hubProxy.Invoke("ReloadProducts"); } } await Task.Delay(30000); } } } public enum Exchange { Dollar = 1, Euro = 2, Pound = 3 } } |
ProductList/HomeController.cs(Tümü)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
using DAL; using Microsoft.AspNet.SignalR; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Threading.Tasks; using Microsoft.AspNet.SignalR.Client; using Microsoft.AspNet.SignalR.Client.Transports; namespace ProductList.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } public async Task<string> SaveProdut(List<ExportProductDetail> productList) { try { using (ProductContext dbContext = new ProductContext()) { var list = (from prod in productList where prod.ID == 0 select prod).ToList(); if (list.Count > 0) { dbContext.ExportProductDetail.AddRange(list); dbContext.SaveChanges(); //Triger SignalR HubConnection hubConnection = new HubConnection("http://localhost:35669/"); IHubProxy hubProxy = hubConnection.CreateHubProxy("GetProducts"); await hubConnection.Start(new LongPollingTransport()); hubProxy.Invoke("ReloadProducts"); return "All data Saved!"; } else return "No Data Saved!"; } } catch (Exception ex) { return ex.Message; } } } public class GetProducts : Hub { public override async Task OnConnected() { List<ExportProductDetail> productList = new List<ExportProductDetail>(); using (ProductContext dbContext = new ProductContext()) { foreach (var item in dbContext.ExportProductDetail.ToList()) { ExportProductDetail model = new ExportProductDetail(); model.CreatedDate = item.CreatedDate; model.ID = item.ID; model.ExchangeRate = item.ExchangeRate; model.ExchangeType = item.ExchangeType; model.Price = item.Price; model.PriceTL = item.PriceTL; model.ProductName = item.ProductName; model.UpdateDate = item.UpdateDate; productList.Add(model); } } await Clients.Caller.getAllProducts(productList); } public void ReloadProducts() { List<ExportProductDetail> productList = new List<ExportProductDetail>(); using (ProductContext dbContext = new ProductContext()) { foreach (var item in dbContext.ExportProductDetail.ToList()) { ExportProductDetail model = new ExportProductDetail(); model.CreatedDate = item.CreatedDate; model.ID = item.ID; model.ExchangeRate = item.ExchangeRate; model.ExchangeType = item.ExchangeType; model.Price = item.Price; model.PriceTL = item.PriceTL; model.ProductName = item.ProductName; model.UpdateDate = item.UpdateDate; productList.Add(model); } } Clients.All.reloadProducts(productList); } } } |
ProductList/Index.cshtml(Tümü):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
@{ ViewBag.Title = "Index"; } <script src="~/Scripts/angular.min.js"></script> <script src="~/Scripts/jquery-2.1.3.min.js"></script> <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> <script src="~/signalr/hubs"></script> <script> function getDateTime() { var now = new Date(); var year = now.getFullYear(); var month = now.getMonth() + 1; var day = now.getDate(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); if (month.toString().length == 1) { var month = '0' + month; } if (day.toString().length == 1) { var day = '0' + day; } if (hour.toString().length == 1) { var hour = '0' + hour; } if (minute.toString().length == 1) { var minute = '0' + minute; } if (second.toString().length == 1) { var second = '0' + second; } var dateTime = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second; return dateTime; } (function (angular) { function MainController($scope, $http) { //signalR var hubProxy = $.connection.getProducts; hubProxy.client.getAllProducts = function (productList) { console.log("client.getAllProducts (" + JSON.stringify(productList) + ")"); $scope.ProductList = []; for (var i = 0; i < productList.length; i++) { $scope.ProductList.push(productList[i]); } if (productList.length > 0) { $scope.Show = true; $scope.$apply(); } } hubProxy.client.reloadProducts = function (productList) { console.log("client.reloadProducts (" + JSON.stringify(productList) + ")"); $scope.ProductList = []; for (var i = 0; i < productList.length; i++) { $scope.ProductList.push(productList[i]); } if (productList.length > 0) { $scope.Show = true; $scope.$apply(); } } //------------------------------------------ $scope.ProductList = []; $scope.Product = function () { ProductName, Price, ExchangeType, ExchangeRate, PriceTL, CreatedDate, UpdateDate }; $scope.Save = function (_product) { $scope.Show = true; $scope.ProductList.push({ ProductName: _product.ProductName, Price: _product.Price, ExchangeType: _product.ExchangeType, ExchangeRate: _product.ExchangeRate, PriceTL: _product.PriceTL, CreatedDate: getDateTime(), UpdateDate: _product.UpdateDate }); $scope.Product = null; $('.name').focus(); }; $scope.SaveAll = function (_productList) { $http({ method: 'POST', url: "/Home/SaveProdut", data: _productList }).success(function (result) { alert(result); }) console.log(angular.toJson(_productList)); } $.connection.hub.logging = true; $.connection.hub.start().done(function () { console.log("hub.start.done"); }).fail(function (error) { console.log(error); }); }; var app = angular.module("app", []); app.controller("MainController", ["$scope", "$http", MainController]); app.filter("moneyType", function () { return function (input) { switch (input) { case '1': case 1: return '$'; break; case '2': case 2: return '€'; break; case '3': case 3: return '£'; break; }; }; }); })(angular); </script> <h2>Ürün Giriş</h2> <hr /> <div class="Main" ng-app="app" ng-controller="MainController"> <table> <tr><td>Product Name:</td><td><input type="text" ng-model="Product.ProductName" class="name"></td></tr> <tr><td>Price:</td><td><input type="text" ng-model="Product.Price"></td></tr> <tr> <td>ExchangeType:</td> <td> <select ng-model="Product.ExchangeType"> <option value=1>$</option> <option value=2>€</option> <option value=3>£</option> </select> </td> </tr> <tr><td><input type="button" value="Save" ng-click="Save(Product)" /></td><td></td></tr> </table> <hr /> <div class="productList" ng-show="Show"> <h2>Ürün Listesi</h2> <input type="button" value="Save All Product" ng-click="SaveAll(ProductList)"><table> <tr> <th>ProductName |</th> <th>Price |</th> <th>ExchangeType |</th> <th>ExchangeRate |</th> <th>PriceTL |</th> <th>CreatedDate |</th> <th>UpdateDate</th> </tr> <tr ng-repeat="prod in ProductList"> <td>{{prod.ProductName}}</td> <td>{{prod.Price}}</td> <td>{{prod.ExchangeType | moneyType}}</td> <td>{{prod.ExchangeRate}}</td> <td>{{prod.PriceTL}}</td> <td>{{prod.CreatedDate}}</td> <td>{{prod.UpdateDate}}</td> </tr> </table> </div> </div> |
Yukarıdaki örnekde Azure Cloud Service, Mvc , AngularJS, Entity Framework (Code First), SignalR(Websocket) teknolojileri birlikte kullanılmıştır. Görüldüğü gibi farklı teknolojiler birlikte çok güzel çalışabilmektedirler. Azure çok geniş kapsamlı ve sürekli gelişen günümüzün en popüler teknolojilerinden biridir. Örneğin az önce Azure search özelliği gelmiştir. AngularJS javascript frameworkleri arasında en populer olanlarından biridir. Gene az önce gördüğüm bir habere göre Microsoft & Google iş birliği ile AngularJS 2.0 TypeScript üzerinde geliştirilmeye başlanmıştır. SignalR sürekli gelişen daha çok yeni bir teknolojidir. Kısaca gelişimin sonu yoktur. Klasik sorunlarımıza yenilikçi çözümler getirmek ve bunları sizinle paylaşmak benim en büyük gayemdir.
Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.
Source Code: http://www.borakasmer.com/projects/CheckDB.rar
Selamlar Hocam;
Çok güzel bir makale olmuş. Çok yararlı ve faydalı. Elinize sağlık.
İyi çalışmalar.
Your style is very unique compared to other people I’ve read stuff from.
Thank you for posting when you’ve got the opportunity, Guess I will just book mark this
site.
Thank you for your commands. I am writing for a while. Keep tracking to me.
See you next posting..
Bye.
Você qᥙe descobrir com᧐ como ganhar dinheiro nas
rеdes sociaіs?
Hi,
I have no idea, what are you talking about :)
Thank you..
Thanks for finally writing about >Azure Cloud
Service Worker Role ile Sql Db’den Kurlara Göre
TL Karşılığını Bulma Part2 – Bazıları Hayal Eder Bazıları Yapar – Bora Kaşmer
– http://www.borakasmer.com <Liked it!
Thanks for finally talking about >Azure Cloud Service Worker Role ile
Sql Db’den Kurlara Göre TL Karşılığını Bulma Part2 – Bazıları Hayal Eder Bazıları Yapar – Bora Kaşmer – http://www.borakasmer.com <Loved it!
You are Wellcome :)
Thanks for finally writing about >Azure Cloud Service Worker
Role ile Sql Db’den Kurlara Göre TL Karşılığını Bulma
Part2 – Bazıları Hayal Eder Bazıları Yapar – Bora Kaşmer – http://www.borakasmer.com <Loved it!