Ne arayalım?

ARAMIZA KATILIN

BİZE ULAŞIN

Adres:

E-posta:

host/bin/bilisimlife.dll

iletisim@bilisimlife.net

ASP.NET Web Service (ASMX) URL Routing - Get ve Post Işlemleri 78317831 okunma

05.11.2018

ASP.NET

Rserit

Web Service kullananınız hala vardır. Şimdi işlemler daha kolaylaşmış olsa da eski teknolojilerde de kolaylıklar sağlanmasından yanayım. Bu kullanım kolaylığı sağladığı gibi güvenlik de getirir. Yeni Web APIye geçmemiş olsanız bile sisteminizde Internal olarak sağladığınız Web Methodlar bulunuyor olabilir. Bu Javascript tarafında işlemler yapmanıza olanak verir ki aslında bu yapının doğması da buradan gelir.

Amaç ASMX Web Hizmetleri olan mevcut bir web sitesi için URL yönlendirmesini uygulamak. Birinin bunu neden yapmak isteyeceğini tartışabilirsiniz, bu yüzden bunun nedenlerinden biri, mevcut web servislerini daha "modern" olarak yeniden yazmak zorunda kalmadan URL routing avantajlarından yararlanmak istememden kaynaklanıyor. MVC gibi bir alternatif aslında. Web API hizmeti daha fazla URL dostu oluyor ve büyük esneklik sağlıyor. Halihazırdaki projenizi de yenileyebiliriz.

Web uygulamanızın IIS7 ve üzeri, .NET 4 ve üzerinde çalışması gerekmektedir. Gerçekten MVCdeki yönlendirmenin aksine, WebFormsta bu daha az önemsizdir. WebForm  yapısının yönlendirmesinde MapPageRoute yöntemimiz var, ancak Web Service (ASMX) veya diğer işleyiciler için özel bir şeyimiz yok.

Daha geleneksel bir yöntemle örnek bir senaryo yaparak adım adım başlayalım.
Basit bir HelloWorld metodunu şöyle yazalım:

using System.Web;
using System.Web.Services;

 

