Merhaba Arkadaşlar ben bugun yeni karşılaştığım hatayı sizlerle paylaşmak istiyorum. Benim epey zamanımı aldı,, sizinde almamasını istiyorum.
Giden bilgi
Servere gelen bilgi ise
ImageCropModel deki değerler double olduğu halde bu hatayı vermekte idi...
Client tarafındaki javascript kodunu, her bir değer için parseInt(x); gibi bir tür dönüşümü yaparak sorunu çözdüm..
Fakat hala aklımda bu sorunun heden çıktığını bulmuş değilim.
Merhaba Arkadaşlar;
Image upload işlemini aslında kendeio, jequery upload, mvc nin içinde helper metodları kullanarak yapılabilir. Çok geniş ve yyöntemleri farklı ve oldukça zor bir konudur. Ben ce iyi bir javascript koduyla mükemmel bir iş çıkartalıbilir. Bu yadığım kod daha da geliştirilebilir.
Crop işlemi için gerekli kütüphaneyi buradan indiriyoruz.
Ayrııca display template ve editor template konularında bilgi sahibi olmamız gerekiyor. Burada Bayram Üçüncü konuyu iyi açıklamış..
Öncelikle Upload işlemi kodlarını yazılım...
public class ProfileViewModel
{
[UIHint("resim")]
public string ImageUrl { get; set; }
}
Daha Sonra displaytemplate için resim.cshtml dosyasını yazlım..Bu dosya shared/DisplayTemplate klasörününü anltında olması gerekir.
@model System.String
<img src="@(String.IsNullOrEmpty(Model) ? "" : @Model)" id="preview" />
şimdide index.cshtml yazalım..
@using FileUpload.Controllers;
@model ProfileViewModel
@using Microsoft.Web.Helpers;
<h2>Index</h2>
@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { @encType = "multipart/form-data" }))
{
@Html.DisplayFor(x => x.ImageUrl)<br/>
@FileUpload.GetHtml(initialNumberOfFiles:1, allowMoreFilesToBeAdded: true, includeFormTag: false, addText: "Add Files", uploadText: "Upload File")<br />
<input type="submit" name="submit" text="upload" />
}
Ben burada microsoftun web helper kulladınm package id si "microsoft-web-helpers" şeklindedir. Bunu muget consoleyi kullanarak indiriebilirsiniz. Bu FileUpload
heplerı ile birden fazla resim eklenebilmekte. Şimdi upload işlemini yapacak Actionımızı yazalım...
private bool CreateFolderIfNeeded(string path)
{
bool result = true;
if (!Directory.Exists(path))
{
try
{
Directory.CreateDirectory(path);
}
catch (Exception)
{
/*TODO: You must process this exception.*/
result = false;
}
}
return result;
}
public ActionResult Upload(ProfileViewModel model)
{
var image = WebImage.GetImageFromRequest();
if (image != null)
{
if (image.Width > 500)
{
image.Resize(500, ((500 * image.Height) / image.Width));
}
var filename = Path.GetFileName(image.FileName);
if (this.CreateFolderIfNeeded(Server.MapPath("~/Temp")))
{
try
{
image.Save(Path.Combine("../Temp", filename));
filename = Path.Combine("~/Temp", filename);
model.ImageUrl = Url.Content(filename);
}
catch (Exception ex)
{
string message = string.Format("File upload failed: {0}", ex.Message);
}
}
}
return View("Index", model);
}
}
Bir crop işelemi client tarafında sadece seçim işlemini yaptırıyoruz. Crop işlemini ise servere yaptırdığımız için crop kordinatları için gerekli bir model yazalım..
public class EditorInputModel
{
public ProfileViewModel Profile { get; set; }
public double Top { get; set; }
public double Bottom { get; set; }
public double Left { get; set; }
public double Right { get; set; }
public double Width { get; set; }
public double Height { get; set; }
}
Şimdi de crop işlemi için gerekli kodlarımız yazalım. Upload Action methodumuzu tekrardan düzenleyerek aşağıdaki kodları ekleyelim
//return View("Index", model);
var editModel = new EditorInputModel()
{
Profile = model,
Width = image.Width,
Height = image.Height,
Top = image.Height * 0.1,
Left = image.Width * 0.9,
Right = image.Width * 0.9,
Bottom = image.Height * 0.9
};
return View("Editor", editModel);
Daha sonra editor.cshtml doasyasını ve gerekli script kodları yazalım..
@using FileUpload.Controllers;
@model EditorInputModel
@section Head{
<link href="~/Content/Jcrop-v0.9.12/css/jquery.Jcrop.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Content/Jcrop-v0.9.12/js/jquery.Jcrop.min.js"></script>
}
<h2>Editor</h2>
<div id="mainform">
@using(Html.BeginForm("Edit","Home", FormMethod.Post))
{
@Html.EditorFor(x=>x.Profile.ImageUrl)
@Html.HiddenFor(x=>x.Left)
@Html.HiddenFor(x=>x.Right)
@Html.HiddenFor(x=>x.Top)
@Html.HiddenFor(x=>x.Bottom)
@Html.HiddenFor(x => x.Profile.ImageUrl)
<input type='submit' name='action' value='Crop' />
}
</div>
<script>
$(function () {
$('#profileImageEditor').Jcrop({
onChange: showPreview,
onSelect: showPreview,
setSelect: [@Model.Top, @Model.Left, @Model.Right, @Model.Bottom],aspectRatio: 1});
});
function showPreview(coords)
{
if (parseInt(coords.w) > 0)
{
$('#Top').val(coords.y);
$('#Left').val(coords.x);
$('#Bottom').val(coords.y2);
$('#Right').val(coords.x2);
var width = @Model.Width;
var height = @Model.Height;
var rx = 100 / coords.w;
var ry = 100 / coords.h;
$('#preview').css({
width: Math.round(rx * width) + 'px',
height: Math.round(ry * height) + 'px',
marginLeft: '-' + Math.round(rx * coords.x) + 'px',
marginTop: '-' + Math.round(ry * coords.y) + 'px'
});
}
}
Daha sonra crop işleminin yapacak actionımızı yapalım..
[HttpPost]
public ActionResult Edit(EditorInputModel editor)
{
var image = new WebImage("~" + editor.Profile.ImageUrl);
var height = image.Height;
var width = image.Width;
image.Crop((int)editor.Top, (int)editor.Left, (int)(height-editor.Bottom), (int)(width-editor.Right));
var originalFile = editor.Profile.ImageUrl;
if (this.CreateFolderIfNeeded(Server.MapPath("~/ProfileImage")))
{
try
{
editor.Profile.ImageUrl = Url.Content("~/ProfileImage/" + Path.GetFileName(image.FileName));
image.Resize(100, 100, true, false);
image.Save(@"~" + editor.Profile.ImageUrl);
}
catch (Exception ex)
{
string message = string.Format("File upload failed: {0}", ex.Message);
}
}
System.IO.File.Delete(Server.MapPath(originalFile));
return View("Index", editor.Profile);
}
Projenini tümünü burdan indiriebilirsiniz..
FileUploadAndCrop.rar (11,55 mb)
Action<> Delegesi, Func<> gibi önceden tanımlı toplam 16 adet türü olan bir delege çeşidirdir. Farkı Tresult, yani geri değer döndürmemesidir.
class Program
{
static void Main(string[] args)
{
Action delegem = ()=>{ Console.WriteLine("merhaba Dünya");};
Action<int,int> delegem2 = (x,y) => { Console.WriteLine(x*y); };
Action<string> delegem3 = yaz;
delegem();
delegem2(3,5);
delegem3("Erkan");
}
static void yaz(string mesaj)
{
Console.WriteLine("merhaba"+ mesaj);
}
}
Aslında List<T> türünden bir nesnenin Foreach iterasyonu için gereken parametre Action türündendir. aşağıda şekilde görüldüğü gibi.
Func<> delegesi, Preciadte<T> delegesi gibi linq işlemlemlerinde kullanılmaktadır. Aslında Pricate<T>, Func<T,bool> ile aynı yapıya sahiptir. Bir T nesnesi gider bool tipinde bir değer geri döner. Framework de bir çok yapısı bulunmaktadır. En çok kullanılanlar aşağıdadır.
Public delegate TResult Func<TResult>() // parametre yok, dönüş değeri Tresult
Public delegate TResult Func<T, TResult>(T t) // parametre T, bir adet, dönüş değeri Tresult
Public delegate TResult Func<T1, T2, TResult>(T1 t1, T2 t2) // parametre T, 2 adet, dönüş değeri Tresult
Public delegate TResult Func<T1, T2, T3, TResult>(T1 t1, T2 t2, T3 t3) // parametre T, 4adet, dönüş değeri Tresult
Public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 t1, T2 t2, T3 t3,T4 t4) // parametre T, 4 adet, dönüş değeri Tresult
Parametre yok ise şöyle bir örnek yapabiliriz.
static void Main(string[] args)
{
//delegeat tanımla ve başlat
Func<string> funcDelegate = First;
string mesaj = funcDelegate();
Console.WriteLine(mesaj);
}
private static string First()
{
return "merhaba dünya!!";
}
class Program
{
static void Main(string[] args)
{
List<int> list = new List<int> { 6, 9, 3, 6, 7, 33, 56 };
Predicate<int> more = new Predicate<int>(sonuc);
Func<int, bool> more2 = new Func<int, bool>(sonuc);
int sayi= list.FirstOrDefault(more2);
Console.WriteLine(sayi);
}
static bool sonuc(int sayilar)
{
return sayilar > 10;
}
}
Örneğimizi çoğaltılım artıkk, 2 parametr e bir geriş dönüş olsun. Float olan dönüş tipidir.
public class Program{
static void Main(string[] args)
{
Func<int, int, float> deleggem = Ekle;
double sayi = deleggem(2, 4);
Console.WriteLine(sayi);
}
private static float Ekle(int birinci, int ikinci) {
return birinci * ikinci;
}
}
Aynı örneği isimsiz bir method şeklinde yazdım. Bir method bir defa lazım olacak ise, bu istenilen yerde yazılabilir.
public class Program{
static void Main(string[] args){
Func<int, int, float> deleggem = delegate(int birinci, int ikinci) {
return birinci * ikinci;
};
double sayi = deleggem(2, 4);
Console.WriteLine(sayi);
}
}
Şimdide aynı örneği lambada ifadeleri ile yazalım.
public class Program{
static void Main(string[] args){
Func<int, int, float> delegem=(x,y)=>x*y;
double sayi = delegem(2, 4);
Console.WriteLine(sayi);
}
}
Son bir örnek daha verelimm.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication18
{
public class Person
{
public int ProductId { get; set; }
public string Name { get; set; }
public string SurName { get; set; }
}
public static class ProductFactory
{
public static Person CreateProduct(int id=0) {
return CreateProduct(id, "No Name", "No Surname");
}
public static Person CreateProduct(int id, string ad) {
return CreateProduct(id, ad, "Soy isimsiz");
}
public static Person CreateProduct(int id, string name, string surname) {
return new Person {
ProductId = id,
Name = name,
SurName = surname,
};
}
}
class Program
{
static void Main(string[] args)
{
List<Person> list = new List<Person> {
ProductFactory.CreateProduct(1),
ProductFactory.CreateProduct(2,"Kemal"),
ProductFactory.CreateProduct(3,"Mustafa", "Kemal"),
ProductFactory.CreateProduct(4,"Kemal", "Ballı"),
ProductFactory.CreateProduct()
};
List<Person> newList = list.Where(x => x.Name == "Kemal").ToList(); ;
newList.ForEach(x => Console.WriteLine("{0}: {1} {2}", x.ProductId, x.Name,x.SurName));
}
}
}
Merhaba arkadaşlar ,
Bildiğiniz gibi Microsoft firması Visual stduio 2013 Priview ve mvc% rc1 sürümlerini duyurdu. Şu an studio 2012 için MVC% template daha çıkmadı. Ben bunu kısaca nasıl yapabilceğinizi anlatacağım.
Öncelikle bizim için önemli olan referans dosyaları nuget pajketden yükelemiz gerekiyor. Nuget consoldan aşağıda yazılan paketleri yükleyelim. Tabiki bunları nuget paket yükleyisinden seçerek de yükleyebilirsiniz.
Install-Package Microsoft.AspNet.WebApi -pre
Install-Package Microsoft.AspNet.Mvc -Pre
Install-Package Microsoft.AspNet.SignalR -Pre
Install-Package Microsoft.AspNet.Identity.Owin -Pre (Bu membership, external girişler, güvenlik library)
Yüklendikten sonra aşağıdaki dosyalar aşağıdaki gibi update olacaktır.
Microsoft.AspNet.Mvc 5.0.0-rc1
Microsoft.AspNet.Razor
Microsoft.AspNet.WebApi 5.0.0-rc1
Microsoft.AspNet.WebApi.Client 5.0.0-rc1
Microsoft.AspNet.WebApi.Core 5.0.0-rc1
Microsoft.AspNet.WebApi.WebHost 5.0.0-rc1
Microsoft.AspNet.WebPages 3.0.0-rc1
Gülü güle kullanın.
LinqToEtOrneklerim.rar (2,16 mb)
Merhaba Arkadaşlar, evet sizlerle çok şeyler paylaşmak ve uzun uzun makale yazıp, örnek kodlarla bunu pekiştrmek çok isterdim. Bu benim zevk aldığım bir etkinliğim. Fakat bende bazı teknolojileri öğrenme ve kod yazma evresindeyim ve yetiştirmem gereken bazı projeler var. Sanırım ileriki yıllarda bunu daha iyi yapacağıma inanıyorum. Tek sorunum bu iş için zaman ayırabilmek. Buda ne zaman olur bilmiyorum..
TDD bence profesyonel bir programcının olmazsa olmaz yöntemlerinden biridir. Ben bunu gerçek hayatda (Real Word) şu şekilde açıklarsam sanırım doğru olur.
Diyelimki ben bir uçak motoru üreticisiyim ve ürettiğim motor gelişime açık bir motor tabiki. Bu motorun yağışlı havalarda, normal havada, olagan üstü durumlarda hiç zorlanmadan görevinin yapması gerekiyor. Ben bir uçak üretici olarak havanın o kouşullarda olmasını, bir pilot bulmayı, motoru takacak bir uçak gövdesinin olmasını bekleyemem, beklememek zorundayım. Dolayısıyla bunu uygun bir similator hazırlayıyorum, biraz zor oluyor ama hazırlıyorum. Böylece ileriki geliştirmelerlede diğer koşullardan bağımsız(Dependecy) bir ürün üretebilirim. Hızlı, çevik(Agile) olmam için muhakkak bağımzısz bir test ortamına ihtiyacım var.
Kod yazarkende katmanlı kod yazarken katmanların birbirinden mümkün olduğunca bağızsız olmasına özen göstermek gerekir. Bunu başarmak test edilebilirliğide artırmaktadır. Yazdığım kodlar, servislerden, veri tabanından, diğer eklenecek nesne(object), kural(rule), davranışlardan bağımsız olmalı. Musteriden gelen isteklere-(returns),Yani bir anlamda gelişime açık fakat değişime kapalı olmalı. bunun için bazı yazılım şablonları(paterns) ve kurallarına uymamız(priciple) gerekmekte. Bu patern ve şablonlar bence biir yazılımcının ilk öğrenmesi gereken konulardır. Bir kodu diğer etmenlerden bağımsız hale getirmek için bağızsızlık aşılaması(Dependency injection), bağızsızlığın tesr çevrilmesi(Dependecy inversion), gelişime açık, değişime kapalı (open closed priciple), arabirimleri parçalama (Interface Segregation), bir sınıfın bir sorumluluğu olması(Single Responsibility) vs. Object patern, reprository patern, MVC,MVVM gibi bir çok patern ve kalıbı bilmek ve uymak zorundadır. Zaman olduğundna bunları tek tek ele alacağım. Fakat siz bu kavramlar hakkında bir çok yazı ve örnek kod bulabilirsiniz.
Cihat Altuntaş TDD kısaca özellemiş, çok hoşuma gitti, bende sizlerle paylaşmak istedim.
Test Driven Development(TDD) nedir?
- Daha hızlı yazılım geliştirme
- Çok daha az hata içeren kod
- Testler kodun çalıştırılabilir örnek dökümanını oluşturur.
- Daha iyi tasarıma sahip daha kaliteli kod
- Hataların daha çabuk bulunması ve düzeltmesi
- Kullanıcı bakış açısından yazılan daha anlaşılabilir kod
- Basit ,gereksiz kompekslik içermeyen kod
- Kodun tekrar düzenlenmesini oldukça kolaylaştırması
- Daha eğlenceli
Ne değildir?
- Yazılımı test etmek ile alakalı birşey değildir.
- Projedeki Tester arkadaşların yapması gereken bir aktivite değildir.
- Kodu yazıp artından test yazmak değildir.
- Geliştirme süresini arttıran bir stil değildir.
- Fantezi ürünü gerçek projelerde kullanılmayan bir geliştirme biçimi değildir.
- Sadece bazı dillerde,bazı projelerde kullanılabilecek bir aktivite değildir.
- Unit Testing framework kullanmak değildir.
- Gereksiz hiç değildir.
Öncelikle Ürün nesnemizi ve bunu depolayacak(repository), crud işlemlerini yapacak poco classlarımızı hazırlayalım..
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
interface IProductRepository
{
IEnumerable<Product> GetAll();
Product Get(int id);
Product Add(Product item);
bool Update(Product item);
bool Delete(int id);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Mvc4KnockoutCRUD.Models
{
public class ProductRepository : IProductRepository
{
private List<Product> products = new List<Product>();
private int _nextId = 1;
public ProductRepository()
{
// Add products for the Demonstration
Add(new Product { Name = "Computer", Category = "Electronics", Price = 23.54M });
Add(new Product { Name = "Laptop", Category = "Electronics", Price = 33.75M });
Add(new Product { Name = "iPhone4", Category = "Phone", Price = 16.99M });
}
public IEnumerable<Product> GetAll()
{
// TO DO : Code to get the list of all the records in database
return products;
}
public Product Get(int id)
{
// TO DO : Code to find a record in database
return products.Find(p => p.Id == id);
}
public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
// TO DO : Code to save record into database
item.Id = _nextId++;
products.Add(item);
return item;
}
public bool Update(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
// TO DO : Code to update record into database
int index = products.FindIndex(p => p.Id == item.Id);
if (index == -1)
{
return false;
}
products.RemoveAt(index);
products.Insert(index,item);
return true;
}
public bool Delete(int id)
{
// TO DO : Code to remove the records from database
products.RemoveAll(p => p.Id == id);
return true;
}
}
}
Daha sonra still, knockout kodu, ve html kodunu yazalım...
<style type="text/css">
body {
margin: 20px;
font-family: "Arial", "Helventica", sans-serif;
}
label {
width: 80px;
display: inline-block;
}
button {
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
padding: .4em 1.1em .4em;
color: #fef4e9;
border: solid 1px #006fb9;
background: #1276bb;
}
button:hover {
text-decoration: none;
background: #282828;
border: solid 1px #000;
}
table {
padding-top: 1em;
}
thead, tfoot {
font-weight: 600;
}
th, td {
padding: .1em .5em;
text-align: left;
}
td li, td ul {
margin: 0;
padding: 0;
}
td li {
display: inline;
}
td li::after {
content: ',';
}
td li:last-child::after {
content: '';
}
</style>
function formatCurrency(value) {
return "$" + value.toFixed(2);
}
function ProductViewModel() {
//Make the self as 'this' reference
var self = this;
//Declare observable which will be bind with UI
self.Id = ko.observable("");
self.Name = ko.observable("");
self.Price = ko.observable("");
self.Category = ko.observable("");
var Product = {
Id: self.Id,
Name: self.Name,
Price: self.Price,
Category: self.Category
};
self.Product = ko.observable();
self.Products = ko.observableArray(); // Contains the list of products
// Initialize the view-model
$.ajax({
url: '/api/product',
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Products(data); //Put the response in ObservableArray
}
});
// Calculate Total of Price After Initialization
self.Total = ko.computed(function () {
var sum = 0;
var arr = self.Products();
for (var i = 0; i < arr.length; i++) {
sum += arr[i].Price;
}
return sum;
});
//Add New Item
self.create = function () {
if (Product.Name() != "" && Product.Price() != "" && Product.Category() != "") {
$.ajax({
url: 'api/product',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(Product),
success: function (data) {
// alert('added');
self.Products.push(data);
self.Name("");
self.Price("");
self.Category("");
}
}).fail(
function (xhr, textStatus, err) {
alert(err);
});
}
else {
alert('Please Enter All the Values !!');
}
}
// Delete product details
self.delete = function (Product) {
if (confirm('Are you sure to Delete "' + Product.Name + '" product ??')) {
var id = Product.Id;
// alert(id);
$.ajax({
url: 'api/product/' + id,
cache: false,
type: 'DELETE',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Products.remove(Product);
// alert("Record Deleted Successfully");
}
}).fail(
function (xhr, textStatus, err) {
alert(err);
});
}
}
// Edit product details
self.edit = function (Product) {
self.Product(Product);
}
// Update product details
self.update = function () {
var Product = self.Product();
var id = Product.Id;
$.ajax({
url: 'api/product/' + id,
cache: false,
type: 'PUT',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(Product),
success: function (data) {
self.Products.removeAll();
self.Products(data); //Put the response in ObservableArray
self.Product(null);
alert("Record Updated Successfully");
}
})
.fail(
function (xhr, textStatus, err) {
alert(err);
});
}
// Reset product details
self.reset = function () {
self.Name("");
self.Price("");
self.Category("");
}
// Cancel product details
self.cancel = function () {
self.Product(null);
}
}
var viewModel = new ProductViewModel();
ko.applyBindings(viewModel);
ve son olarak html kodunu yazalım....
<div id="body">
<h2>Knockout CRUD Operations with MVC4</h2>
<h3>List of Products</h3>
<table id="products1" data-bind="visible: Products().length > 0">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: Products">
<tr>
<td data-bind="text: Id"></td>
<td data-bind="text: Name"></td>
<td data-bind="text: Category"></td>
<td data-bind="text: formatCurrency(Price)"></td>
<td>
<button data-bind="click: $root.edit">Edit</button>
<button data-bind="click: $root.delete">Delete</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td>Total :</td>
<td data-bind="text: formatCurrency($root.Total())"></td>
<td></td>
</tr>
</tfoot>
</table>
<br />
<div style="border-top: solid 2px #282828; width: 430px; height: 10px"> </div>
<div data-bind="if: Product">
<div>
<h2>Update Product</h2>
</div>
<div>
<label for="productId" data-bind="visible: false">ID</label>
<label data-bind="text: Product().Id, visible: false"></label>
</div>
<div>
<label for="name">Name</label>
<input data-bind="value: Product().Name" type="text" title="Name" />
</div>
<div>
<label for="category">Category</label>
<input data-bind="value: Product().Category" type="text" title="Category" />
</div>
<div>
<label for="price">Price</label>
<input data-bind="value: Product().Price" type="text" title="Price" />
</div>
<br />
<div>
<button data-bind="click: $root.update">Update</button>
<button data-bind="click: $root.cancel">Cancel</button>
</div>
</div>
<div data-bind="ifnot: Product()">
<div>
<h2>Add New Product</h2>
</div>
<div>
<label for="name">Name</label>
<input data-bind="value: $root.Name" type="text" title="Name" />
</div>
<div>
<label for="category">Category</label>
<input data-bind="value: $root.Category" type="text" title="Category" />
</div>
<div>
<label for="price">Price</label>
<input data-bind="value: $root.Price" type="text" title="Price" />
</div>
<br />
<div>
<button data-bind="click: $root.create">Save</button>
<button data-bind="click: $root.reset">Reset</button>
</div>
</div>
</div>
Product Controler :
public class ProductController : ApiController
{
static readonly IProductRepository repository = new ProductRepository();
public IEnumerable<Product> GetAllProducts()
{
return repository.GetAll();
}
public Product PostProduct(Product item)
{
return repository.Add(item);
}
public IEnumerable<Product> PutProduct(int id, Product product)
{
product.Id = id;
if (repository.Update(product))
{
return repository.GetAll();
}
else
{
return null;
}
}
public bool DeleteProduct(int id)
{
if (repository.Delete(id))
{
return true;
}
else
{
return false;
}
}
}
Evet bunu bir web api değilde MVC4 projesi yapmak isterseniz product controlerı Json döndürecek şekilde düzenleyebilirsiniz.bu şekilde düzenleyebilirsiniz..
public class ProductController : Controller
{
static readonly IProductRepository repository = new ProductRepository();
public ActionResult Product()
{
return View();
}
public JsonResult GetAllProducts()
{
return Json(repository.GetAll(), JsonRequestBehavior.AllowGet);
}
public JsonResult AddProduct(Product item)
{
item = repository.Add(item);
return Json(item, JsonRequestBehavior.AllowGet);
}
public JsonResult EditProduct(int id, Product product)
{
product.Id = id;
if (repository.Update(product))
{
return Json(repository.GetAll(), JsonRequestBehavior.AllowGet);
}
return Json(null);
}
public JsonResult DeleteProduct(int id)
{
if (repository.Delete(id))
{
return Json(new { Status = true }, JsonRequestBehavior.AllowGet);
}
return Json(new { Status = false }, JsonRequestBehavior.AllowGet);
}
}
Görüldüğü işlemleri web api üzeriden yapmaktayız. tabii burada securty düşünülmemiştir.
kaynak: Shailendra Chauhan, kaynadosyayı buradan erişebilirsiniz. Yazara teşekkür ediyorumm..
WebAPI-KnockoutCRUD.rar (11,17 mb)
Mvc4KnockoutCRUD.rar (11,14 mb)
public static MvcHtmlString DatePickerDropDowns(this HtmlHelper html,
string dayName, string monthName, string yearName,
int? beginYear = null, int? endYear = null,
int? selectedDay = null, int? selectedMonth = null, int? selectedYear = null, bool localizeLabels = true)
{
var daysList = new TagBuilder("select");
var monthsList = new TagBuilder("select");
var yearsList = new TagBuilder("select");
daysList.Attributes.Add("name", dayName);
monthsList.Attributes.Add("name", monthName);
yearsList.Attributes.Add("name", yearName);
var days = new StringBuilder();
var months = new StringBuilder();
var years = new StringBuilder();
string dayLocale, monthLocale, yearLocale;
if (localizeLabels)
{
var locService = new LocaleService();
dayLocale = locService.GetResource("Day");
monthLocale = locService.GetResource("Month");
yearLocale = locService.GetResource("Year");
}
else
{
dayLocale = "Day";
monthLocale = "Month";
yearLocale = "Year";
}
days.AppendFormat("<option value='{0}'>{1}</option>", "0", dayLocale);
for (int i = 1; i <= 31; i++)
days.AppendFormat("<option value='{0}'{1}>{0}</option>", i,
(selectedDay.HasValue && selectedDay.Value == i) ? " selected=\"selected\"" : null);
months.AppendFormat("<option value='{0}'>{1}</option>", "0", monthLocale);
for (int i = 1; i <= 12; i++)
{
months.AppendFormat("<option value='{0}'{1}>{2}</option>",
i,
(selectedMonth.HasValue && selectedMonth.Value == i) ? " selected=\"selected\"" : null,
CultureInfo.CurrentUICulture.DateTimeFormat.GetMonthName(i));
}
years.AppendFormat("<option value='{0}'>{1}</option>", "0", yearLocale);
if (beginYear == null)
beginYear = DateTime.UtcNow.Year - 100;
if (endYear == null)
endYear = DateTime.UtcNow.Year;
for (int i = beginYear.Value; i <= endYear.Value; i++)
years.AppendFormat("<option value='{0}'{1}>{0}</option>", i,
(selectedYear.HasValue && selectedYear.Value == i) ? " selected=\"selected\"" : null);
daysList.InnerHtml = days.ToString();
monthsList.InnerHtml = months.ToString();
yearsList.InnerHtml = years.ToString();
return MvcHtmlString.Create(string.Concat(daysList, monthsList, yearsList));
}
Ayrıca Session timeOut olunca işe yarayan bir kok
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class MyAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
OnAuthorizationHelp(filterContext);
}
internal void OnAuthorizationHelp(AuthorizationContext filterContext)
{
if (filterContext.Result is HttpUnauthorizedResult)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.HttpContext.Response.End();
}
}
}
}
$(document).ajaxError(function (xhr, props) {
if (props.status === 401) {
location.reload();
}
});
Web.Configde aşğıdaki ayarıda yapmak gerekiyor tabii.
<forms loginUrl="~/Account/Login" timeout="30" />
Ayrıca
Jquery-json post örneği verelim..
Global.asax da eklemizi yapalım..
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
Sonra poco classlarımızı oluşturalım
[Serializable]
public class PersonInputModel
{
public string Name { get; set; }
public int Age { get; set; }
public List<Book> Books { get; set; }
}
[Serializable]
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
}
Action methodumuzu hazırlayalım..
[HttpPost]
public ActionResult Save(PersonInputModel inputModel)
{
if (ModelState.IsValid)
{
var message = string.Format("İsmi '{0}' yaşı '{1}' olan kişi kaydedildi ayrıca '{2}' adet kitabı var."
, inputModel.Name, inputModel.Age, inputModel.Books.Count);
return Json(new PersonViewModel { Message = message });
}
var errorMessage = ModelState.Keys.Select(key => ModelState[key].Errors.FirstOrDefault()).Where(error => error != null).Aggregate("<div class=\"validation-summary-errors\">" + "The following errors occurred:<ul>", (current, error) => current + ("<li class=\"field-validation-error\">" + error.ErrorMessage + "</li>"));
errorMessage += "</ul>";
return Json(new PersonViewModel { Message = errorMessage });
}
<input type="text" value="Name" id="Name" />
<input type="text" value="10" id="Age" />
<input type="button" value="Create" id="personCreate" />
@section scripts
{
<script type="text/javascript">
$(function () {
$("#personCreate").click(function () {
var person = {};
person.Name = $("#Name").val();
person.Age = $("#Age").val();
var books = [];
var book = {};
book.Id = "1";
book.Name = "Katre-i Matem";
var book2 = {};
book2.Id = "1";
book2.Name = "Olasılıksız";
books.push(book);
books.push(book2);
person.books = books;
var json = $.toJSON(person);
$.ajax({
url: '/home/save',
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
// get the result and do some magic with it
var message = data.Message;
alert(message);
}
});
});
});
</script>
}
Tabii java script kodunun çalışması için jquery-json{version} eklentisi olması unutmuyoruz.
referans: http://www.kalbeyn.com/
Merhaba arkadaşlar,
Bu makalemizde json ne demektir, tür dönüşümleri,Dictionary<T> dönüşümlerini anlatacağım.
Json Java tabanlı XML gibi içerik kategorileme dilidir. XML' e göre avantajı açıp kapanan tagların yerine sadece bir başlıkda yazılması ve kapasite tasarrufu sağlanmasıdır. JavaScript Object Notatin anlamına gelmektedir.
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
Bu Json verisinin Xml karşılığı aşağıdaik gibidir.
<menu id="file" value="File">
<popup>
<menuitem value="New" onclick="CreateNewDoc()" />
<menuitem value="Open" onclick="OpenDoc()" />
<menuitem value="Close" onclick="CloseDoc()" />
</popup>
</menu>
Buradan örnek dönüşleri inceleyebilirsiniz.
Örnek bir c# projesi yapalım...
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace JsonProcess
{
class Program
{
static void Main(string[] args)
{
Product p1 = new Product
{
Name = "Ürün 1",
Price = 99.95m,
ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
Sizes = new string[] { "Small", "Medium", "Large" }
};
Product p2 = new Product
{
Name = "Ürün 2",
Price = 12.50m,
ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
Sizes = new string[] { "Small", "Medium"}
};
List<Product> products = new List<Product>();
products.Add(p1);
products.Add(p2);
//Formatting.Indented satır başı yapar.
//Bu Formating enumu Xml kütüphanesinde de olduğu için ben uzun yazdım..
string json = JsonConvert.SerializeObject(products, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(json);
List<Product> productsDonusum = JsonConvert.DeserializeObject<List<Product>>(json);
Console.WriteLine(products.Count);
Product urun1 = products[0];
Console.WriteLine(p1.Name);
string json2 = @"{""key1"":""value1"",""key2"":""value2""}";
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Console.WriteLine(values.Count);
Console.WriteLine(values["key1"]);
}
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime ExpiryDate { get; set; }
public string[] Sizes { get; set; }
}
}
Ayrıca mvc projelerinde modelden gelen bir bilgiyi knockout teknolojisinde şu şkilde dönüşümlerde yapabilriz.
this.IsActive = ko.observable(@Html.Raw(Json.Encode(@Model.IsActive)))
Bir sonraki yazımda görüşmek üzere hoşçakalınız.
Merhaba değerli okuyucular,
Bugün Microsoft firmasının da desteklediği knockout teknolojisini anlatacağım ve kendimde bunun yanında bir uygulama yapacağım.
Resmi sitesini buradan ve kendi öğreticisini(learnig) buradan erişebilirsiniz. Knockout kaynak bir javascript koddur, MIT license sahip olarak GitHub yayınlanmaktadırç Bu sistem MVVM sistemini(model, view, viewModel), object-oriented JavaScripts ve declarative bindings teknolojilerini barındırmaktadır. IE 6+, Mozzilla 2+, Chrome ve diğer tarayıcıları destelemektedir.
Biz bu teknoloji ile client-side tarafında zengin interaktif uygulamar yazabiliriz. Ben bir projeyi geliştirerek yazacağım. Microsoft dan Steve Sandersen bir webinerinde geliştirdiği uygulamayı yazacağım, farkı aynı senaryoyu kullanarak yeni yazım formatıyla yazacağım.
İlk olarak Boş internet şablonlu bir MVC4 proje uygulaması açalım.
<script src="/Scripts/knockout-2.2.0.js" type="text/javascript"></script>
<h1>İlk kodlar</h1>
<p>Ad <span data-bind="text:Ad">adım </span></p>
<p>Soyad <span data-bind="text:SoyAd">soyadım </span></p>
<script>
function View() {
this.Ad = "kemal";
this.SoyAd="Mustafa";
}
ko.applyBindings(new View);
</script>
----------------------------------------
<p>Ad <span data-bind="text:Ad">adım </span></p>
<p>Soyad <span data-bind="text:SoyAd">soyadım </span></p>
<p>Ad <span data-bind="text: Ad">adım </span></p>
<p>Soyad <span data-bind="text: SoyAd">soyadım </span></p>
-----------------------------------------
<p>Ad <span data-bind="text:Ad">adım </span></p>
<p>Soyad <span data-bind="text:SoyAd">soyadım </span></p>
<p>Ad <input data-bind="value: Ad">adım </input></p>
<p>Soyad <input data-bind="value: SoyAd">soyadım </input></p>
<script>
function View() {
this.Ad = "kemal";
this.SoyAd="Mustafa";
}
ko.applyBindings(new View);
</script>
--------------------------------------------
<p>Ad <span data-bind="text:Ad">adım </span></p>
<p>Soyad <span data-bind="text:SoyAd">soyadım </span></p>
<p>Ad <input data-bind="value: Ad"> </input></p>
<p>Soyad <input data-bind="value: SoyAd"> </input></p>
<script>
function View() {
this.Ad = ko.observable("kemal");
this.SoyAd=ko.observable("Mustafa");
}
ko.applyBindings(new View);
</script>
----------------------------------------
<p>Ad <span data-bind="text:Ad">adım </span></p>
<p>Soyad <span data-bind="text:SoyAd">soyadım </span></p>
<p>Ad <input data-bind="value: Ad"> </input></p>
<p>Soyad <input data-bind="value: SoyAd"> </input></p>
<p>Ad ve Soyad <span data-bind="text: AdSoyad"> </span></p>
<script>
function View() {
this.Ad = ko.observable("kemal");
this.SoyAd = ko.observable("Mustafa");
this.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
},this);
}
ko.applyBindings(new View);
</script>
-----------------------------------------------
<p>Ad <span data-bind="text:Ad">adım </span></p>
<p>Soyad <span data-bind="text:SoyAd">soyadım </span></p>
<p>Ad <input data-bind="value: Ad"> </input></p>
<p>Soyad <input data-bind="value: SoyAd"> </input></p>
<p>Ad ve Soyad <span data-bind="text: AdSoyad"> </span></p>
<button data-bind="click: Buyuk">Buyuk Harf Yap</button>
<script>
function View() {
this.Ad = ko.observable("kemal");
this.SoyAd = ko.observable("Mustafa");
this.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
},this);
this.Buyuk = function () {
var buyukHarf = this.SoyAd();
this.SoyAd(buyukHarf.toUpperCase());
};
}
ko.applyBindings(new View);
</script>
------------------------------------------------
<script src="/Scripts/knockout-2.2.0.js" type="text/javascript"></script>
<h1>İlk kodlar</h1>
<p>Ad <input data-bind="value: Ad"> </input></p>
<p>Soyad <input data-bind="value: SoyAd"> </input></p>
<p>Ad ve Soyad <span data-bind="text: AdSoyad"> </span></p>
<h2>Arkadaşlar :</h2>
<ul data-bind="foreach:Arkadaslar">
<li data-bind="text:name"> </li>
</ul>
<script>
function Arkadas(name) {
this.name = name;
}
function View() {
this.Ad = ko.observable("kemal");
this.SoyAd = ko.observable("Mustafa");
this.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
}, this);
this.ekle = function () {
this.Arkadaslar.push(new Arkadas("Başka Arkadaşım"));
}
this.Arkadaslar = ko.observableArray([
new Arkadas("Erkan"),
new Arkadas("Ayhan"),
new Arkadas("Murat")
]);
}
ko.applyBindings(new View);
</script>
-------------------------------------------
Şimdi kolleksiyon, databind ve ekleme işlemleri yaparak projemizi geliştirelim.
<p>Ad <input data-bind="value: Ad"> </input></p>
<p>Soyad <input data-bind="value: SoyAd"> </input></p>
<h2>Arkadaşlar :</h2>
<ul data-bind="foreach:Arkadaslar">
<li data-bind="text:name"> </li>
</ul>
<button data-bind="click: ekle">Arkadaş Ekle</button>
<script>
function Arkadas(name) {
this.name = name;
}
function View() {
this.Ad = ko.observable("kemal");
this.SoyAd = ko.observable("Mustafa");
this.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
}, this);
this.ekle = function () {
this.Arkadaslar.push(new Arkadas("Başka Arkadaşım"));
}
this.Arkadaslar = ko.observableArray([
new Arkadas("Erkan"),
new Arkadas("Ayhan"),
new Arkadas("Murat")
]);
}
ko.applyBindings(new View);
</script>
Şimdi ben bu koda silme kodu ekleyeceğim. Fakat 2 farklı yöntemle eklemek istiyorum. Birinci table ile ve diğeri ise bir script kod oluşturarak ekliyorum..
<script src="/Scripts/knockout-2.2.0.js" type="text/javascript"></script>
<h1>İlk kodlar</h1>
<p>Ad <input data-bind="value: Ad"/></p>
<p>Soyad <input data-bind="value: SoyAd"/> </p>
<p>Ad Soyad <strong data-bind="text: AdSoyad"> </strong></p>
@*<div data-bind="template: 'ArkadaslarTemp'"></div>*@
<h2>Arkadaşlar :</h2>
<table>
<thead><tr>
<th>Arkadaslar</th><th>İşlemler</th><th>Facebook</th>
</tr></thead>
<tbody data-bind="foreach: Arkadaslar">
<tr>
<td><input data-bind="value: name"/></td>
<td><a href="#" data-bind="click: $root.sil">silin</a></td>
</tr>
</tbody>
</table>
<ul data-bind="template : {name:'Ftemp',foreach: Arkadaslar}"></ul>
<script id="Ftemp" type="text/html">
<li>
<input data-bind="value: name"/>
<button data-bind="click: $root.sil"> silin </button>
</li>
</script>
<button data-bind="click: ekle">Arkadaş Ekle</button>
<script>
function friend(name) {
var self = this;
self.name = ko.observable(name);
}
function View() {
var self = this;
self.Ad = ko.observable("kemal");
self.SoyAd = ko.observable("Mustafa");
self.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
}, this);
self.Arkadaslar = ko.observableArray([
new friend("Erkan"),
new friend("Ayhan"),
new friend("Murat")
]);
self.ekle = function () {
self.Arkadaslar.push(new friend("Başka Arkadaşım"));
}
self.sil = function (name) {
self.Arkadaslar.remove(name);
}
}
ko.applyBindings(new View());
</script>
Daha Sonra ben buna face adresi varmı, face adresi gibi alanlar ekliyorum. Face adresi boolean değere göre face adresini gizletiyorum Ayrıca arkadaslar kolleksiyonun değerini yukarıdaki h2 etiketine ekliyorum.. Sonrada Arkadaş ekle butonuna 6 arkadaş ekleeycek şekilde enable değerini Arkadaslar().length<6 gibi bir şarta bağladım.
<script src="/Scripts/knockout-2.2.0.js" type="text/javascript"></script>
<h1>İlk kodlar</h1>
<p>Ad <input data-bind="value: Ad"/></p>
<p>Soyad <input data-bind="value: SoyAd"/> </p>
<p>Ad Soyad <strong data-bind="text: AdSoyad"> </strong></p>
@*<div data-bind="template: 'ArkadaslarTemp'"></div>*@
<h2>Arkadaşlar(<span data-bind="text: Arkadaslar().length"></span>)</h2>
<table>
<thead><tr>
<th>Arkadaslar Tablosu</th><th>İşlemler</th><th>Facebook Varmı</th><th>Facebook Adress</th>
</tr></thead>
<tbody data-bind="foreach: Arkadaslar">
<tr>
<td><input data-bind="value: name"/></td>
<td><a href="#" data-bind="click: $root.sil">silin</a></td>
<td><label><input type="checkbox" data-bind="checked: FaceVarmi"/>FaceVarmı</label></td>
<td><input data-bind="value: FaceAdres, visible: FaceVarmi"/></td>
</tr>
</tbody>
</table>
<h3>Arkadaşlar Listesi</h3>
<ul data-bind="template: { name: 'Ftemp', foreach: Arkadaslar }"></ul>
<script id="Ftemp" type="text/html">
<li>
<input data-bind="value: name"/>
<input data-bind="value: SoyAd"/>
<label><input type="checkbox" data-bind="checked: FaceVarmi"/>FaceVarmi</label>
<input data-bind="value: FaceAdres, visible:FaceVarmi"/>
<button data-bind="click: $root.sil"> silin </button>
</li>
</script>
<button data-bind="click: ekle, enable:Arkadaslar().length<6">Arkadaş Ekle</button>
<script>
function friend(name,soyad,val) {
var self = this;
self.name = ko.observable(name);
self.SoyAd = ko.observable(soyad);
self.FaceVarmi = ko.observable(val);
self.FaceAdres = ko.observable();
}
function View() {
var self = this;
self.Ad = ko.observable("kemal");
self.SoyAd = ko.observable("özler");
self.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
}, this);
self.Arkadaslar = ko.observableArray([
new friend("Erkan", "yürek",true),
new friend("Ayhan"," ballı", false),
new friend("Murat", "Can",false)
]);
self.ekle = function () {
self.Arkadaslar.push(new friend("Başka Arkadaşım"));
}
self.sil = function (name) {
self.Arkadaslar.remove(name);
}
}
ko.applyBindings(new View());
</script>
Kodun En sonunda Json tipinde veriyi ajax ile conroler a görderdim..
<script src="/Scripts/knockout-2.2.0.js" type="text/javascript"></script>
<h1>İlk kodlar</h1>
<p>Ad <input data-bind="value: Ad"/></p>
<p>Soyad <input data-bind="value: SoyAd"/> </p>
<p>Ad Soyad <strong data-bind="text: AdSoyad"> </strong></p>
<h2>Arkadaşlar(<span data-bind="text: Arkadaslar().length"></span>)</h2>
<table>
<thead><tr>
<th>Arkadaslar Tablosu</th><th>İşlemler</th><th>Facebook Varmı</th><th>Facebook Adress</th>
</tr></thead>
<tbody data-bind="foreach: Arkadaslar">
<tr>
<td><input data-bind="value: name"/></td>
<td><a href="#" data-bind="click: $root.sil">silin</a></td>
<td><label><input type="checkbox" data-bind="checked: FaceVarmi"/>FaceVarmı</label></td>
<td><input data-bind="value: FaceAdres, visible: FaceVarmi"/></td>
</tr>
</tbody>
</table>
<h3>Arkadaşlar Listesi</h3>
<ul data-bind="template: { name: 'Ftemp', foreach: Arkadaslar }"></ul>
<script id="Ftemp" type="text/html">
<li>
<input data-bind="value: name"/>
<input data-bind="value: SoyAd"/>
<label><input type="checkbox" data-bind="checked: FaceVarmi"/>FaceVarmi</label>
<input data-bind="value: FaceAdres, visible:FaceVarmi"/>
<button data-bind="click: $root.sil"> silin </button>
</li>
</script>
<button data-bind="click: ekle, enable:Arkadaslar().length<6">Arkadaş Ekle</button>
<button data-bind="click: save">save</button>
<script>
function friend(name,soyad,val,adres) {
var self = this;
self.name = ko.observable(name);
self.SoyAd = ko.observable(soyad);
self.FaceVarmi = ko.observable(val);
self.FaceAdres = ko.observable(adres);
}
function View() {
var self = this;
self.Ad = ko.observable("kemal");
self.SoyAd = ko.observable("özler");
self.AdSoyad = ko.computed(function () {
return this.Ad() + " " + this.SoyAd();
}, this);
self.Arkadaslar = ko.observableArray([
new friend("Erkan", "yürek",true,"www.facebook.com/canercanli"),
new friend("Ayhan"," ballı", false,null),
new friend("Murat", "Can",true,"www.facebook.com/muratcan")
]);
self.ekle = function () {
self.Arkadaslar.push(new friend("Başka Arkadaşım"));
}
self.sil = function (name) {
self.Arkadaslar.remove(name);
}
self.save= function () {
$.ajax({
url:"@Url.Action("Save","Home")",
type: "post",
data: ko.toJSON(this),
contentType: "application/json",
success:function (result) { alert(result); }
});
}
}
ko.applyBindings(new View());
</script>
Modellerimm;
public class Calisan
{
public string Ad {get;set;}
public string SoyAd { get; set; }
public string AdSoyad { get; set; }
public ICollection<Arkadas> Arkadaslar { get; set; }
}
public class Arkadas
{
public string name { get; set; }
public string SoyAd { get; set; }
public string FaceAdres { get; set; }
public bool FaceVarmi { get; set; }
}
Action methot ;
[HttpPost]
public JsonResult Save(Calisan person)
{
string mesaj = string.Format(" Kaydedildi {0} ", person.AdSoyad);
mesaj += string.Format(" {0} arkadas ile,", person.Arkadaslar.Count);
mesaj += string.Format(" {0} facebooklu arkadşı kaydedildi.", person.Arkadaslar.Where(x => x.FaceVarmi).Count());
return Json(mesaj, JsonRequestBehavior.AllowGet);
}
Bir sonraki yazımda görüşmek üzere hoşçakalın.
z