如何生成动态路径,在运行时生成的swagger中重写可能的参数值?

时间:2018-05-31 08:08:57

标签: asp.net-web-api asp.net-core swagger swashbuckle

我有一个带有url模板的Web Api:'TestEmail / Render / {templateName}',其中templateName参数的可能值是在运行时使用反射确定的。

public class TestEmailController : Controller
{
    public static IEnumerable<Type> AllNotificationTypes =>
       typeof(INotification).Assembly.GetTypes()
           .Where(t => typeof(INotification).IsAssignableFrom(t) && !t.IsAbstract);

    [HttpGet("[controller]/{templateName}")]
    public async Task<IActionResult> Render(string templateName)
    {
        Type templateType = AllNotificationTypes.FirstOrDefault(t => t.Name == templateName);
        if (templateType == null) return NotFound();
        string renderedHtml = ...
        return Content(renderedHtml, "text/html");
    }   
}

如何使用Swashbuckle.AspNetCore反映swagger文件中的可能值?

编辑:受到HelperSepu答案的启发,我最终得到了:

[SwaggerOperationFilter(typeof(TemplateNameOperationFilter))]
[HttpGet("[controller]/{templateName}")]
public async Task<IActionResult> Render(string templateName)
{ 
....


public class TemplateNameOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        var param = (PartialSchema)operation.Parameters.First(o => o.Name == "templateName");
        param.Enum = TestEmailController.AllNotificationTypes.Select(type => (object)type.Name).ToList();
    }
}

1 个答案:

答案 0 :(得分:0)

我正在考虑这个,一个不错的选择是使用IDocumentFilter将其作为枚举

public class MyDocFilter : IDocumentFilter
{
  public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
  {
    PathItem path = swaggerDoc.Paths.Where(x => x.Key.Contains("TestEmail")).First().Value;
    var p = (NonBodyParameter)path.Get.Parameters.Where(x => x.Name == "templateName").First();
    p.Enum = new List<object>();
    foreach (var item in TestEmailController.AllNotificationTypes.Select(x => x.Name))
    {
      p.Enum.Add(item);
    }
  }
}

这将更改用户界面以显示下拉列表: enter image description here