Asp.Net MVC Web API Projesinde Ninject ile Dependency Injection

5 Tem

Bir önceki yazılarımdan biri olan MVC Projesinde Dependency Injection başlıklı yazıda MVC uygulamasında Controller sınıfı içerisine dışarıdan bağımlılıkların enjekte edilmesini incelemeye çalışmıştık. Bu yazımızda ise Asp.Net MVC Web Api uygulaması üzerinde Dependency Injection işlemini uygulamaya çalışacağız.

MVC uygulamasında Controller sınıfları System.Web.Mvc.Controller tipinden türetilirken API Controller sınıfları System.Web.Http.ApiController tipinden türetilmiştir. Bu nedenle Web API üzerinde Dependency Injection uygularken bir önceki örnek uygulamadaki yöntemden daha farklı bir yöntem kullanacağız.

public class ValuesController : ApiController
{
     readonly IProductRepository productRepository;
     public ValuesController(IProductRepository productRepository)
     {
          this.productRepository = productRepository;
     }

     public IEnumerable<string> Get()
     {
         return productRepository.GetValues();
     }
}

API içerisine bağımlılıkları enjekte ederken IProductRepository interface tipini uygulayan(implemente eden) sınıfları göndermeye dikkat edeceğiz.

WEB API içerisinde Dependency Injection işlemini gerçekleştirmek için yine MVC’de olduğu gibi IoC container kütüphanelerinden faydalanmamız gerekiyor.

WEB API projelerinde Controller sınıflarının parametreli şekilde çalışabilmesi için bazı ayarlamaları yapmamız gerekecek. Bu ayarlamalardan biri, System.Web.Http alanında bulunan GlobalConfiguration statik sınıfındaki DependencyResolver özelliğinin düzenlenmesi olacaktır. Bu sayede WEB API, resolver mekanizmasını tanıyacaktır. Bu ayarlama Global.asax.cs dosyası içerisinde yapılmaktadır. Tanımlama:

public class WebApiApplication : HttpApplication
{
     protected void Application_Start()
     {
         // Diğer kodlar...
         GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(CreateKernel());
     }

     private IKernel CreateKernel()
     {
         IKernel kernel = new StandardKernel();

         kernel.Bind<IProductRepository>().To<ProductRepository>();

         return kernel;
     }

}

NinjectDependencyResolver adında bir sınıf hazırlıyoruz ve yukarıdaki gibi DependencyResolver özelliğine atıyoruz. DependencyResolver özelliği IDependencyResolver tipindedir. Bu sebeple NinjectDependencyResolver sınıfı da IDependencyReolver tipini uygulamalıdır.

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
      private readonly IKernel kernel;

      public NinjectDependencyResolver(IKernel kernel): base(kernel)
      {
          this.kernel = kernel;
      }

      public IDependencyScope BeginScope()
      {
          return new NinjectDependencyScope(kernel.BeginBlock());
      }
}

NinjectDependencyResolver sınıfını aynı zamanda NinjectDependencyScope sınıfından türetiyoruz. Bunun sebebi ise IDependencyResolver interface tipinin barındırdığı BeginScope() metodudur. Bu metodun bir şekilde doldurulması gerekmektedir. NinjectDependencyScope tipi de kendi oluşturmuş olduğumuz bir sınıf olacaktır. Bu sınıfı de şu şekilde oluşturabiliriz.

public class NinjectDependencyScope : IDependencyScope
{
    IResolutionRoot resolver;

    public NinjectDependencyScope( IResolutionRoot resolver)
    {
        this.resolver = resolver;
    }

     public void Dispose()
     {
        IDisposable disposable = resolver as IDisposable;

        if (disposable!=null)
        {
            disposable.Dispose();
        }

        resolver = null;
     }

     public object GetService(Type serviceType)
     {
         if (resolver==null)
         {
             throw new ObjectDisposedException("this", "This scope has been disposed");
         }

         return resolver.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
         if (resolver == null)
         {

              throw new ObjectDisposedException("this", "This scope has been disposed");
         }

