ASP.NET MVC中RESTful原教旨主義者的兩個實現細節

來源:互聯網
上載者:User

剛才無意中看到《什麼是REST?》一文。文章雖然很短,短到我幾乎要鄙夷一下作者的程度,但是仔細看了下,確也發現本文著實有用。

作為一名想盡量實現純RESTful服務的人(或可稱為RESTful原教旨主義者)來說,希望做出來的服務能盡量的符合RESTful原則定義,如果做出來一個RPC + ROA(面向資源的架構,其定義見《RESTful Web Services 中文版》)的服務,那還不如直接使用WCF算了,雖然,羅馬不是一天建成的,我也不可能一上手就構建一個純RESTful服務,但是盡量向標準靠攏還是很有必要的。

文中提到了一些概念,我很快發現在我的實踐中有兩條不符合。

其一:“REST式的Web Service使用HTTP裡的方法:GET, POST, DELETE, PUT。你不需要使用URL或請求的內容來指定這個方法。”

而在我目前的做法中,我是使用了類似這樣的Url:http://www.cleversoft.com/svc/log/create作為建立一條日誌記錄的url的,很明顯,在這個Url中,create是不必要的,甚至也是不應該出現的,為什麼呢,RESTful的原則之一:統一介面原則,為啥具有這個原則呢,統一介面的目的是建立一種面向程式的網站,既然是面向程式的,大家都嚴格的尊重約定便是一個十分重要的事情了,否則你開放了一個資源,如:http://www.anywhere.com/blog,(實際上這個資源甚至可以稱為API了)別人怎麼知道後面是Get還是Search才能調用呢?但是運用了統一介面原則,大家很自然就想到使用GET(Http Method)來擷取資料了,這就在很大程度上簡化了MetaData的定義。回到我的應用程式中來說,對於Log服務來說,http://www.cleversoft.com/svc/log/已經很明確的代碼了Log服務(資源的表示),使用POST方法就代表是建立日誌記錄了,畫蛇添足的加上一個Create,不是又回到RPC方式了嗎?

按照ASP.NET MVC的Route規則來說,想要用戶端使用http://www.cleversoft.com/svc/log的方式來調用到一個POST的方法,最簡單直接的方法便是建立一個方法

[HttpPost]public ActionResult Index(){    //...}

但是..這似乎也太銼了點吧,明明一個Create方法,使用Index..用戶端爽了,伺服器端的人該罵娘了吧,還是繼續使用Create方法名稱為好,代碼可讀性也是至上的啊。那就只能從Url Routing上想辦法了,結果很快發現了一個類型HttpMethodConstraint,哈哈,看起來就是為這件事準備的吧,於是為Url Routing添加新執行個體,如下代碼所示:

        public override void RegisterArea(AreaRegistrationContext context)        {            context.MapRoute("Svc_default_Create",                "Svc/{controller}/{action}",                new { action = "Create" },                new { httpMethod = new HttpMethodConstraint("POST") }                );            context.MapRoute("Svc_default_Update",                "Svc/{controller}/{action}",                new { action = "Update" },                new { httpMethod = new HttpMethodConstraint("PUT") }                );            context.MapRoute("Svc_default_Delete",                "Svc/{controller}/{action}",                new { action = "Delete" },                new { httpMethod = new HttpMethodConstraint("Delete") }                );            context.MapRoute(                "Svc_default",                "Svc/{controller}/{action}/{id}",                new { action = "Index", id = UrlParameter.Optional }            );        }

將用戶端Url中的Create刪除,使用http://www.cleversoft.com/svc/log添加Log記錄,成功!

下面說說其二,第2個相對來說更簡單點。文中提到“REST式的Web Service使用HTTP狀態代碼作為傳回值。”,我看Google中的服務,很多都是返回被建立(修改)的實體的,這我倒不願意,我向伺服器發了什麼我還不知道麼,這一來一回的多浪費啊,所以我就返回了new EmptyResult(),當然,返回EmptyResult應該就是返回一個200(Http StatusCode)吧,但是對於Create,Update,Delete來說,都返回200似乎顯的不那麼專業,於是對之前我做的HttpStatusResult稍作改動,為Controller添加幾個擴充方法:

        public static HttpStatusResult GetResult200(this Controller controller, params string[] content)        {            return new HttpStatusResult(HttpStatusCode.OK, content.Length > 0 ? content[0] : "OK");        }        public static HttpStatusResult GetResult201(this Controller controller, params string[] content)        {            return new HttpStatusResult(HttpStatusCode.Created, content.Length > 0 ? content[0] : "Created");        }        public static HttpStatusResult GetResult202(this Controller controller, params string[] content)        {            return new HttpStatusResult(HttpStatusCode.Accepted, content.Length > 0 ? content[0] : "Accepted");        }        public static HttpStatusResult GetResult204(this Controller controller, params string[] content)        {            return new HttpStatusResult(HttpStatusCode.NoContent, content.Length > 0 ? content[0] : "No Content");        }

這樣,就可以視情況向用戶端如實反映操作結果了,萬一以後有人使用別的用戶端調我的服務,也不至於罵我NC了,呵呵

使用方法樣本:

        [HttpPost]        [ServiceError]        public ActionResult Create([AtomEntryParameterConvert(typeof(LogEntry))]LogRecord log)        {            var logMng = new LogManager();            logMng.CreateLog(log);            return this.GetResult201();        }
ps: 聽說.NET 5.0可能會有擴充屬性?如果真有的話就不會讓這個操作顯的那麼難看了,期待...
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.