我所做的是在类库中创建了一个小的 API。此 API 将被其他站点使用。将其视为我们所有网站都将包含的标准端点。
[Route("api/[controller]")]
[ApiController]
public class CustomController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
}
Run Code Online (Sandbox Code Playgroud)
以上是在一个类库中。现在我想做的是能够以简单的方式将其添加到项目中。
app.UseCustomAPI("/api/crap");
Run Code Online (Sandbox Code Playgroud)
我不确定我应该如何处理到库中 api 控制器的路由。我创建了一个 CustomAPIMiddleware,它能够捕捉到我称之为“/api/crap”的东西,但是我不确定我应该如何将请求转发到库中的 CustomController
public async Task Invoke(HttpContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
PathString matched;
PathString remaining;
if (context.Request.Path.StartsWithSegments(_options.PathMatch, out matched, out remaining))
{
PathString path = context.Request.Path;
PathString pathBase = context.Request.PathBase;
context.Request.PathBase = pathBase.Add(matched);
context.Request.Path = remaining;
try
{
await this._options.Branch(context);
}
finally
{
context.Request.PathBase = pathBase;
context.Request.Path = path;
}
path = new PathString();
pathBase = new PathString();
}
else
await this._next(context);
}
Run Code Online (Sandbox Code Playgroud)
完成之后,我开始认为我可能以错误的方式处理了这个问题,实际上应该尝试以某种方式将其直接添加到路由表中。话虽如此,如果他们可以自定义自定义控制器从中读取的端点,我会喜欢它。
更新
以下确实有效。 从 ASP.NET 核心中的类库加载和注册 API 控制器
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddApplicationPart(Assembly.Load(new AssemblyName("WebAPI")));
Run Code Online (Sandbox Code Playgroud)
然而,我真的在寻找一种中间类型的解决方案,以便用户可以简单地添加它,我可以配置默认设置,或者他们可以更改一些设置。上面的示例不允许更改设置。
app.UseCustomAPI("/api/crap");
Run Code Online (Sandbox Code Playgroud)
从没有程序集的评论更新
如果我不添加 .AddApplicationPart(Assembly.Load(new AssemblyName("WebAPI")));
无法找到此本地主机页面未找到该网址的网页: https://localhost:44368/api/Custom
为了在运行时自定义控制器的路由,您可以使用应用程序模型约定。在最简单的层面上,这可以通过自定义实现来实现IControllerModelConvention:
public class CustomControllerConvention : IControllerModelConvention
{
private readonly string newEndpoint;
public CustomControllerConvention(string newEndpoint)
{
this.newEndpoint = newEndpoint;
}
public void Apply(ControllerModel controllerModel)
{
if (controllerModel.ControllerType.AsType() != typeof(CustomController))
return;
foreach (var selectorModel in controllerModel.Selectors)
selectorModel.AttributeRouteModel.Template = newEndpoint;
}
}
Run Code Online (Sandbox Code Playgroud)
此示例只是将现有模板 ( api/[controller])替换为SampleConvention构造函数中提供的任何内容。下一步是注册这个新约定,这可以通过调用AddMvc. 这是一个如何工作的示例:
services.AddMvc(o =>
{
o.Conventions.Add(new CustomControllerConvention("api/whatever"));
});
Run Code Online (Sandbox Code Playgroud)
这就是让事情在这里工作所需的全部,但是当您从另一个程序集提供它时,我建议使用基于扩展方法的方法。这是一个例子:
public static class MvcBuilderExtensions
{
public static IMvcBuilder SetCustomControllerRoute(this IMvcBuilder mvcBuilder, string newEndpoint)
{
return mvcBuilder.AddMvcOptions(o =>
{
o.Conventions.Add(new CustomControllerConvention(newEndpoint));
});
}
}
Run Code Online (Sandbox Code Playgroud)
下面是一个示例:
services.AddMvc()
.SetCustomControllerRoute("api/whatever");
Run Code Online (Sandbox Code Playgroud)
这整个方法意味着如果不调用SetCustomControllerRoute,api/Custom仍将用作默认值。
| 归档时间: |
|
| 查看次数: |
487 次 |
| 最近记录: |