c# - ASP.NET Web API Generate all parameters from model - help pages -


i'm busy creating web api (inside asp mvc4 application). using library suggested on asp.net site generating documentation (http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages).

my problem if parameter model, can't specify properties model contains in generated pages.

here example:

model:

public class testmodel {     property string firstname {get;set;}     property string surname {get; set;}     property boolean active {get;set;}  } 

action:

/// <summary> /// test action /// </summary> /// <param name="model">this model</param> <-- works /// <param name="firstname">this first name </param>  <-- doesn't work /// <param name ="model.surname">this surname</param> <-- doesn't work public httpresponsemessage post(my.namespace.models.testmodel model) {   ... } 

only parameter model gets generated.

i took @ xml document gets generated documentation , add other parameters.

<member name="my.namespace.api.post(my.namespace.models.testmodel)">      <summary>          test action      </summary>      <param name="model>this model</param>      <param name="firstname">this first name </param>      <param name="model.surname">this surname</param> </member> 

but on pages generates parameter model.

i have traced down method gets parameters xml.

collection<apidescription> apidescriptions = config.services.getapiexplorer().apidescriptions; 

this located in helppageconfigurationextentions.cs auto generated.

am approaching wrong way? know of work around?

any suggestions or solutions appreciated.

the mvc web api documentation feature walks through api classes , methods using reflection. build structure of documentation result in more or less empty (and useless) documentation unless have added documentation comments.

the body of documentation filled using xml file generated using /// documentation comments has specific structure must followed. means can't fill xml whatever want display, has connected in api , must follow structure of classes , properties.

so in case can't put model property documentation in api method. have put model property exists.

model:

  public class testmodel   {   /// <summary>this first name </summary>       property string firstname {get;set;}   /// <summary>this surname</summary>       property string surname {get; set;}       property boolean active {get;set;}    } 

action:

  /// <summary>   /// test action   /// </summary>   /// <param name="model">this model</param>    public httpresponsemessage post(my.namespace.models.testmodel model)   {     ...   } 

modify pages

the default pages automatically generated not include model documentation api methods documented. in order display more information parameters in api customisation required. instruction follow 1 way add parameter documentation.

create 2 new types in areas/helppage/models

public class typedocumentation {     public typedocumentation()     {         propertydocumentation = new collection<propertydocumentation>();     }      public string summary { get; set; }     public icollection<propertydocumentation> propertydocumentation { get; set; }  }  public class propertydocumentation {     public propertydocumentation(string name, string type, string docs)     {         name = name;         type = type;         documentation = docs;     }     public string name { get; set; }     public string type { get; set; }     public string documentation { get; set; } } 

add new property helppageapimodel.cs

public idictionary<string, typedocumentation> parametermodels{ get; set; }  

create new interface

internal interface imodeldocumentationprovider {     idictionary<string, typedocumentation> getmodeldocumentation(httpactiondescriptor actiondescriptor); } 

modify xmldocumentationprovider implement new interface

public class xmldocumentationprovider : idocumentationprovider, imodeldocumentationprovider {     private const string typeexpression = "/doc/members/member[@name='t:{0}']";     private const string propertyexpression = "/doc/members/member[@name='p:{0}']"; ///... ///... existing code ///...      private static string getpropertyname(propertyinfo property)     {         string name = string.format(cultureinfo.invariantculture, "{0}.{1}", property.declaringtype.fullname, property.name);         return name;     }      public idictionary<string, typedocumentation> getmodeldocumentation(httpactiondescriptor actiondescriptor)     {         var retdictionary = new dictionary<string, typedocumentation>();         reflectedhttpactiondescriptor reflectedactiondescriptor = actiondescriptor reflectedhttpactiondescriptor;         if (reflectedactiondescriptor != null)         {             foreach (var parameterdescriptor in reflectedactiondescriptor.getparameters())             {                 if (!parameterdescriptor.parametertype.isvaluetype)                 {                     typedocumentation typedocs = new typedocumentation();                       string selectexpression = string.format(cultureinfo.invariantculture, typeexpression, gettypename(parameterdescriptor.parametertype));                     var typenode = _documentnavigator.selectsinglenode(selectexpression);                      if (typenode != null)                     {                         xpathnavigator summarynode;                         summarynode = typenode.selectsinglenode("summary");                         if (summarynode != null)                             typedocs.summary = summarynode.value;                     }                      foreach (var prop in parameterdescriptor.parametertype.getproperties())                     {                         string propname = prop.name;                         string propdocs = string.empty;                         string propexpression = string.format(cultureinfo.invariantculture, propertyexpression, getpropertyname(prop));                         var propnode = _documentnavigator.selectsinglenode(propexpression);                         if (propnode != null)                         {                             xpathnavigator summarynode;                             summarynode = propnode.selectsinglenode("summary");                             if (summarynode != null) propdocs = summarynode.value;                         }                         typedocs.propertydocumentation.add(new propertydocumentation(propname, prop.propertytype.name, propdocs));                      }                     retdictionary.add(parameterdescriptor.parametername, typedocs);                 }              }          }          return retdictionary;     } } 

add code helppageconfigurationextension in generateapimodel method

imodeldocumentationprovider modelprovider =             config.services.getdocumentationprovider() imodeldocumentationprovider; if (modelprovider != null) {     apimodel.parametermodels = modelprovider.getmodeldocumentation(apidescription.actiondescriptor); } 

modify helppageapimodel.cshtml adding following want model documentation displayed.

bool hasmodels = model.parametermodels.count > 0; if (hasmodels) {      <h2>parameter information</h2>   @html.displayfor(apimodel => apimodel.parametermodels, "models")  } 

add models.cshtml displaytemplates

@using system.web.http @using system.web.http.description @using mvcapplication2.areas.helppage.models @model idictionary<string, typedocumentation>  @foreach (var modeltype in model) {     <h3>@modeltype.key</h3>     if (modeltype.value.summary != null)     {     <p>@modeltype.value.summary</p>     }     <table class="help-page-table">         <thead>             <tr>                 <th>property</th>                  <th>description</th>             </tr>         </thead>         <tbody>             @foreach (var propinfo in modeltype.value.propertydocumentation)             {                 <tr>                     <td class="parameter-name"><b>@propinfo.name</b> (@propinfo.type)</td>                      <td class="parameter-documentation">                         <pre>@propinfo.documentation</pre>                     </td>                 </tr>             }         </tbody>     </table> } 

Comments

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -