Как зарегистрировать контроллер api из библиотеки с настройкой - PullRequest
4 голосов
/ 20 марта 2019

Я создал небольшой API в библиотеке классов.Этот API будет использоваться другими сайтами.Думайте об этом как о стандартной конечной точке, которую будут содержать все наши веб-сайты.

[Route("api/[controller]")]
[ApiController]
public class CustomController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

Выше приведено в библиотеке классов.Теперь я хотел бы добавить это к проектам простым способом.

app.UseCustomAPI("/api/crap");

Я не совсем уверен, как мне следует обрабатывать маршрутизацию к контроллерам 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);
    }

После того, как я это сделалначинаю думать, что я, возможно, подошел к этому неправильным образом и на самом деле должен пытаться как-то добавить его непосредственно в таблицы маршрутизации.При этом мне бы хотелось, чтобы они могли настроить конечную точку, с которой пользовательский контроллер читает.

Обновление

Следующее работает. Загрузка и регистрация контроллеров API из библиотеки классов в ядре ASP.NET

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddApplicationPart(Assembly.Load(new AssemblyName("WebAPI"))); 

Однако я действительно ищу решение типа middlewere, чтобы пользователи могли просто добавить его, и я могу настроитьнастройки по умолчанию или они могут изменить некоторые настройки.Приведенный выше пример не позволяет изменять настройки.

 app.UseCustomAPI("/api/crap");

Обновление из комментария без сборки

Если я не добавлю .AddApplicationPart(Assembly.Load(new AssemblyName("WebAPI")));

Эта страница локального хоста не найдена. Веб-страница не была найдена для веб-адреса: https://localhost:44368/api/Custom

1 Ответ

4 голосов
/ 20 марта 2019

Чтобы настроить маршрутизацию для контроллера во время выполнения, вы можете использовать Application Model Convention .На простейшем уровне это может быть достигнуто с помощью пользовательской реализации 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;
    }
}

Этот пример просто заменяет существующий шаблон (api/[controller]) тем, что предусмотрено вSampleConvention конструктор.Следующим шагом является регистрация этого нового соглашения, что можно сделать с помощью вызова AddMvc.Вот пример того, как это будет работать:

services.AddMvc(o =>
{
    o.Conventions.Add(new CustomControllerConvention("api/whatever"));
});

Это все, что нужно, чтобы все заработало здесь, но, поскольку вы предлагаете это из другой сборки, я бы предложил подход, основанный на методе расширения.Вот пример этого:

public static class MvcBuilderExtensions
{
    public static IMvcBuilder SetCustomControllerRoute(this IMvcBuilder mvcBuilder, string newEndpoint)
    {
        return mvcBuilder.AddMvcOptions(o =>
        {
            o.Conventions.Add(new CustomControllerConvention(newEndpoint));
        });
    }
}

Вот пример того, как это будет выглядеть:

services.AddMvc()
    .SetCustomControllerRoute("api/whatever");

Весь этот подход означает, что без вызова SetCustomControllerRoute, api/Custom будетпо-прежнему будет использоваться по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...