         return resolver.GetAll(serviceType);
     }

}

Son aşamayı da bu şekilde tamamladıktan sonra projemiz çalışabilir hale gelmiş demektir.

WEB API Sonuç
WEB API Sonuç

Projenin örnek kodlarını SkyDrive üzerinden paylaşıyorum.

Kaynak Kod: Burada

Asp.Net XMLHttpRequest ve Proxy Uygulaması

20 Haz

Bir önceki yazımızda XMLHttpRequest nedir, nasıl kullanılır ve kullanılırken ne gibi sorunlar ile karşılaşılır şeklinde bir incelemede bulunmuştuk.

Bu yazıda ise ASP.NET MVC tabanlı bir uygulamada javascript ile XMLHttpRequest göndermeyi ve karşılaşılan sorunları inceleyeceğiz.

Bir önceki yazımızda, bir XMLHttpRequest gönderme işleminin uygulama sunucusuna yapılması durumunda bir sorunla karşılaşmayacağımızdan ancak dışarıdaki bir sunucuya istek gönderirken bir yetki sorunuyla karşılaşacağımızdan bahsetmiştik.

Şimdi ASP.NET MVC uygulamasında bulunan bir controller sınıfındaki JsonResult döndüren bir action metoduna XMLHttpRequest göndermeye çalışalım.

public class HomeController : Controller
{
     public JsonResult Application()
     {
         var jsonResult = new {
                                Name = "XMLHttpRequest Applcaition",
                                Date = DateTime.Now.AddDays(-5).ToShortDateString()
                              };

        return Json(jsonResult, JsonRequestBehavior.AllowGet);
      }
}

Basit bir JSON nesnesi döndüren bir metod olşuturduk. Şimdi View tarafından bu metoda bir XMLHttpRequest gönderelim. Yani kendi uygulamamızı sunan sunucuya bir XMLHttpRequest gönderelim ve internet tarayıcımızın tavrına bakalım.

Uygulama Sunucusuna Gönderilen XMLHttpRequest
Uygulama Sunucusuna Gönderilen XMLHttpRequest

İnternet tarayıcımız hiç itiraz etmeden sorguyu Javascript aracılığı ile başarılı bir şekilde almıştır.

Şimdi de uygulama sunucumuzun dışındaki bir sunucuya istek(request) göndermeye çalışalım ve sonucu görelim.

Farklı Sunucuya XMLHttpRequest gönderilmesi
Farklı Sunucuya XMLHttpRequest gönderilmesi

Tarayıcımız kodu derlerken bize bir itirazda bulundu. Hata “Erişim Engellendi” şeklinde. İnternet tarayıcımız bize uygulama sunucumuz dışına çapraz(cross) sorgu gönderme izni vermiyor ve ağ iletişimini kapatıyor.

Bu sorunu aşmak için uygulama sunucumuza bir istek gönderip, uygulama sunucumuz üzerinden ilgili sorgunun sonucunu almaya çalışacağız. Yani arka kapıdan dolaşmak zorunda kaldık.

Şimdi projemize bir Proxy uygulaması oluşturup bu uygulama üzerinde işlemi deneyelim. Projemize Proxy adında bir dizin açıp içerisine Proxy.ashx adında bir Generic Handler ekleyelim.

public class proxy : IHttpHandler
{
     public void ProcessRequest(HttpContext context)
     {
         context.Response.ContentType = "text/plain";

         WebRequest request = WebRequest.Create("http://www.google.com");
         WebResponse webResponse = request.GetResponse();

         Stream responseStream = webResponse.GetResponseStream();

         if (responseStream != null)
         {
              StreamReader reader = new StreamReader(responseStream);

              context.Response.Write(reader.ReadToEnd());
         }
     }

     public bool IsReusable
     {
        get
        {
             return false;
        }
     }

}

Javascript üzerinden bu proxy’ye XMLHttpRequest göndereceğiz ve proxy’nin elde ettiği sonucu kullanacağız.

Proxy ile XMLHttpRequest
Proxy ile XMLHttpRequest

