ASP.NET WebAPI 12 Actionの実行

4007 ワード

Actionのアクティブ化は、Actionがメソッドの呼び出しに対応し、結果の交渉を実行する2つのステップに大きく分けることができます.WebAPIでは、HttpActionInvoker(System.Web.Http.Controllers)によってActionの実行が行われる.
 
public interface IHttpActionInvoker

 { 

Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken); 

 }

 
  
 
HttpActionInvokerも「標準化コンポーネント」であり、WebAPIのデフォルト実装は、ApiControllerActionInvoker(System.Web.Http.Controllers,ApiControllerActionInvokerの実装におけるActionメソッドの呼び出しは、実際にはHttpActionDescriptorのExecuteAsyncのメソッドによって実行され、コンテンツ交渉はContentNegotiatorによって処理される.
 

アクションの実行


ActionExecutor


ReflectedHttpActionDescriptor ExecuteAsyncメソッド実装でActionの実行をその内部クラスActionExecutorに渡す
 
 
public class ReflectedHttpActionDescriptor : HttpActionDescriptor

 {

public abstract Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken); 

 }

 
  
 
ReflectedHttpActionDescriptorでは、アクションの実行を内部クラスActionExecutorに渡します.
 
public override Task<object> ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments, CancellationToken cancellationToken) 

 { 

if (controllerContext == null) 

 { 

throw Error.ArgumentNull("controllerContext"); 

 } 

 

if (arguments == null) 

 { 

throw Error.ArgumentNull("arguments"); 

 } 

 

if (cancellationToken.IsCancellationRequested) 

 { 

return TaskHelpers.Canceled<object>(); 

 } 

 

try

 { 

object[] argumentValues = PrepareParameters(arguments, controllerContext); 

return _actionExecutor.Value.Execute(controllerContext.Controller, argumentValues); 

 } 

catch (Exception e) 

 { 

return TaskHelpers.FromError<object>(e); 

 } 

 }

 
  
 
 
ActionExecutorはActionの実行に対してツリーを表す方式を採用しています.この後、Action実行のdemoを書きます.
 

コンテンツ交渉(結果のシーケンス化)


先のパラメータバインドでは、パラメータの逆シーケンス化は、要求ヘッダ情報のContent-Typeに基づいて異なるシーケンス化オブジェクトを取得するものであり、結果をシーケンス化する過程でも同様であるが、取得したヘッダ情報はAcceptである.
 
Actionに対する戻り結果は,void,,object,ActionResult,HttpResponseMessageの場合が多い.HttpResponseMessageは、HttpMessageHandler全体の戻り値がHttpResponseMessageであるため、そのまま戻ることができる.IActionResultの場合、それ自体はExecuteAsyncメソッド(結果を返す)でHttpResponseMessageを返すことができます.異なるActionResultは不要なシーケンス化戦略を用いる.JsonResultは、結果を直接Json形式でシーケンス化します.OkNegotiatedContentResultタイプでは、JsonResultのように明確なシーケンス化方式がないため、この場合はクライアント要求に従ってシーケンス化を取得する.この方式はobjectとvoidタイプの戻り値にも同様に適用できるが,この具体的な実装はHttpResponseMessageの拡張法CreateResponseによって行われる.
 
ContentNegotiator
IContentNegotiator(System.Net.Http.Formatting)は、WebAPIにおいても「標準化されたコンポーネント」であり、デフォルトではDefaultContentNegotiator(System.Net.Http.Formatting)として実装されている.
 
 
public interface IContentNegotiator

 { 

ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters); 

 }

 
  
 
IContentNegotiatorには、MedioType情報と取得したシーケンス化オブジェクトを含むNegotiatorメソッドが1つしかありません.
 
public class ContentNegotiationResult

 { 

public MediaTypeFormatter Formatter { get; set; } 

public MediaTypeHeaderValue MediaType { get; set; } 

 }

 
  
 
 
Demoでは、コンテンツ交渉の具体的な処理ロジックを示すためにMyContentNegotiationResultをカスタマイズしました.
 
 
 

ソースコード


 
Github: https://github.com/BarlowDu/WebAPI (API_12)