Универсальный строковый маршрутизатор с БД в Asp.net Core - PullRequest
0 голосов
/ 10 ноября 2018

Я создаю интернет-магазин. И я хочу добавить короткие URL-адреса для продуктов, категорий и так далее. Например:

store.com / iphone-7-плюс

Эта ссылка должна открыть страницу с продуктом iPhone 7 plus.

Логика:

  1. Сервер получает URL
  2. Сервер попробует против существующих маршрутов
  3. Если для этого пути нет никакого маршрута - сервер просматривает БД и пытается найти товар или категорию с таким названием .

Очевидные решения и почему они не применимы:

Первое решение - это новый маршрут:

public class StringRouter : IRouter
{
    private readonly IRouter _defaultRouter;

    public StringRouter(IRouter defaultRouter)
    {
        _defaultRouter = defaultRouter;
    }

    public async Task RouteAsync(RouteContext context)
    {
        // special loggic

        await _defaultRouter.RouteAsync(context);
    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        return _defaultRouter.GetVirtualPath(context);
    }
}

Проблема в том, что я не могу предоставить доступ к моей БД с StringRouter.

Второе решение:

public class MasterController : Controller
{
    [Route("{path}")]
    public IActionResult Map(string path)
    {
        // some logic
    }
}

Проблема в том, что сервер получает буквально все вызовы типа store.com/robots.txt

Так что вопрос все еще открыт - не могли бы вы посоветовать мне какое-нибудь подходящее решение?

1 Ответ

0 голосов
/ 13 ноября 2018

Для доступа к DbContext вы можете попробовать:

     using Microsoft.Extensions.DependencyInjection;

    public async Task RouteAsync(RouteContext context)
    {           
        var dbContext = context.HttpContext.RequestServices.GetRequiredService<RouterProContext>();
        var products = dbContext.Product.ToList();
        await _defaultRouter.RouteAsync(context);
    }

Вы также можете попробовать Middleware, чтобы проверить, не существует ли запрос, а затем вернуть ожидаемый ответ.

            public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
        {                
            app.Use(async (context,next) => {

                await next.Invoke();
                // add your own business logic to check this if statement
                if (context.Response.StatusCode == 404)
                {
                        var db = context.RequestServices.GetRequiredService<RouterProContext>();
                        var users = db.Users.ToList();
                        await context.Response.WriteAsync("Request From Middleware");
                }
            });
            //your rest code
        }
...