2011-12-22 7 views
9

MVC3 uygulamam için bir RESTful Json Api oluşturmak istiyorum. Tek bir nesne örneğinin işlenmesi için birden çok Http Fiilleri işlemek konusunda yardıma ihtiyacım var.MVC3 RESTful API Yönlendirme ve Http Fiil İşleme

okudum ne// çalışılan bana aynı adı paylaşan birden eylemlerle bir denetleyici için izin

MVC (HttpPost, HttpGet vs.) niteliklerini çalıştı, ama yine de farklı bir yöntem olmalıdır imzalar.

MVC'nin başlamadan önce rota kısıtlamaları yönlendirme modülünde gerçekleşir ve bana 4 açık yola sahip olur ve yine de tek tek denetleyici eylemleri gerektirir. Özel bir HTTP Fiil Özellik Bina

ASP.NET MVC AcceptVerbs and registering routes

eylem çağrılır olarak harekete erişmek ve daha sonra bağımsız değişken olarak geçmek için kullanılan fiil kapmak için kullanılabilir - Kod, daha sonra anahtar davalarını olacaktır. Bu yaklaşımla ilgili sorun, bazı yöntemlerin, eylemin kendisinin içinde değil, eylem filtresi düzeyinde ele alınması gereken yetki gerektirmesidir. , POST, PUT GET:

http://iwantmymvc.com/rest-service-mvc3


Gereksinimleri/Hedefler

tek örneği nesnesi için
  1. Bir rota imza, MVC dört ana HTTP Fiiller işlemek bekleniyor SİL. URI kimliği parametresini geçmedi zaman

    context.MapRoute("Api-SingleItem", "items/{id}", 
        new { controller = "Items", action = "Index", id = UrlParameter.Optional } 
    ); 
    
  2. , bir eylem POST ve PUT işlemesi gerekir. bir kimlik parametresi URI geçirildiğinde

    public JsonResult Index(Item item) { return new JsonResult(); } 
    
  3. , tek bir eylem GET ve DELETE idare edilmelidir.

    public JsonResult Index(int id) { return new JsonResult(); } 
    

Soru birden fazla eylem her benzersiz http fiil yanıt (aynı adı ve yöntem imzası paylaşımı) sahip olabilir nasıl

. İstenen örnek:

[HttpGet] 
public JsonResult Index(int id) { /* _repo.GetItem(id); */} 

[HttpDelete] 
public JsonResult Index(int id) { /* _repo.DeleteItem(id); */ } 

[HttpPost] 
public JsonResult Index(Item item) { /* _repo.addItem(id); */} 

[HttpPut] 
public JsonResult Index(Item item) { /* _repo.updateItem(id); */ } 

cevap

10

RESTful çağrılar için, eylemin hiçbir anlamı yoktur, çünkü yalnızca HTTP yöntemlerinden farklıdır. Bu yüzden hile statik bir işlem adı kullanmaktır, böylece denetleyicideki farklı yöntemler yalnızca kabul ettikleri HTTP yönteminde farklıdır.

MVC framework provides a solution for specifying action names olsa da, daha özlü ve kendi kendini açıklayan yapılabilir.

özel bir nitelik (bu özel bir eylem adına maçları) RESTful yöntemleri belirtmek için kullanılır

:

public sealed class RestfulActionAttribute: ActionNameSelectorAttribute { 
    internal const string RestfulActionName = "<<REST>>"; 

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) { 
     return actionName == RestfulActionName; 
    } 
} 

kontrolörleri HTTP yöntemi ile kombinasyon halinde kullanmak niteliklerini:

Biz bunu böyle çözüldü
public class MyServiceController: Controller { 
    [HttpPost] 
    [RestfulAction] 
    public ActionResult Create(MyEntity entity) { 
     return Json(...); 
    } 

    [HttpDelete] 
    [RestfulAction] 
    public ActionResult Delete(Guid id) { 
     return Json(...); 
    } 

    [HttpGet] 
    [RestfulAction] 
    public ActionResult List() { 
     return Json(...); 
    } 

    [HttpPut] 
    [RestfulAction] 
    public ActionResult Update(MyEntity entity) { 
     return Json(...); 
    } 
} 

Ve başarıyla bu denetleyicileri bağlamak amacıyla , biz (aynı anda da URL'leri özelleştirmek için izin olan) beforementionned özelliğinden statik bir işlem adıyla özel yolları kullanın:

tüm gereksinimleri kolayca kadarıyla söyleyebilirim bu yaklaşımla aşılabileceğini
routes.MapRoute(controllerName, pathPrefix+controllerName+"/{id}", new { 
    controller = controllerName, 
    action = RestfulActionAttribute.RestfulActionName, 
    id = UrlParameter.Optional 
}); 

Not; Bir yöntemde birden çok HTTP yöntemini kabul etmek için birden çok [HttpXxx] özniteliğine sahip olabilirsiniz. Bazı akıllı (er) ModelBinder ile eşleştirilmiş bu çok güçlü.

+0

Belki Yanıtınızda şey eksik, ama bu mantıklı değil. Örneğinizde, her eylemin farklı bir adı ve farklı bir imzası vardır. Aslında her biri farklı bir http fiiline cevap veren aynı yöntem imzalarıyla 4 ayrı eylem gerçekleştirmeye çalışıyorum. Ayrı eylemler olmalılar çünkü bir kısmı izin gerektirecek, diğerleri olmayacak. Güncellemeye bakın. @ –

+0

one.beat.consumer: Burada noktası yönteminin adı alakasız *, * olmasıdır çünkü onlar yolla statik olarak ayarlanır aynı eylem adları "<>" tüm maç. Bu nedenle, bir yol üzerinde istediğiniz sayıda yöntem (ve dinleyici denetleyici) olabilir ve çözümünüze (A) karşılık gelen herhangi bir sayıda "aynı" eyleme (farklı yöntem adlarına sahip olsa bile) sahip olabilirsiniz veya birden çok HTTP'ye sahip olabilirsiniz. Metot başına metotlar hangisini tercih ederseniz, B çözümünüz olur ve hatta bu çözümleri uygun gördüğünüz gibi karıştırabilirsiniz. one.beat.consumer @ – Lucero

+0

: Eğer bir '[Yetkilendirme]' özelliğini eklerseniz bu sadece iyi çalışır, böylece o yetkiyi Not (önceki yorumunda alanınız Ran), yöntem düzeyinde değil, eylem düzeyinde yapılır bazı fiil yöntemleri. – Lucero