9

Web APIがあり、ドキュメントを自動生成するためにweb api help pagesを追加しました。それは私のパラメータがリストアップされている方法のための偉大な作業だが、私はこのような方法があります:Web APIのヘルプページ - プロパティのドキュメントのカスタマイズ

public SessionResult PostLogin(CreateSessionCommand request) 

そして、私のヘルプページに、それが唯一のプロパティ]セクションにコマンドパラメータを一覧表示されます。ただし、サンプルリクエストセクションには、私のCreateSessionCommandクラスのすべてのプロパティがリストアップされています。

パラメータ

名前|説明|追加情報

リクエスト|ドキュメントはありません。 |要求本体にこのパラメーターを定義します。

代わりに、CreateSessionCommandクラスのすべてのプロパティをリストしたいと思います。これを行う簡単な方法はありますか?

答えて

6

これは@Joshの回答に追加する必要があります。あなたはモデルクラスからプロパティを一覧表示するだけでなく、したい場合は、だけでなく、各プロパティのドキュメントが含まれ、以下のように、エリア/ HelpPage/XmlDocumentationProvider.csファイルを変更する必要があります。

public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor) 
{ 
    ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor; 
    if (reflectedParameterDescriptor != null) 
    { 
     if (reflectedParameterDescriptor.ParameterInfo is CustomParameterInfo) 
     { 
      const string PropertyExpression = "/doc/members/member[@name='P:{0}']"; 
      var pi = (CustomParameterInfo) reflectedParameterDescriptor.ParameterInfo; 

      string selectExpression = String.Format(CultureInfo.InvariantCulture, PropertyExpression, pi.Prop.DeclaringType.FullName + "." + pi.Prop.Name); 
      XPathNavigator methodNode = _documentNavigator.SelectSingleNode(selectExpression); 
      if (methodNode != null) 
      { 
       return methodNode.Value.Trim(); 
      } 
     } 
     else 
     { 
      XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor); 
      if (methodNode != null) 
      { 
       string parameterName = reflectedParameterDescriptor.ParameterInfo.Name; 
       XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName)); 
       if (parameterNode != null) 
       { 
        return parameterNode.Value.Trim(); 
       } 
      }      
     } 
    } 

    return null; 
} 

CustomParameterInfoクラスべきプロパティ情報も保持してください。

internal class CustomParameterInfo : ParameterInfo 
{ 
    public PropertyInfo Prop { get; private set; } 

    public CustomParameterInfo(PropertyInfo prop) 
    { 
     Prop = prop; 
     base.NameImpl = prop.Name; 
    } 
} 
+1

私は十分にあなたに感謝することはできません、これは本当に私に役立った! – Haney

7

だから、誰か興味がある場合に備えて、この問題の回避策を考案することができました。 HelpPageConfigurationExtensions.csで

私は、次の拡張メソッドを追加:

public static void AlterApiDescription(this ApiDescription apiDescription, HttpConfiguration config) 
{ 
    var docProvider = config.Services.GetDocumentationProvider(); 
    var addParams = new List<ApiParameterDescription>(); 
    var removeParams = new List<ApiParameterDescription>(); 

    foreach (var param in apiDescription.ParameterDescriptions) 
    { 
     var type = param.ParameterDescriptor.ParameterType; 

     //string is some special case that is not a primitive type 
     //also, compare by full name because the type returned does not seem to match the types generated by typeof 
     bool isPrimitive = type.IsPrimitive || String.Compare(type.FullName, typeof(string).FullName) == 0; 

     if (!isPrimitive) 
     { 
      var properties = from p in param.ParameterDescriptor.ParameterType.GetProperties() 
           let s = p.SetMethod 
           where s.IsPublic 
           select p; 

      foreach (var property in properties) 
      { 
       var documentation = docProvider.GetDocumentation(new System.Web.Http.Controllers.ReflectedHttpParameterDescriptor() 
       { 
        ActionDescriptor = param.ParameterDescriptor.ActionDescriptor, 
        ParameterInfo = new CustomParameterInfo(property) 
       }); 

       addParams.Add(new ApiParameterDescription() 
       { 
        Documentation = documentation, 
        Name = property.Name, 
        Source = ApiParameterSource.FromBody, 
        ParameterDescriptor = param.ParameterDescriptor 
       }); 
      } 

      //since this is a complex type, select it to be removed from the api description 
      removeParams.Add(param); 
     } 
    } 

    //add in our new items 
    foreach (var item in addParams) 
    { 
     apiDescription.ParameterDescriptions.Add(item); 
    } 

    //remove the complex types 
    foreach (var item in removeParams) 
    { 
     apiDescription.ParameterDescriptions.Remove(item); 
    } 
} 

そして、ここに私が次に

internal class CustomParameterInfo : ParameterInfo 
{ 
    public CustomParameterInfo(PropertyInfo prop) 
    { 
     base.NameImpl = prop.Name; 
    } 
} 

を使用するパラメータ情報インスタンス化クラスで、我々は内部の別の方法で拡張を呼び出します拡張クラス

public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string apiDescriptionId) 
{ 
    object model; 
    string modelId = ApiModelPrefix + apiDescriptionId; 
    if (!config.Properties.TryGetValue(modelId, out model)) 
    { 
     Collection<ApiDescription> apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions; 
     ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(), apiDescriptionId, StringComparison.OrdinalIgnoreCase)); 
     if (apiDescription != null) 
     { 
      apiDescription.AlterApiDescription(config); 

      HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator(); 
      model = GenerateApiModel(apiDescription, sampleGenerator); 
      config.Properties.TryAdd(modelId, model); 
     } 
    } 

    return (HelpPageApiModel)model; 
} 

クラスオブジェクトのプロパティではなくコントローラメソッドに追加する必要があります。これは、私のオブジェクトが外部ライブラリの一部であるためかもしれません。

+0

私は十分にあなたに感謝することはできません、これは本当に私に役立った! – Haney

関連する問題