Olay bu kadar basit aslında. Bu şekilde istediğimiz sosyal paylaşım sitelerine, değişik hizmetler sunan web servislerine Javascript üzerinden erişebiliriz.

Bu yöntem, CBS tarzı harita uygulamalarında farklı yerlerde barınan sunuculara Javascript API’ler üzerinden sorgu gönderirken çok işe yarıyor. Örneğin Map servislerini bir sunucudan, Harita resimlerini başka bir sunucudan, kişi bilgilerini ayrı bir servis üzerinden çekip tek bir sunum ortamında faydalanmak mümkün hale gelebiliyor. Farklı çözümlerde bu yöntemi kullanmak size kalmış.

Bir sonraki yazıda görüşmek dileğiyle.

Asp.Net MVC JSON Model Bining

7 May

Asp.Net MVC mimarisinde yer alan model binding konusunu daha önceki yazılarda ele almıştık. Bu yazıda ise model binding işlemini JSON nesneleri ile uygylamaya çalışacağız. Web projelerinde ihtiyaç duyduğumuz  javascript tabanlı sorguları gerçekleştirmek için JSON nesnelerini .NET nesnelerine dönüştürmemiz gerekebilir. Request data olarak JSON nesnelerini POST edebilmeliyiz.

Örnek Uygulama

Örnek uygulama olarak bir ürün arama işlemini JSON formatındaki verileri bir Action metoda POST edeceğiz.

Öncelikli olarak Request ile gelen JSON fromatındaki veriyi deserialize ederek .Net nesnelerine dönüştürecek olan ModelBinder sınıfımızı oluşturmalıyız.

public class JsonModelBinder : IModelBinder
{
     public object BindModel(ControllerContext controllerContext,
                             ModelBindingContext bindingContext)
     {
          if (controllerContext == null)
             throw new ArgumentNullException("controllerContext");

          if (bindingContext == null)
             throw new ArgumentNullException("bindingContext");

          var serializer = new DataContractJsonSerializer(bindingContext.ModelType);
          var deSerialized = serializer.ReadObject(
                             controllerContext.HttpContext.Request.InputStream);

          return deSerialized;
    }

}

DataContractJsonSerializer sınıfının ReadObject metodu Request üzerinden ile gelen veriyi (InputStream), ModelBindingContext sınıfının ModelType parametresine göre uygun .Net tipine dönüştürür.

Şimdi de ModelBindingContext sınıfına gönderilecek olan tipi hazırlamalıyız.

[DataContract]
[ModelBinder(typeof(JsonModelBinder))]
public class JsonProductSearchRequest
{
     [DataMember]
     public string Name { get; set; }
     [DataMember]
     public string Color { get; set; }
}

System.Runtime.Serialization isim alanına dahil olan DataContract ve DataMember attribute tipleri sınıfları ve sınıf üyelerini serileştirilebilir hale getirmek için kullanılırlar. (Yeri gelmişken söylemekte fayda var; Bir tipi serileştirmek JSON, XML veya Binary şekillerde olabilmektedir. Biz örneğimizde JSON serileştirme üzerinde duracağız). JSonProductSearchRequest sınıfımızı, model binding sırasında ihtiyaç duyulan attribute olan ModelBinder ile imzalıyoruz, parametre olarak ise daha önceden hazırladığımız JsonModelBinder tipini gönderiyoruz.

Artık Controller tarafında ihtiyaç duyulan Action Metodları hazırlayabiliriz.

public class ProductController : Controller
{
   [HttpPost]
   public JsonResult JsonSearch(JsonProductSearchRequest request)
   {
       return null;
   }
}

JsonSearch Action metodu, daha önceden hazırladığımız JsonProductSearchRequest tipinde bir parametre almaktadır.

Şimdi hazırladığımız bu metoda fiddler yardımıyla bir istek (request) göndererek durumu incelemeye çalışalım.

Fiddler Json POST
Fiddler Json POST

