2012-07-30 46 views
6

我在.NET MVC 3中實現了一個REST層。我正在尋找一種乾淨的方式來獲取Accept頭以確定是否應該返回Json或Xml。在.NET MVC中建模綁定的最簡單方法接受頭文件MVC

我也希望能夠用GET參數來欺騙這個頭文件來進行調試(我希望這個文件也可以堅持下去)。

這裏是我當前如何檢測這樣的:

if (Request.AcceptTypes.Contains("application/json") || Request.Url.Query.Contains("application/json")) 

這是在我的控制器代碼的唯一地方,直接接觸Request對象。我想要一個更清晰,更可測試的方式來閱讀這個。我理想的解決方案將是控制器上的參數。

我嘗試了幾個關鍵字來查看默認的模型綁定器是否會啓動它,但沒有嘗試過。

那麼,獲取這些信息的最簡潔方法是什麼?自定義模型聯編程序?你能提供一個例子嗎?

+0

如果你不反對mvc4 webapi,你可以爲你處理這個問題。更不用說當你將應用程序遷移到mvc4 +的時候,你將會處理一些MVC已經爲你做的事情。搜索mvc4內容類型協商以獲取更多信息。 – 2012-07-31 00:14:22

+0

我注意到了這一點,對此我感到非常興奮,但不幸的是,我無法在RC下發布這個項目,並且我可以告訴我沒有4的發佈日期。 – Travis 2012-07-31 03:01:10

+0

http://prideparrot.com/blog/archive/2012/3/returning_data_view_from_controller_action – VJAI 2012-07-31 06:03:33

回答

2

動作過濾器屬性將是一個很好的乾淨的解決方案。

有一個很好的教程在這裏:http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs

+0

感謝您的回答,但如果我正確理解這一點,我需要複製每個操作 - 一個用於Xml,一個用於Json。這對於封裝和可測試性來說似乎有點過分。或者我錯過了什麼? – Travis 2012-07-31 03:02:47

+1

你可以將它註冊爲一個全局動作過濾器,並在一個過濾器中處理Xml和Json。這不是你所追求的嗎?您仍然需要將其存儲在ViewData/Bag中,這不像我想的那樣「乾淨」。 – 2012-07-31 03:55:16

2

,我沒有看到一個自定義的模型綁定任何更好的選擇。我會在這裏發佈我的binder的實現,以防其他人看到這個。使用模型聯編程序允許Accept頭強制綁定到動作的直接輸入,從而允許直接測試返回類型,並且不會強制您人爲執行比您需要的更多操作,也不會導致動態類型化視圖數據/袋。

這裏的模型綁定有支撐枚舉類型:

public enum RequestAcceptType 
{ 
    NotSpecified, 
    Json, 
    Xml 
} 

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

     RequestAcceptType acceptType = RequestAcceptType.NotSpecified; 

     // Try for Json 
     if (controllerContext.HttpContext.Request.AcceptTypes.Contains("application/json") || controllerContext.HttpContext.Request.Url.Query.Contains("application/json")) 
     { 
      acceptType = RequestAcceptType.Json; 
     } 

     // Default to Xml 
     if (acceptType == RequestAcceptType.NotSpecified) 
     { 
      acceptType = RequestAcceptType.Xml; 
     } 

     return acceptType; 
    } 
} 

這裏是在Application_Start方法在Global.asax中的相關位:

ModelBinders.Binders[typeof(RequestAcceptType)] = new RequestAcceptTypeModelBinder(); 

然後用它在你的行動,只是使用枚舉類型進行參數(任意名稱):

public ActionResult Index(RequestAcceptType acceptType) 

如果沒有人用ab響應在幾天之內,我會接受這個答案。