Почему LinkGenerator всегда возвращает null?

#asp.net-mvc #asp.net-core #razor-pages

#asp.net-mvc #asp.net-core #razor-страницы

Вопрос:

Я написал класс для генерации ссылок для других классов (Aspnet core 3.1), которые отправляют электронные письма со ссылками в них, которые получают экземпляр LinkGenerator через DI.

Всякий раз, когда я вызываю какой-либо метод в экземпляре LinkGenerator , он возвращает null . Я делаю что-то не так?

  public interface IPageLinkGenerator
    {
        string LinkFor(string page, object values);
    }

    public class PageLinkGenerator : IPageLinkGenerator
    {
        private readonly IHttpContextAccessor _accessor;
        private readonly LinkGenerator _generator;

        public PageLinkGenerator(IHttpContextAccessor accessor, LinkGenerator generator)
        {
            _accessor = accessor;
            _generator = generator;
        }

        public string LinkFor(string page, object values)
        {
            var context = _accessor.HttpContext;

            var callBackLink = _generator.GetUriByPage(
                context,
                page: page,
                handler: null,
                values: values,
                scheme: context.Request.Scheme,
                host: context.Request.Host
                );

            return callBackLink;
        }
    }
  

Это мой метод ConfigureServices из Startup.cs

 public void ConfigureContainer(ServiceRegistry services)
        {
            services.Scan(_ =>
            {
                _.AssemblyContainingType<IDbConnectionFactory>();
                _.WithDefaultConventions();
                _.ConnectImplementationsToTypesClosing(typeof(IHandle<>));
            });

            services.For<IConfiguration>().Use(Configuration);
            services.For<IStorageClient>().Use<AzureBlobClient>();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton<IDomainEventDispatcher, DomainEventDispatcher>();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>));
            services.AddScoped(typeof(IValidationRepository<>), typeof(ValidationRepository<>));
            
            services.AddCustomisedDbContext(Configuration);
            services.AddHtmlTags(new TagConventions());
            services.AddMediatR(typeof(Startup));

            services.For<IRazorLightEngine>()
                .Use(RazorLightEngineFactory.Get())
                .Singleton();

            services.AddTestConfigurationInstance(_environment, Configuration);
            services.AddEmailSender(_environment);

            services.AddProxyHttpClient();

            services.AddCustomisedIdentity(_environment, Configuration);

            services.AddAuthorizationPolicies(Configuration);

            services.AddCustomisedRazorPages();

            services.AddWkhtmltopdf();

            services.AddLocalization();
            
            services.AddRouting();
        }
  

Это метод, который вызывает класс:

 public async Task Handle(BookingAdminMessageCreated @event, CancellationToken cancellationToken)
    {
        var url = _linkGenerator.LinkFor("/Customers/Bookings/Messages", new { Id = @event.BookingId.ToString() });
        
        foreach (var (fullName, emailAddress) in @event.EmailDetails)
        {
            await _emailSender.SendAsync(emailAddress, MailType.MessageAdded, new Dictionary<string, dynamic>
            {
                {"FullName", fullName},
                {"ReferenceNumber", @event.Reference},
                {"BookingUrl", HtmlEncoder.Default.Encode(url)},
            });
        }
    }
  

Комментарии:

1. Не могли бы вы рассказать мне, как вы вызываете PageLinkGenerator ? Вы регистрируете его как сервис?

2. Я использую Lamar, который регистрирует его как сервис и вводит его в другой класс через DI.

3. Серверы LinkGenerator будут зарегистрированы при вызове служб. AddRouting(); , поскольку я не знаю, что lamar зарегистрирует запрос addrouting. Вы можете попробовать зарегистрировать его и повторить попытку. Кроме того, пожалуйста, поделитесь своими кодами, такими как startup.cs, как говорит @CodeCaster.

4. @BrandoZhang Я добавил сервисы. AddRouting() к startup.cs и LinkGenerator по-прежнему возвращает null

5. Похоже, что вы не регистрируете PageLinkGenerator как сервис в методе ConfigureContainer.

Ответ №1:

Проблема заключалась в том, что я пропустил имя страницы на странице. Я не указывал индексную страницу.

 _linkGenerator.LinkFor("/Customers/Bookings/Messages/Index" ...