Konuya girmeden önce bu yazının web geliştiriciler için teknik bir implementasyon örneği olduğunu, işiniz geliştirme yapmak değilse sizin için anlamsız olabileceğini belirtmek istiyorum. Fakat bilgi bilgidir, nerde görürsem alırım derseniz mutlaka fayda sağlayacağınız kısımlar olacaktır.
Şimdi konumuza girebiliriz. Web uygulamalarında mobil kullanım için farklı geliştirme yaklaşımları bulunmaktadır. Bu yaklaşımlar özet olarak;
Bu yazıda üçüncü yaklaşımı birkaç senaryoya göre .Net Core Mvc kullanarak örnekleyeceğiz. Bunu da iki farklı geliştirme yöntemi olan subfolder (www.site.com/mobile) ve subdomain (m.site.com) olarak yapacağız. İlk örnek bu yazının konusu, ikincisi ise devam yazısı olarak gelecek. İkisi için de tek proje üzerinde geliştirme yapıp area kullanarak mobil ile masaüstünü birbirinden izole edeceğiz. Daha iyi pratikleri mutlaka var, fakat proje sayısını artırmamak ve yazının odağını dağıtmamak için aynı proje içinde işlemlerimizi yapacağız.
Öncelikle .Net Core MVC projesi oluşturuyoruz. Projeye bir area ekleyip ismini Mobile olarak belirliyoruz. Eklediğimiz area’ya bir controller ve action ekleyip aşağıdaki dosya görünümüne sahip oluyoruz.
Yönlendirme işlemlerini actionfilter’ları kullanarak yapıyoruz. Genel mantık olarak gelen isteğin hangi cihazdan geldiğini anlayıp ilgili action’a yönlendirilecek şekilde çalışıyor.
Eklediğimiz area için route ayarlamasını startup.cs dosyasında aşağıdaki şekilde yapıyoruz.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDetection();
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDetection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Sonraki aşamada yönlendirme işlemlerini yapacak actionfilter’ları ekliyoruz. Bu işlemi yapabilmek için istek yapan cihazı biliyor olmamız gerekiyor. İstek yapan cihazı tanımak için request üzerindeki user-agent bilgisi kullanılabilir. Fakat her cihaz, tarayıcı mobil bilgisini aynı şekilde tanımlamadığı için bu bilgiye ulaşmak çok kolay olmayabiliyor. Bu bilgiye ulaşmak için Wangkanai.Detection kütüphanesini kullanabiliriz. Bu sayede tüm browser ve cihazlar için cihaz tipini hızlıca tanıyabileceğiz. Yıldız sayısı yüksek, güvenli bir kütüphane olduğu için gönül rahatlığı ile kullanabilirsiniz. Kütüphaneyi projeye dahil edip actionfilter’ları aşağıdaki şekilde oluşturuyoruz.
using Microsoft.AspNetCore.Mvc.Filters;
using Wangkanai.Detection.Services;
namespace Mobile_Redirection_Subfolder
{
public class DesktopRedirectAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var path = filterContext.HttpContext.Request.Path.ToString();
if (!IsMobile())
{
path = path.Contains("/mobile/") ? path.Substring(7) : path;
filterContext.HttpContext.Response.Redirect(path);
}
bool IsMobile()
{
var service = (DetectionService)filterContext.HttpContext.RequestServices.GetService(typeof(IDetectionService));
var deviceType = service.Device.Type;
return deviceType == Wangkanai.Detection.Models.Device.Mobile;
}
}
}
}
using Microsoft.AspNetCore.Mvc.Filters;
using Wangkanai.Detection.Services;
namespace Mobile_Redirection_Subfolder
{
public class MobileRedirectAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var path = filterContext.HttpContext.Request.Path.ToString();
if (IsMobile())
{
filterContext.HttpContext.Response.Redirect("/mobile" + path);
}
bool IsMobile()
{
var service = (DetectionService)filterContext.HttpContext.RequestServices.GetService(typeof(IDetectionService));
var deviceType= service.Device.Type;
return deviceType == Wangkanai.Detection.Models.Device.Mobile;
}
}
}
}
Eğer cihaz mobil ise anlayıp yönlendirmeyi yapacak kod parçası:
Eğer cihaz mobil değilse masaüstüne yönlendirecek kod parçası:
Bu işlemlerden sonra actionfilter’lar controller ya da action seviyesinde kullanılabilir duruma geliyor.
Senaryomuzda iki sayfamız olduğunu ve birisinin mobil sayfasının olmadığını düşünelim. Bu senaryoyu oluşturmak için ana seviyedeki HomeController’a Index ve OnlyDesktop olacak şekilde iki action ekleyelim. Area altındaki HomeController içine de Index adında bir action ekleyelim. Index action’ının hem masaüstü hem de mobil için sayfaları olacak, OnlyDesktop action’ının sadece masaüstü için sayfası olacak. Aşağıdaki şekilde implemente ediyoruz.
[Area("Mobile")]
[DesktopRedirect]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
public class HomeController : Controller
{
[MobileRedirect]
public IActionResult Index()
{
return View();
}
public IActionResult OnlyDesktop()
{
return View();
}
}
Mobil area içindeki controller’da yapılan işlem:
Ana controller’da yapılan işlem:
Bu işlemleri de tamamladıktan sonra uygulamamızı test edebiliriz. Kontrol için browser’ın mobil görünüm özelliğini kullanarak testi tamamlayabiliriz.
Subfolder yaklaşımı ile mobil site implementasyon örneğimizi tamamladık. Sonraki yazıda subdomain yaklaşımı ile ilgili örnekte görüşmek üzere.