Fiddler aracında Composer sekmesinden Request Tipini POST olarak seçiyoruz. Sunucudaki uygulama linkimizi girerek Request Body kısmına uygun JSON verisini giriyoruz. Execute butonuyla çalıştırdığımızda kodumuza geçip “break point” ile takip edersek:

Json Model Binder
Json Model Binder

Gönderdiğimiz verinin POST edildiğini rahatlıkla görebiliriz.

Bu şekilde etkili sonuç veren bir çözüme ModelBinding nimetlerinden faydalanarak ulaşmayı başardık. JSON tabanlı arama işlemlerini rahatlıkla bu şekilde gerçekleştirebiliriz. Ben bu örnekte View sayfalarıyla uğraşmamak adına fiddler aracından faydalanmayı uygun gördüm.

Bir sonraki yazıda görüşmek üzere.

Asp.net MVC DisplayTemplates Kullanımı

27 Tem

ASP.NET MVC projelerinde Model tarafından gelen property’ler için özel görünüm şablonları oluşturabiliriz. Bunun için kullanılacak yöntem DisplayTemplates şeklinde şablonlar oluştırmaktır. Display Template oluşturma işlemini gerçekleştirmek için Views/Shared altına DisplayTemplates şeklinde bir dizin oluşturmalıyız. Bu dizin altına şablonlarımızı tanımlayabiliriz.

Display  template içerisinde YesNo.cshtml adında bir partial view oluşturuyoruz. Bu view içerisini bool tipindeki değişkenleri istediğimiz gibi göstermek amacıyla doldurabiliriz. Örneğin kişinin profil tipinin gene veya özel olduğunu gösteren bir şablon oluşturalım. YesNo.cshtml içeriği aşağıdaki gibi olacaktır:

Model içeriğimizde şu şeklide olacaktır:

public class Register

{

[UIHint(“YesNo”)]

[Display(Name=”Profil Türü”)]

public bool Accept { get; set; }

}

Bu durumda view sayfalarında @Html.DisplayFor(m=>m.Accept) şeklindeki render istekleri sonucunda Genel veya özel şeklinde bir format oluşacaktır.

Sonuc:

Asp.net MVC Custom Image Helper

24 Tem

Asp.net mvc uygulamalarında view tarafında kullanılmak üzere kendi özel extension metodlarımızı oluşturabiliriz. Oluşturduğumuz extension metodları da mevcut Html helper tipine bağlayarak rahatlıkla kullanabiliriz.

Html helper tipinde mevcut extension metodlar Action, ActionLink, Label,… şeklinde devam etmektedir. Asp.net mvc takımı, genel ihtiyaçları karşılamak için bu metodları oluşturmuştur. Tüm ihtiyaçlara karşılık verecek metodları da oluşturup sisteme dahil etmeleri de anlamsız ve büyük bir yüktür zaten. İhtiyacımız olan tipleri kendimiz geliştirebilmemiz için bize açık kapı bırakılmıştır.

Bizde bu kapıdan girerek kendi image extension metodumuzu Html helper tipine dahil edelim.

Extension metodlar, statik bir sınıf içerisine statik metodlar halinde tanımlanırlar. Biz de bu şartlara göre Image metodumuzu oluşturabiliriz.


public static class ImageHelper
{
      public static MvcHtmlString Image(this HtmlHelper helper, string imageUrl, string altTag)
      {
            TagBuilder tag = new TagBuilder("img");
            tag.MergeAttribute("src", imageUrl);
            tag.MergeAttribute("alt", altTag);

            return MvcHtmlString.Create(tag.ToString());
      }
}

Artık bu sınıfı view tarafına gösterdiğimizde, @Html.Image(“”,””) şeklinde kullanabiliriz. O halde ImageHelper sınıfını view tarafına nasıl göstereceğimizi inceleyelim.

1.Yol

View sayfasının içerisinde using keywordu ile sınıfın bulunduğu dizini göstermek. View sayfasının  en üstüne @using MyProject.Helpers kodunu yapıştırarak extension metodu kullanmaya başlayabiliriz.

2.Yol

