尝试激活时无法解析“Microsoft.AspNetCore.Mvc.IUrlHelper”类型的服务

Jay*_*Jay 8 c# asp.net-core

我试图将代码从控制器分离到我创建的服务。我所做的是创建一个带有接口 IUserService 的用户服务。

将 RegisterUser 代码从直接控制器移动到 UserService,我得到的下一个挑战是直接与控制器一起使用的 Url 不能与服务一起使用。

这段从 Controller 到 Service 的代码已更改如下:

如果在控制器中

var callbackUrl = Url.EmailConfirmationLink(user.Email, token, model.contactno, Request.Scheme);
Run Code Online (Sandbox Code Playgroud)

从控制器更改为服务:

  private IUrlHelper _urlHelper;

    public UserService (IUrlHelper urlHelper, HttpRequest request) {
_urlHelper = urlHelper;
}
Run Code Online (Sandbox Code Playgroud)

这是构造函数,

在方法中我这样称呼它:

        var callbackUrl = _urlHelper.EmailConfirmationLink (user.Email, token, U.Email, _request.Scheme);
Run Code Online (Sandbox Code Playgroud)

我在 Startup.cs 的 DI 中这样提到:

services.AddScoped<IUserService, UserService>();
Run Code Online (Sandbox Code Playgroud)

编译时没有异常。在运行时,它抛出以下异常:

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.IUrlHelper' while attempting to activate 'erp.Services.UserService'.
Run Code Online (Sandbox Code Playgroud)

不是很清楚到底要做什么。

这是完整的堆栈跟踪,可以更仔细地查看错误。好吧,我不能说确切的行,因为我不是在调试,而只是从日志中复制:

Executed endpoint 'erp.Controllers.AccountController.Register (erp)'
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Http.HttpRequest' while attempting to activate 'erp.Services.UserService'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
Run Code Online (Sandbox Code Playgroud)

Tao*_*hou 14

因为Object reference not set to an instance of an object,是你没有注册造成的IActionContextAccessor

尝试按照以下步骤操作:

  1. 用户服务

    public interface IUserService
    {
        void RegisterUser();
    }
    public class UserService : IUserService
    {
        private IUrlHelper _urlHelper;
        private HttpRequest _request;
    
        public UserService(IUrlHelper urlHelper, IHttpContextAccessor httpContextAccessor)
        {
            _urlHelper = urlHelper;
            _request = httpContextAccessor.HttpContext.Request;
        }
        public void RegisterUser()
        {
            var callbackUrl = _urlHelper.EmailConfirmationLink("user.Email", "token", _request.Scheme);
            //throw new NotImplementedException();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 登记

    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
    services.AddScoped<IUrlHelper>(x => {
        var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
        var factory = x.GetRequiredService<IUrlHelperFactory>();
        return factory.GetUrlHelper(actionContext);
    });
    
    services.AddScoped<IUserService, UserService>();
    
    Run Code Online (Sandbox Code Playgroud)


Moi*_*jik 5

IUrlHelper像这样在您的 DI 容器中注册:

services.AddScoped<IUrlHelper>(factory =>
{
    var actionContext = factory.GetService<IActionContextAccessor>()
                               .ActionContext;
    return new UrlHelper(actionContext);
});
Run Code Online (Sandbox Code Playgroud)

要在您的服务中使用 HttpContext,您必须使用 IHttpContextAccessor:

public class MyService
{
    private IHttpContextAccessor _httpContextAccessor;
    public MyService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void MyMethod()
    {
        // Use HttpContext like this
        var username = _httpContextAccessor.HttpContext.User.Identity.Name;
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,不要忘记在 DI Container 中注册 IHttpContextAccessor :

services.AddHttpContextAccessor();
Run Code Online (Sandbox Code Playgroud)