[WebService(Namespace = "http://bilisimlife.net/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class TestService : System.Web.Services.WebService
{
    [System.Web.Services.WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] // Sadece GET işlemi yaptırmak için
    public string HelloWorld(string name)
    {
        return name;
    }
}
 
Web.config dosyamızda şu satırların olması gerektiğini unutmayın:
 
Web.config dosyamızda şu satırların olması gerektiğini unutmayın:
< system.web >
< webServices >
  < protocols >
< add name="HttpGet" / >
< add name="HttpPost" / >
  < / protocols >
< / webServices >
< / system.web >
 
Metodumuzu Javascriptten şöyle çağırabiliriz:
 
var obj;
var xhr = new XMLHttpRequest();
xhr.open("GET", "/TestService.asmx/HelloWorld?name=Recep");
xhr.setRequestHeader(Content-Type, application/json);
xhr.onload = function() {
if (xhr.status === 200 && xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.send(j);

onsol çıktısı olarak QueryString üzerinden verdiğim adı görebiliriz. 

Peki bu işi nasıl routing yapabiliriz?

1. Route Handler oluşturulması gerekli.

WebServiceRouteHandler sınıfı oluşturun ve şöyle yapılandırın:

using System;
using System.Web;
using System.Web.Routing;
public class WebServiceRouteHandler : IRouteHandler
{
    private static IHttpHandlerFactory ScriptHandlerFactory;
    static WebServiceRouteHandler()
    {
        var assembly = typeof(System.Web.Script.Services.ScriptMethodAttribute).Assembly;
        var type = assembly.GetType("System.Web.Script.Services.ScriptHandlerFactory");
        ScriptHandlerFactory = (IHttpHandlerFactory)Activator.CreateInstance(type, true);
    }
 
    private string virtualPath;
    public WebServiceRouteHandler(string virtualPath)
    {
        this.virtualPath = virtualPath;
    }
 
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string pathInfo = requestContext.RouteData.Values["path"] as string;
        if (!string.IsNullOrWhiteSpace(pathInfo))
            pathInfo = string.Format("/{0}", pathInfo);
 
        requestContext.HttpContext.RewritePath(this.virtualPath, pathInfo, requestContext.HttpContext.Request.QueryString.ToString());
        var handler = ScriptHandlerFactory.GetHandler(HttpContext.Current, requestContext.HttpContext.Request.HttpMethod, this.virtualPath, requestContext.HttpContext.Server.MapPath(this.virtualPath));
        return handler;
    }
}
 
2. Route config dosyası oluşturalım.
 
public static class ServiceRouteConfig
{
public static void RegisterRoutes(RouteCollection Routes)
{
Routes.Add(new System.Web.Routing.Route("test/{*path}", new ServiceRouteHandler("~/TestService.asmx")));
}
}
 
Burada ne kadar ASMX dosyamıza varsa hepsini istediğimiz gibi ekleyebiliriz.
 
Şöyle çağırıyorz:
ServiceRouteConfig.RegisterRoutes(Routes);
 
Şimdi ise Javascript ile şöyle çağırabiliriz:
 
var obj;
var xhr = new XMLHttpRequest();
xhr.open("GET", "/test/helloworld?name=recep"); // Metodu kısalttık
xhr.setRequestHeader(Content-Type, application/json);
xhr.onload = function() {
if (xhr.status === 200 && xhr.readyState == 4) {
console.log(xhr.responseText);
}
};
xhr.send(j);
 
Yukarıda oluşturduğumuz GetHttpHandler metoduna breakpoint koyarak takip edebilirsiniz. RouteData içinde path ve data bulunuyor.
Yani requestContext.RouteData.Values["path"] içerisinde /helloworld yazacaktır.
Dilerseniz daha estetik yazım için GETi şöyle yazabilirsiniz: "/test/hello-world?name=recep"
 
GetHttpHandler içinde tireyi replace ettirebilirsiniz.
 
Parametre olarak bir class verilmiş (model) metoda nasıl post işlemi yapabiliriz?
Bu da işin ince noktası. Bir XHR isteğinde post yapıldığında, bu bir InputStream olarak atanır ve RequestContext.HttpContext.Request.InputStream atında bulunur. InputStreamde Read() metoduyla neyin post edildiği görülebilir. Querystring ile veriyi göndermek oldukça basit. Şimdi class olarak verilen bir parametreye post için küçük bir değişiklik yapılması gerekiyor.
 
GetHttpHandler metodumuzda "ScriptHandlerFactory.GetHandler" alanını yenilememiz gerekiyor. Çünkü orada parametre olarak HttpContext.Current veriliyor. Bu şekilde veri gönderildiğinde requestContextteki veriyi yani post edilen veriyi alamayız. Bu bakımdan dolayı şöyle yeniliyoruz:
 
HttpContext Context = requestContext.HttpContext.ApplicationInstance.Context; // RequestContextBasei HttpContexte aktarıyoruz
requestContext.HttpContext.RewritePath(this.virtualPath, Path, requestContext.HttpContext.Request.QueryString.ToString(), true); // Rewrite yapıyoruz
var handler = ScriptHandlerFactory.GetHandler(Context, requestContext.HttpContext.Request.HttpMethod, this.virtualPath, requestContext.HttpContext.Server.MapPath(this.virtualPath));
return handler,

 
Işte budur! Şimdi post edilen modeli görecektir. 
 
Yeni web servis metodumuzun TestService.asmx/UrunEkleme olduğunu varsayalım. Parametre olarak da Urunler sınıfını alıyor.
Yeniden Javascript metodumuzu şöyle yazalım:
 
var x = { "ProductName": "Note 8" };
var j = JSON.stringify({ model: x }); // Parametrenin adı "model"
 
var obj, data;
var xhr = new XMLHttpRequest();
xhr.open("POST", "/test/servis/urun-ekleme"); // Route edilen path
xhr.setRequestHeader(Content-Type, application/json); // Json olarak gönderiyoruz
xhr.onload = function() {
if (xhr.status === 200 && xhr.readyState == 4) {
obj = JSON.parse(xhr.responseText); // Response
data = obj.d;
console.log(data);
}
};
xhr.send(j); // Modeli gönderdik
 
Işlemlerinizi mutlaka tarayıcının web konsolu üzerinden takip edin. Eksik bir şeyler olduğunda bunu daha iyi anlayabilirsiniz.


BİR YORUM YAZIN