Solution penceresinde ASP.NET MVC projemizin Views dizinindeki web.config dosyası içerisindeki <system.web.webPages.razor>  içerisindeki <namespaces> düğümüne ekleyebiliriz.


<namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="MyProject.Helpers" />
</namespaces>

Bu yöntemi uyguladığımızda ilk etapta kodun kullanımı sırasında, extension metodumuzun altını kırmızı olarak çizebilir. Ancak kod çalışır. Eğer visual studio restart edilirse artık extension metodun altı çizilmeyecektir. Bu sorun intellisense tarafına kodumuzun web.config tarafından dahil olamadığındn kaynaklanıyor.

Kodun kullanımı:

@Html.Image(“../Content/Images/flower.jpg”,”flower”)

Sonuç:

Asp.Net MVC Gzip/Deflate Sıkıştırılmış (Compressed) içerik

15 May

Web sayfalarımızın içeriği genişledikçe, sunucu tarafından oluşturulan cevapların(response) boyutu artmaktadır. Bu boyutu küçültmenin yolu içeriği sıkıştırmaktır.

Bu işlemi incelemek için senaryomuzda, içeriği binlerce kelimeden oluşan bir sunucu cevabı (response) oluşturup,  kullanıcı(client) tarafına sunalım. Bu işlemi önce normal bir şekilde, ardından da sıkıştırılmış bir şekilde gerçekleştirelim ve farkı görelim.

ASP.NET MVC ortamında çalıştığımız için önce bir action metod oluşturup içeriğini doldurarak sunalım ve boyutuna bakalım.


public ActionResult Zip()
{
     StringBuilder result = new StringBuilder();

     for (int i = 0; i < 42000; i++)
     {
          result.Append("word");
     }

     return Content(result.ToString());
}

Yukarıdaki action metod ile 42000 kelimeyi içeren bir içeriği kullanıcıya sunuyoruz. Bu içeriğin boyutuna Firefox tarayıcısında Firebug eklentisiyle bakalım.

Sıkıştırılmamış içerik

Evet içerin 164.1KB boyutunda oluşturulmuş durumda.

Şimdi bu işlemi, içeriği sıkıştırarak yapmayı deneyelim. Önce sıkıştırılacak action metod veya controller sınıfını sıkıştırmaya yarayan bir attribute oluşturalım. Daha sonra sıkıştırmak istediğimiz metodu bu attribute ile imzalayabiliriz.

public class CompressAttribute: ActionFilterAttribute
{
      public override void OnActionExecuting(ActionExecutingContext filterContext)
      {
          var encodingAccept = filterContext.HttpContext.Request.Headers["Accept-Encoding"];

          if (string.IsNullOrEmpty(encodingAccept))
              return;

          encodingAccept = encodingAccept.ToLowerInvariant();

          var response = filterContext.HttpContext.Response;

          if (encodingAccept.Contains("gzip"))
          {
              response.AddHeader("Content-encoding", "gzip");
              response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
          }
          else if (encodingAccept.Contains("deflate"))
          {
              response.AddHeader("Content-encoding", "deflate");
              response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
          }

      }

}

Şimdi oluşturduğumuz bu attribute ile metodumuzu imzalayıp tekrar içerik boyutuna bakalım.

[Compress]
public ActionResult Zip()
{
      StringBuilder result = new StringBuilder();

      for (int i = 0; i < 42000; i++)
      {
           result.Append("word");
      }

      return Content(result.ToString());
}

Gzip sıkıştırılmış içerik

İçerik 1.9KB boyutuna düştü. Sıkıştırma işleminden önceki içerik 164.1KB idi. Bence bu müthiş birşey.

Tekrar görüşmek ümidiyle…

ASP.NET MVC ile Dosya okuma ve yazma işlemleri

14 May

Web ortamında bazı durumlarda dosyalarla işlem gerektiren durumlar olabilmektedir. Örneğin bir HTML sayfa, CSS dosyası, Text dosya veya şu anda aklıma gelmeyen bir çeşit dosyanın içeriğinin online olarak değiştirilmesi gibi.

Bu işlemi, ASP.NET MVC ortamında nasıl gerçekleştirebileceğimizi inceleyelim. Bu işlem için dosyalarımızın bulunduğu bir dizini belirleyip içindeki dosyaları kullanıcının önüne döküp, istediği gibi düzenlemesini sağlamaya çalışalım.

Dizin içindeki dosyaları kullanıcıya veren bir model sınıfı oluşturalım.


public class PersonelFiles
{
      public string FileName { get; set; }
}

Bu model sınıfından üretilen bir view oluşturmak için File controller içerisine Files adında bir action metod oluşturalım.


public class FileController : Controller
{
      public ActionResult Files()
      {
         DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Files"));

         var personelFiles = new List<PersonelFiles>();

         foreach (var item in directory.GetFiles("*.txt"))
         {
             personelFiles.Add(new PersonelFiles { FileName = item.Name });
         }

         return View(personelFiles);
     }
}

Files dizinindeki *.txt uzantılı dosyalarımızı listeleyecek bir view artık bu action metod üzerinden oluşturulabilir. Files() action metoduna sağ tıklayıp create view diyerek ilerleyebiliriz.

Şimdi de dosyaların içeriğini editleme işlemini gerçekleştirmek için, düzenle linkine tıklandığında dosya içeriğini bir kutu içerisinde bize sunacak action metodu yazalım.

Metod adı Edit şeklinde olacaktır.


public ActionResult Edit(string id)
{
     if (!string.IsNullOrEmpty(id))
     {
         StreamReader reader = new StreamReader(Server.MapPath("~/Files/") + id, System.Text.Encoding.Default);

         var content = new FileEditFormView()
         {
             FileContent = reader.ReadToEnd(),
             FileName = id
         };

         reader.Close();
         reader.Dispose();

         return PartialView("_Edit", content);
     }

     return View("FileNotFound");

}

Edit modtodu, düzenle linkine tıkladığımızda linkteki id parametresiyle dosya adını Edit metoduna verecektir. dosya içeriği okundukran sonra  FileEditFormView şeklinde karşımıza gelecektir.

Kaydet butonuna bastığımızda da POST metodu ile gönderdiğimizde de yazma işlemini gerçekleştireceğiz.


[HttpPost]
public ActionResult Edit(FileEditFormView form)
{
      StreamWriter writer = new StreamWriter(Server.MapPath("~/Files/") + form.FileName, false, System.Text.Encoding.Default);

      writer.Write(form.FileContent);
      writer.Close();
      writer.Dispose();

      return RedirectToAction("Files");
}

Bu şekilde işlem tamamlanmış olacaktır.

Düzenleme Geçmişi:

Başlık düzenlendi 25.09.2013
İçerik düzenlendi 25.09.2013

ASP.NET MVC Reset Password

7 May

Bir çok web sitesinin klasik bölümüdür şifremi unuttum bölümü. Kullanıcı adınızı veya email adresinizi girersiniz ve mail adresinize postalanır yeni şifreniz. Peki bu senaryo ASP.NET  MVC ile Membership yapısı kullanılarak nasıl yapılır? Yani kullanıcı şifresi resetlenir (reset password) ve yeni şifre mail olarak gönderilir.

Bu işlem için önce sistemimizin konfigurasyonunu mail gönderebilecek şekilde hazırlamamız gerekmektedir.


<system.net>
    <mailSettings>
       <smtp deliveryMethod="Network">
         <network host="mailhostadresiniz" (örneğin smtp.gmail.com)
                  port="587"
                  userName="emailadresiniz"
                  password="sifreniz"
                  enableSsl="true"/> (SSL gerektiren mail sunucu kullanıyorsanız)

       </smtp>
    </mailSettings>
</system.net>

Sistemimiz mail gönderemeye hazır bir vaziyete gelmiş durumda.

ASP.NET MVC projemizde Models dizinindeki Account model içerisine yeni bir model tanımlamalıyız. Bu modelin adı LostPasswordModel olacak.


