Asp.Net Core ile OSX Ortamda Monitor Ekranı Hazırlama
Selamlar,
Bugün OsX işletim sisteminde, Visual Studio Code kullanarak MVC ile bir monitör ekranı hazırlayacağız.
Çalışma Ortamının Hazılanması :
Öncelikle (Mac) makinamızda kurulu değil ise Homebrew‘in indirilmesi gerekmektedir. Daha sonra terminal’den aşağıdaki komutlar çalıştırılır.
1 2 3 4 |
brew update brew install openssl ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/ ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/ |
Daha sonra .NET Core SDK, ilgili sitesinden indirilir. Eğer sizde de bende olduğu gibi terminalde dotnet komutu çalışmaz ise aşağıdaki komut çalıştırılmalıdır.
1 |
<span class="pl-mo">ln -s /usr/local/share/dotnet/dotnet /usr/local/bin</span> |
Sonraki adım olarak makinanızda kurulu değil ise node.js kurmanızı tavsiye ederim. Böylece terminalde “npm” komutu çalışacaktır.
Daha sonra aynı Visual Studio’da olduğu gibi terminalden belirlediğimiz tipte bir proje template’i oluşturmak için, aşağıdaki komut ile AspNet Generator kurulur.
1 |
sudo npm install -g generator-aspnet |
Son olarak eğer makinada yok ise Yeoman kurulur.
1 |
sudo npm install -g yo |
Projenin Oluşturulması :
Şimdi sıra geldi Mvc projenin oluşturulması : Aşağıdaki komut yazılıp, “Web Application Basic” seçilir. Hangi UI frameworkün’de çalışılacağı seçilir. Ben Boostrap(3.3.6) seçtim. Son olarak ismi tanımlanıp enter’a basılır. Ben proje adını “Exchange” tanımladım.
1 |
yo aspnet:MvcController Exchange |
Ben OSX ortamında ide olarak Visual Studio Code ile çalıştım. Aşağıdaki komut yazılarak, yeni yaratılan Exchange Mvc projesinin Visual Studio Code’a açılması sağlanır.
1 |
code . |
Öncelikle gelin işelem yapacağımız data modelini oluşturalım. “Services” klasörü altında, aşağıdaki sınıflar oluşturulur.
DataModel.cs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Exchange.Services { public class DataModel { public double Dun { get; set; } public double Dusuk { get; set; } public double HacimLot { get; set; } public double HacimTl { get; set; } public string Name { get; set; } public double Ort { get; set; } public double Son { get; set; } public double Yuksek { get; set; } public double Yuzde { get; set; } public DataModel() { } } } |
Şimdi sıra geldi ilgili datayı sağlayacak “Services.cs” sınıfının oluşturulmasına.
Services.cs: Burada çeşitli borsa bilgilerinin verildiği, bir data kümesi oluşturulmuştur. “FillData()” methodu ile ilgili oluşturulan List of DataModel geri dönülmektedir.
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 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Exchange.Services { public class Service { public Service() { } public List<DataModel> FillData() { List<DataModel> models = new List<DataModel>(); models.AddRange(new DataModel[]{ new DataModel() { Name = "BOSSA BOSSA", Son = 11.06, Dun = 10.8, Yuzde = 2.12, Yuksek = 12.3, Dusuk = 9, Ort = 10.59, HacimLot = 13.2, HacimTl = 1.008 }, new DataModel() { Name = "ASELS ASELSAN", Son = 23.3, Dun = 12.4, Yuzde = 3.74, Yuksek = 24.3, Dusuk = 47, Ort = 31.59, HacimLot = 7.2, HacimTl = 3.008 }, new DataModel() { Name = "ADBGR", Son = 14.3, Dun = 34.6, Yuzde = 6.74, Yuksek = 51.3, Dusuk = 13, Ort = 45.59, HacimLot = 31.2, HacimTl = 3.012 }, new DataModel() { Name = "ADEL", Son = 1.3, Dun = 23.6, Yuzde = 12.74, Yuksek = 34.3, Dusuk = 17, Ort = 20.59, HacimLot = 27.2, HacimTl = 3.008 } }); return models; } } } |
Şimdi sıra geldi Asp.Net Core üzerinde bu datanın verildiği WebApi servisinin oluşturulmasına. Aşağıdaki komut yazılarak “yo generator” ile oluşturulabilecek proje templatelerinin listesini alabilirsiniz.
1 |
yo aspnet --help |
WebApi klasörü açılıp ilgili “DataControl” WebApi servisi aşağıdaki komut ile oluşturulur.
1 |
yo aspen:WebApiController DataController |
DataControl.cs: Aşağıda görüldüğü gibi “Get()” ile tüm data ve “Get(string name)” ile isme göre data çekilmektedir. İlgili data “Service” sınıfından yararlanılarak verilmektedir.
Önemli nokta: İsme göre filitrelemede “-” karakteri ” ” ile replace edilmiştir. Kısaca ismi içerisinde boşluk karakteri olanlar “-” konularak ilgili servise gönderilmiştir. Bunu debug ederek birazdan inceleyeceğiz. Bu işlem Url’de boşluk karakteri bıraklamıyacağı ve yerine “-” karakteri konduğu için yapılmışıtır.
Bir önemli nokta Routingdir. Aşağıdaki kod ile “Route Attribute” kullanılarak hızlıca rotasyon belirlenmiştir.
1 |
[Route("api/[controller]")] |
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 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Exchange.Services; using Microsoft.AspNetCore.Mvc; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace Exchange.WebApi { [Route("api/[controller]")] public class DataController : Controller { // GET api/values [HttpGet] public List<DataModel> Get() { Service service=new Service(); var dataList=service.FillData(); return dataList; } // GET api/values/5 [HttpGet("{name}")] public DataModel Get(string name) { Service service=new Service(); var dataList=service.FillData(); name=name.Replace("-"," "); return dataList.Where(dl=>dl.Name==name).FirstOrDefault(); } } } |
Sıra geldi debug işlemine:
Debug: Öncelikle yukarıdaki resimde görüldüğü gibi örümcek resmine tıklanır. DEBUG modda “.NET Core Launch(web)” ayarlardan seçilmelidir. BreakPoints kısmında debug edilecek kod satırları görülmektedir. Bu örnekde biz, isminde boşluk geçen datayı yakalamaya çalışacağız.
Önemli Nokta: Debug modda yukarıda görülen çark şeklindeki ikon tıklandığında karşımıza aşağıdaki config dosyası çıkmaktadır. “program” olarak tanımlanan alanda uygulamanın “dll” yolunun doğru tanımlandığına dikkat edilmesi gerekir.
“program”: “${workspaceRoot}/bin/Debug/netcoreapp1.0/Exchange.dll”
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 |
{ "version": "0.2.0", "configurations": [ { "name": ".NET Core Launch (web)", "type": "coreclr", "request": "launch", "preLaunchTask": "build", "program": "${workspaceRoot}/bin/Debug/netcoreapp1.0/Exchange.dll", "args": [], "cwd": "${workspaceRoot}", "stopAtEntry": false, "internalConsoleOptions": "openOnSessionStart", "launchBrowser": { "enabled": true, "args": "${auto-detect-url}", "windows": { "command": "cmd.exe", "args": "/C start ${auto-detect-url}" }, "osx": { "command": "open" }, "linux": { "command": "xdg-open" } }, "env": { "ASPNETCORE_ENVIRONMENT": "Development" }, "sourceFileMap": { "/Views": "${workspaceRoot}/Views" } }, { "name": ".NET Core Attach", "type": "coreclr", "request": "attach", "processId": "${command.pickProcess}" } ] } |
Önemli Nokta 2: Debug işlemi için “SHIFT + COMMAND + P” tuşlarına basılıp “ext install csharp” komutu yazılarak ilgili extension’ın yüklenmesi gerekmektedir.
Önemli Nokta 3: Aşağıda görüldüğü gibi program.cs’deki “UseUrls” başlangıç adresi, sadece debug işlemi için değiştirilmelidir. Yoksa debug işlemi sırasında bu port kullanılıyor diye hata mesajı alınabilmektedir..
1 |
.UseUrls("http://localhost:1455") |
Şimdi sıra geldi ilgili WebApi’yi kullanarak Mvc action’da modelimizi doldurmaya ve Viewımıza göndermeye.
HomeController.cs/Index():
- [Route(“Show”)] şeklinde Custom bir Routing tanımlanmıştır.
- Bir dış WebApi servisinden faydalanıldığı için asenkron bir yapı yapılarak “Task<>”‘lar kullanılmıştır.
- Gelen datanın List of “DataModel”‘e dönüştürülmesi için NewtonSoft kullanımıştır. “JsonConvert.DeserializeObject<>()”
- İlgili model çekilip View’a gönderilmiştir.
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 |
using Microsoft.AspNetCore.Mvc; using Exchange.Services; using Microsoft.AspNetCore.Http; using System.Collections.Generic; using System; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; namespace Exchange.Controllers { public class HomeController : Controller { public IActionResult Index() { return View(); } [Route("Show")] public async Task<ActionResult> ShowExchange() { using (HttpClient client = new HttpClient()) { var response = await client.GetAsync("http://localhost:1453/api/data"); var model = JsonConvert.DeserializeObject<List<DataModel>>( response.Content.ReadAsStringAsync().Result); return View(model); } } } } |
Örnek Ekran Çıktısı:
ShowExchange.cshtml:
- Html tarafında bootstrap kullanılmıştır. Model olarak @model List of DataModel beklemektedir.
- Her bir satıra atanan css ‘<tr class=”@css”>‘ random olarak belirlenmiş ve böylece her bir satırın farklı renkte görünmesi sağlanmıştır.
- Son olarak her bir kayıt için detay bilgisinin alınabileceği “show/title” şeklinde url tanımlanmıştır. ” ” Titledaki boş alanlar “-” karakteri ile değiştirilmiştir.
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 |
@model List<Exchange.Services.DataModel> <script src="~/lib/jquery/src/jquery.js"></script> <link href="~/lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" /> <script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script> <div class="container"> <div class="jumbotron"> <h1>WellComeTo Live Exchange</h1> <p>Result Change Real Time!</p> </div> @{ System.Random rnd = new Random(); string[] array = new string[] { "success", "danger", "info" }; } <table class="table"> <thead> <tr> <th class="hBig">Hisse</th> <th class="hNarrow">Son</th> <th class="hNarrow">Dün</th> <th class="hNarrow">%</th> <th class="hNarrow">Yüksek</li> <th class="hNarrow">Düşük</th> <th class="hNarrow">Ağ.Ortalama</th> <th class="hWide">Hacim(LOT)</th> <th class="hWide">Hacim(TL)</th> </tr> </thead> <tbody> @foreach(var item in Model) { int rowId=rnd.Next(30)%3; string css=(string)array[rowId]; <tr class="@css"> <td id="Name@(item.Name)"><a href="/show/@item.Name.Replace(' ','-')/">@item.Name</a> <span class="s up"></span></td> <td id="Son@(item.Name)">@item.Son</td> <td id="Dun@(item.Name)">@item.Dun</td> <td id="Yuzde@(item.Name)">@item.Yuzde</td> <td id="Yuksek@(item.Name)">@item.Yuksek</td> <td id="Dusuk@(item.Name)">@item.Dusuk</td> <td id="Ort@(item.Name)">@item.Ort</td> <td id="HacimLot@(item.Name)">@item.HacimLot</td> <td id="HacimTl@(item.Name)">@item.HacimTl</td> </tr> } </tbody> </table> </div> |
HomeController.cs/Index(string title) Detay Sayfası: Detay sayfasına, aşağıdaki Inex() action’ının overload olmuş hali ile gidilir.
- Yen bir view yapmamak adına tek bir kayıt dönmesine ragmen, view List<DataModel> beklediği için yine burada da liste dönülmüştür.
- Önceden yazılan detay servisi burda girilen title parametresi ile çağrılmıştır.
- İlgili Detay Action’a ulaşabilmek adına, [Route(“show/{title}”)] şeklinde custom route tanımlanmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[Route("show/{title}")] public async Task<ActionResult> ShowExchange(string title) { using (HttpClient client = new HttpClient()) { var response = await client.GetAsync("http://localhost:1453/api/data/"+title); var data = JsonConvert.DeserializeObject<DataModel>( response.Content.ReadAsStringAsync().Result); List<DataModel> model=new List<DataModel>(); model.Add(data); return View(model); } } |
Bu kısma kadar bir WebApi servisi yazıp ilgili datayı Mvc controller’da doldurduk. Daha sonra bu doldurulan datayıi ilgili view’a gönderip sayfaya bastık. Ekrana basılan datadan herhangi birisinin detayını görüntülemek için ilgili servisi ve controllerdaki action’ı kodladık. Hataları ayıklamak için Asp.Net Core’da debug modu aktif hale getirdik. Görsel için bootstarp kullandık.
Bir sonraki makalede ilgili datalar anlık değişimini, clientlara nasıl yansıtacağımızı hep beraber inceleyeceğiz.
Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.
Hepinizin geçmiş bayramı kutlu olsun.
Son Yorumlar