asp.net web api 构建api帮助文档
2021-04-26 06:25
标签:ppa rect pat cto fun exception ams mst gis 1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架。 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目引入了MVC框架开发包,使得项目看起来杂乱。 2)自带的Help Pages框架无法针对Odata控制器生成API文档。 3 问题解决方案 1)独立Help Pages项目,以插件形式添加服务 步骤1,添加类ServiceAssembliesResolver,获得服务集 步骤2,替换现有服务 在WebApiConfig.Register方法中添加代码 完整代码如下: 步骤3,添加MultiXmlDocumentationProvider类,读取多个XML文档 步骤4,使用MultiXmlDocumentationProvider 将config.SetDocumentationProvider(new MultiXmlDocumentationProvider(WebConfigSetting.ServicesLocation));添加到Register方法中 步骤5,创建服务插件文件夹,将服务插件及其XML文档放在文件夹中。 2)重构ApiExplorer,获得Odata控制器的API文档 步骤1,重构ApiExplorer 添加RouteValueKeys类 添加OdataRelativePath类 步骤2;根据OData路由拼出api的URI 使用OdataRelativePath.GetOdataRelativePath方法修改ApiExplorer.ApiDescriptions中的URI 注意:配置Odata路由时,将路由名称配置为控制器名称(不含Controller字符串),并且编写服务程序时,遵循一个实体对应一个控制器,对应一个Odata路由。 ----------------------------------------------------------------------------------------- 转载与引用请注明出处。 时间仓促,水平有限,如有不当之处,欢迎指正。 asp.net web api 构建api帮助文档 标签:ppa rect pat cto fun exception ams mst gis 原文地址:http://www.cnblogs.com/hdwgxz/p/7898983.html ///
config.Services.Replace(typeof(IAssembliesResolver), new ServiceAssembliesResolver());
namespace HY_WebApi.HelpPages
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
config.Services.Replace(typeof(IAssembliesResolver), new ServiceAssembliesResolver());
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//OData路由,将路由名称设置为控制器(去掉Controller)名称,以便生成Api帮助文档
config.MapODataServiceRoute(
routeName: "ODataSearch",
routePrefix: "odata",
model: GetEdmModel(),
batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet
///
}public class CustomApiExplorer : ApiExplorer
{
private HttpConfiguration configuration;
public CustomApiExplorer(HttpConfiguration configuration)
: base(configuration)
{
this.configuration = configuration;
}
public override bool ShouldExploreController(string controllerVariableValue, HttpControllerDescriptor controllerDescriptor, IHttpRoute route)
{
if (controllerDescriptor == null)
{
throw new ArgumentNullException("controllerDescriptor");
}
if (route == null)
{
throw new ArgumentNullException("route");
}
var c = controllerDescriptor.ControllerName;
//获得OData路由
IEdmModel edm = EdmModelCreater.GetEdmModel();
Liststring> collectionFromEdms = new Liststring>();
foreach (var item in edm.EntityContainer.Elements)
{
collectionFromEdms.Add(item.Name);
}
//如果是Odata控制器,那么忽略ApiExplorerSettingsAttribute
ApiExplorerSettingsAttribute setting = controllerDescriptor.GetCustomAttributes().FirstOrDefault();
bool isOdataController = collectionFromEdms.Contains(controllerDescriptor.ControllerName);
bool isBaseApi = controllerDescriptor.ControllerName != "BaseApi";
return isBaseApi||isOdataController ||
((setting == null || !setting.IgnoreApi) && MatchRegexConstraint(route, RouteValueKeys.Controller, controllerVariableValue));
}
public override bool ShouldExploreAction(string actionVariableValue, HttpActionDescriptor actionDescriptor, IHttpRoute route)
{
if (actionDescriptor == null)
{
throw new ArgumentNullException("actionDescriptor");
}
if (route == null)
{
throw new ArgumentNullException("route");
}
//获得OData路由
IEdmModel edm = EdmModelCreater.GetEdmModel();
Liststring> collectionFromEdms = new Liststring>();
foreach (var item in edm.EntityContainer.Elements)
{
collectionFromEdms.Add(item.Name);
}
//如果是Odata控制器,那么忽略ApiExplorerSettingsAttribute
ApiExplorerSettingsAttribute setting = actionDescriptor.ControllerDescriptor.GetCustomAttributes().FirstOrDefault();
bool isOdataController = collectionFromEdms.Contains(actionDescriptor.ControllerDescriptor.ControllerName);
bool isBaseApi = actionDescriptor.ControllerDescriptor.ControllerName != "BaseApi";
return isBaseApi||isOdataController ||
((setting == null || !setting.IgnoreApi) && MatchRegexConstraint(route, RouteValueKeys.Action, actionVariableValue));
}
private static bool MatchRegexConstraint(IHttpRoute route, string parameterName, string parameterValue)
{
IDictionarystring, object> constraints = route.Constraints;
if (constraints != null)
{
object constraint;
if (constraints.TryGetValue(parameterName, out constraint))
{
// treat the constraint as a string which represents a Regex.
// note that we don‘t support custom constraint (IHttpRouteConstraint) because it might rely on the request and some runtime states
string constraintsRule = constraint as string;
if (constraintsRule != null)
{
string constraintsRegEx = "^(" + constraintsRule + ")$";
return parameterValue != null && Regex.IsMatch(parameterValue, constraintsRegEx, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
}
}
}
return true;
}
}
internal static class RouteValueKeys
{
// Used to provide the action and controller name
public const string Action = "action";
public const string Controller = "controller";
}
public static class OdataRelativePath
{
public static void GetOdataRelativePath(CustomApiExplorer customApiExplorer, HttpConfiguration configuration)
{
IEdmModel edm = EdmModelCreater.GetEdmModel();
Liststring> collectionFromEdms = new Liststring>();
foreach(var item in edm.EntityContainer.Elements)
{
collectionFromEdms.Add(item.Name);
}
Collection apiColloction = customApiExplorer.ApiDescriptions;
foreach (ApiDescription api in apiColloction)
{
string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName;
//去掉Odata中控制器的版本号
var controllerSelector = configuration.Services.GetService(typeof(IHttpControllerSelector)) as VersionControllerSelector;
string oldString = controllerSelector.RouteVersionSuffixMapping.First(m => m.Key.Contains("OdataRouteVersioning")).Value;
controllerName = controllerName.Replace(oldString, "");
if (collectionFromEdms.Contains(controllerName))
{
string actionName = api.ActionDescriptor.ActionName;
var parameters = api.ActionDescriptor.GetParameters();
string paramStr = null;
foreach (var parameter in parameters)
{
var t = parameter.ParameterType;
if (parameter.ParameterType.IsClass)
{
continue;
}
if (paramStr != null)
{
paramStr = string.Format("{0}&({1}={1})", paramStr, parameter.ParameterName);
}
else
{
paramStr = string.Format("({0}={0})", parameter.ParameterName);
}
}
api.RelativePath = string.Format("{0}/{1}/{2}/Service.{3}{4}", "odata", "{Version}", controllerName, actionName, paramStr);
}
else
{
Regex reg=new Regex("[0-9]");
Match match = reg.Match(api.RelativePath);
if(match.Success)
{
api.RelativePath = api.RelativePath.Replace(string.Format("V{0}",match.Value),"");
}
}
}
}
}
例如在控制器中 public ActionResult Index()
{
ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
CustomApiExplorer customApiExplorer = new CustomApiExplorer(Configuration);
OdataRelativePath.GetOdataRelativePath(customApiExplorer,Configuration);
Collection apiDescriptions = new Collection();
List list = new List();
foreach (ApiDescription ad in customApiExplorer.ApiDescriptions)
{
if (ad.ActionDescriptor.ControllerDescriptor.ControllerName != "Metadata" && ad.ActionDescriptor.ActionName != "ToJson")
{
list.Add(ad);
}
}
list = list.OrderBy(m => m.ActionDescriptor.ControllerDescriptor.ControllerName).ToList();
list.ForEach(m =>
{
apiDescriptions.Add(m);
});
return View(apiDescriptions);
}
下一篇:详解C#中的反射
文章标题:asp.net web api 构建api帮助文档
文章链接:http://soscw.com/index.php/essay/79689.html