public class LostPasswordModel
{
     [Required(ErrorMessage = "Kullanıcı adınızı giriniz.")]
     [Display(Name="Kullanıcı Adı")]
     public string Username { get; set; }
}

Bu model ile kullanıcıdan kullanıcı adını talep ederek mail adresine yeni şifresini göndereceğiz.

Bu modelden gelen kullanıcı adını alarak o kullanıcının şifresini sıfırlayıp, yeni mail adresine postalamalıyız. Bu işlemi yapmak için aşağıdaki metodu tanımlayabiliriz.

public void ResetPassword(string username)
{

     MembershipUser user = Membership.GetUser(username);

     string confirmationGuid = user.ProviderUserKey.ToString();
     string newPassword = user.ResetPassword();
     string bodyMessage = string.Format("Yeni Şifreniz {0}",newPassword);

     var message = new System.Net.Mail.MailMessage("kimden@mail.com", user.Email)
     {
         Subject = "Yeni şifre oluşturma isteği.",
         Body = bodyMessage
     };

     var client = new System.Net.Mail.SmtpClient();
         client.Send(message);
}

Bu metod sayesinde kullanıcının mail adresine yeni şifresini postalamış olduk.

ASP.NET MVC Email Doğrulama (Verification)

6 May

ASP.NET üyelik sistemlerinde bir gelenek olan üyelerin email adreslerini doğrulama işleminden bahsedelim birazda. Sistemimize üye olanları email adresleri aracılığıyla gerçek kullanıcı olup olmadıklarını anlayabiliriz bu sayede. Bu işlem için sistemin konfigurasyonlarının mail gönderebilecek hale getirilmesi gerek. Yani mail ayarları yapılmalıdır.


<system.net>
   <mailSettings>
      <smtp deliveryMethod="Network">
           <network host="mailhostadresiniz" (örneğin smtp.gmail.com)
                    port="587"
                    userName="emailadresiniz"
                    password="sifreniz"
                    enableSsl="true"/> (SSL gerektiren mail sunucu kullanıyorsanız)
      </smtp>
   </mailSettings>
</system.net>

Bu ayarlar yapıldıktan sonra üyelerin kayıtlarının yapıldığı sırada bir doğrulama postasının otomatik olarak gönderilmesi gerekir. Bu işlemi yapan metodu hazırlamalıyız.


public void SendConfirmationEmail(string username)
{

      MembershipUser user = Membership.GetUser(username);

      string confirmationGuid = user.ProviderUserKey.ToString();
      string verifyUrl = System.Web.HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) +
                         "/Account/Verify?Id=" +
                         confirmationGuid;

      string bodyMessage = string.Format("üyeliğiniz başarıyla oluşturulmuştur. Aşağıdaki linke tıkladığınızda hesabınızın aktif olacaktır.\n");
             bodyMessage += verifyUrl;

      var message = new System.Net.Mail.MailMessage(Models.Configuration.SystemMail, user.Email)
      {
          Subject = "Üyeliğinizi doğrulayın.",
          Body = bodyMessage
      };

     var client = new System.Net.Mail.SmtpClient();
         client.Send(message);

}

Mail gönderen metodumuz da artık hazır olduğuna göre bu metodu kayıt işlemi sırasında kullanabiliriz.


[HttpPost]
public ActionResult Register(RegisterModel model)
{

   if (ModelState.IsValid)
   {
       MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email, false);

       if (createStatus == MembershipCreateStatus.Success)
       {
            SendConfirmationEmail(model.UserName);

            return RedirectToAction("Confirmation","Account");
       }
       else
       {
            ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
       }

    }

    return View(model);

}

Artık kayıt olan üyelere otomatik olarak mail gönderiliyor.

Bu linke tıklandığında, üye Account controller içindeki Verify action metoduna yönlendirilecektir.


public ActionResult Verify(string Id)
{
     MembershipUser user = Membership.GetUser(new Guid(Id));

     user.IsApproved = true;
     Membership.UpdateUser(user);

     return RedirectToAction("Welcome");
}

