實作IControllerConfiguration介面
方法前一篇已經介紹過了:
1 | public class JsonOnlyAttribute : Attribute, IControllerConfiguration |
3 | public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor) |
5 | controllerSettings.Formatters.Clear(); |
6 | controllerSettings.Formatters.Add( new JsonMediaTypeFormatter()); |
以上是僅提供JSON Formatter的範例,這樣的好處是不用整個ASP.NET Web API 2專案都完全關閉XML Formatter,需要關閉時才關閉。
如果你是希望動態進行Controller層級組態的話,其實前一篇的參考文件有留下一篇MVP Filip的參考文章,以下簡述Filip文章以瞭解如何進行動態Controller組態。
態動Controller層級組態
一、新增一個延伸方法:
01 | public static class HttpConfigurationExtensions |
04 | /// 建立新HttpControllerSettings實體,並套用提供組態使用者的變更。 |
06 | /// <param name="configuration">HttpConfiguration</param> |
07 | /// <param name="settings">HttpControllerSettings</param> |
08 | public static HttpConfiguration Copy( this HttpConfiguration configuration, Action<HttpControllerSettings> settings) |
10 | var controllerSettings = new HttpControllerSettings(configuration); |
11 | settings(controllerSettings); |
14 | var constructor = typeof (HttpConfiguration).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, |
16 | new [] { typeof (HttpConfiguration), |
17 | typeof (HttpControllerSettings) }, |
19 | var instance = (HttpConfiguration)constructor.Invoke( new object [] { configuration, controllerSettings }); |
二、儲存組態設置
4 | public class ControllerConfig |
6 | public static Dictionary<Type, Action<HttpControllerSettings>> Map = new Dictionary<Type, Action<HttpControllerSettings>>(); |
三、由自訂IHttpControllerActivator呼叫HttpConfigurationExtensions方法
01 | public class PerControllerConfigActivator : IHttpControllerActivator |
03 | private static readonly DefaultHttpControllerActivator Default = new DefaultHttpControllerActivator(); |
04 | private readonly ConcurrentDictionary"Type, HttpConfiguration> _cache = new ConcurrentDictionary<Type, HttpConfiguration>(); |
07 | /// 建立 System.Web.Http.Controllers.IHttpController 物件。 |
09 | /// <param name="request">訊息要求。</param> |
10 | /// <param name="controllerDescriptor">HTTP 控制器描述元。</param> |
11 | /// <param name="controllerType">控制器的型別。</param> |
12 | /// <returns>IHttpController 物件</returns> |
13 | public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) |
15 | HttpConfiguration controllerConfig; |
19 | if (_cache.TryGetValue(controllerType, out controllerConfig)) |
21 | controllerDescriptor.Configuration = controllerConfig; |
23 | else if (ControllerConfig.Map.ContainsKey(controllerType)) |
26 | controllerDescriptor.Configuration = controllerDescriptor.Configuration.Copy(ControllerConfig.Map[controllerType]); |
29 | _cache.TryAdd(controllerType, controllerDescriptor.Configuration); |
33 | var result = Default.Create(request, controllerDescriptor, controllerType); |
四、WebApiConfig進行動態組態
02 | config.Services.Replace( typeof (IHttpControllerActivator), new PerControllerConfigActivator()); |
05 | ControllerConfig.Map.Add( typeof (TodoItems2Controller), settings => |
07 | settings.Formatters.Clear(); |
08 | var jsonformatter = new JsonMediaTypeFormatter |
10 | SerializerSettings = { ContractResolver = new CamelCasePropertyNamesContractResolver() } |
12 | settings.Formatters.Add(jsonformatter); |
15 | ControllerConfig.Map.Add( typeof (TodoItemsController), settings => |
17 | settings.Formatters.Clear(); |
18 | settings.Formatters.Add( new XmlMediaTypeFormatter()); |
註解我都寫在程式碼之中了。注意,態動進行Controller層級組態與實作IControllerConfiguration介面的屬性設置方式無法併存,原因也很簡單,因為我們替換了自行實作的IHttpControllerActivator,它並不懂的如何解讀實作IControllerConfiguration介面的屬性。
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。