Bu action metod sayesinde linke tıklayan üyenin üyeliği aktif hale getirilmiş oldu.

ASP.NET MVC Ajax.ActionLink ile sayfa yenilemeye son

30 Nis

İnternet sayfalarında artık yeni teknolojilerle birlikte javascript’in gücü iyice gösterilmeye başlandı. Sayfa yenilemeleri yapmak yerine sadece javascript ile sayfa üzerindeki etiketler(div) güncellenmekte. Linklere, butonlara tıklandığında istenen sonuçlar etkili bir biçimde bizi rahatsız etmeden önümüze dökülmekte. Son zamanlarda özellikle sosyal paylaşım sitelerinde javascript kendini o kadar belli ediyor ki, javascript’i icat edenler bile birgün bu kadar kullanılacağını tahmin etmemiştir.

Lafı fazla uzatmadan javascript özelliğini, liklere tıklandığında sayfa yenilemesi yapmadan önümüze getiren özelliği ASP.NET MVC mimarisinde kullanmaya çalışacağız.

Bir restorantın menü listesini önümüze getiren bir senaryomuz olduğunu varsayalım. Menü listesinde ürün adı ve fiyatı olsun. Bu yapıyı temsilen bir Menu adında sınıf oluşturmalıyız.


public class Menu
{
      public int Id { get; set; }
      public string Name { get; set; }
      public decimal Price { get; set; }
}

Şimdi MenuController adında bir controller sınıfı oluşturup bu controller sınıfının Index metodu ve Index view sayfası oluşturalım.


public class MenuController : Controller
{
      List<Menu> menu = new List<Menu>
      {
           new Menu{Id =1, Name="Hamburger", Price=3.15M},
           new Menu{Id =2, Name="Cheeseburger", Price=4.05M},
           new Menu{Id =3, Name="Cola", Price=2.0M},
           new Menu{Id =4, Name="Cips", Price=1.25M},
      };

      public ActionResult Index()
      {
           return View();
      }

      public ActionResult GetMenu()
      {
           return PartialView("_MenuPart", menu);
      }

}

Menu Listesi linkine tıklandığında sayfa yenilenmeksizin yukardaki liste tablo halinde linkin aldına indirilacek.

Bunun için yapılacak hazırlıklardan biri jquery.unobtrusive-ajax.min.js dosyasının view sayfasına referans edilmesi gerekmektedir. Aksi taktirde yaptığımız işlem çalışmayacaktır. Bu söylediklerim ASP.NET MVC3 için geçerli tabiki.

Referans olarak ana Layout sayfasına ekliyorum javascript dosyasını.

Şimdi Index view sayfası içine “Menu Listesi” linkini oluşturmalıyız.


@Ajax.ActionLink("Menu Listesi",
                 "GetMenu",
                 new AjaxOptions{
                                 InsertionMode=InsertionMode.Replace,
                                 UpdateTargetId="MenuBox",
                                 HttpMethod="GET",

                 })

<div id="MenuBox"></div>

Ajax helper sınıfının ActionLink Extension metodu ile link oluşturma işlemini gerçekleştirebiliriz. Bu metodun aldığı AjaxOptions parametresinde belirtilen, InsertionMode özelliği Replace olarak işaretlenir. Bu sayede işlem sonrasında, yani GetMenu metodundan dönen değeri UpdateTargerId parametresindeki html element içeriği ile değiştirileceğini belirtiyoruz.

Örneğimizde GetMenu metodu bir _MenuPart adında bir PartialView döndürüyor.

_MenuPart partial view içeriği ise şu şeklide olacaktır.


<table>
    <tr>
         <th>Name</th>
         <th>Price</th>
         <th></th>
    </tr>
    @foreach (var item in Model) {
    <tr>
        <td>@Html.DisplayFor(modelItem => item.Name)</td>
        <td>@Html.DisplayFor(modelItem => item.Price)</td>
        <td>@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.Id })
       </td>
    </tr>
    }

</table>

Sonuç olarak Index sayfasındaki Menu Listesi linkine tıklandığında bu tablo önümüze gelecek.