简体   繁体   English

AutoMapper IValueResolver:无法访问已处理的对象。 对象名称:'IServiceProvider'

[英]AutoMapper IValueResolver: Cannot access a disposed object. Object name: 'IServiceProvider'

I want to use IValueResolver in AutoMapper to map two class, and one value will be take from HttpRequest Context, so I want to use IValueResolver我想在 AutoMapper 中使用 IValueResolver 来映射两个类,并且将从 HttpRequest Context 中获取一个值,所以我想使用 IValueResolver

CreateMap<Dto, ViewModel>().ForMember(x=>x.MemberID, opt=>opt.Mapfrom<SpecialResolver>())

and Resolver is simple和解析器很简单

public string Resolve(ViewModel viewModel, Dto dto, string destMember, ResolutionContext context)
{
  return "test";
}

inside startup class i put this:在启动类中,我把这个:

services.AddAutoMapper(typeof(Startup));

but every time I map them for MemberID will throw out error say IServiceProvider been disposed.但是每次我将它们映射到 MemberID 时都会抛出错误,说 IServiceProvider 已被处理。 so how to make these work?那么如何使这些工作? I tried inject this SpecialResolver in startup but also not work.我尝试在启动时注入这个 SpecialResolver 但也没有工作。 BTW, I'm use .net core 3.0顺便说一句,我使用 .net core 3.0

I'm strongly convinced that a bug has crept in your code somewhere and hence your problems.我坚信一个错误已经潜入您的代码中的某个地方,从而导致您的问题。 On my side, everything works just fine.在我这边,一切正常。 I tried to recrete what you are trying to do, based on your question and comments.根据您的问题和评论,我试图重新定义您正在尝试做的事情。 It will surely differ more or less, but you should be able to grasp the idea and get it going on your own.它肯定会或多或少地有所不同,但您应该能够掌握这个想法并自行完成。

I'm starting with a mapping profile, where I'm explicitly specifying usage of HttpContextValueResolver for MemberId property of ViewModel class:我从一个映射配置文件开始,我在其中明确指定了HttpContextValueResolver用于ViewModel类的MemberId属性的用法:

public class MyMappingProfile : Profile
{
    public MyMappingProfile()
    {
        CreateMap<Dto, ViewModel>()
            .ForMember(x => x.MemberId, opt => opt.MapFrom<HttpContextValueResolver>());
    }
}

Then the value resolver:然后是值解析器:

public class HttpContextValueResolver : IValueResolver<Dto, ViewModel, string>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public HttpContextValueResolver(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public string Resolve(Dto source, ViewModel destination, string destMember, ResolutionContext context)
    {
        // Obtain whatever you need from HTTP context.
        // Warning! HTTP context may be null.

        return _httpContextAccessor.HttpContext?.Request.Path;
    }
}

To acess HttpContext outside a controller I used a dedicated for that purpose service called IHttpContextAccessor .为了在控制器外访问 HttpContext,我使用了一个专门用于该目的的服务,称为IHttpContextAccessor Read more about it in the docs .文档中阅读更多关于它的信息。

It isn't automatically available, so I need to register it in Startup alongside with the AutoMapper:它不是自动可用的,所以我需要将它与 AutoMapper 一起在Startup注册:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddAutoMapper(typeof(Startup));

    services.AddHttpContextAccessor();
}

Take notice that registering AutoMapper while passing just one type (of Startup), requires that all mapping profiles need to be in the same assembly (project) as the Startup.请注意,在仅传递一种类型(启动)时注册 AutoMapper,要求所有映射配置文件都需要与启动在同一个程序集(项目)中。 With mapping profiles in more than one assembly, you need to specify those assemblies or types with a suitable overload of the AddAutoMapper() method.对于多个程序集中的映射配置文件,您需要使用AddAutoMapper()方法的合适重载来指定这些程序集或类型。

And finally usage in an example controller:最后在示例控制器中使用:

public class HomeController : Controller
{
    private readonly IMapper mapper;

    public HomeController(IMapper mapper)
    {
        this.mapper = mapper;
    }

    public IActionResult Index()
    {
        var source = new Dto
        {
            MemberID = "123",
        };
        var result = mapper.Map<ViewModel>(source);

        return View();
    }
}

And here are the dto and view model I used:这是我使用的 dto 和视图模型:

public class Dto
{
    public string MemberID { get; set; }
}
public class ViewModel
{
    public string MemberId { get; set; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Azure function 启动时出错:无法访问已处置的 object。Object 名称:'IServiceProvider' - Azure function error on startup: Cannot access a disposed object. Object name: 'IServiceProvider' 无法访问已处置的 object。 Object 名称:“IServiceProvider”,同时使用后台队列 - Cannot access a disposed object. Object name: 'IServiceProvider' while working with background queue 无法访问已处置的 object。 Object 名称:AspNet Core/EF Core 项目中出现“IServiceProvider”错误 - Cannot access a disposed object. Object name: 'IServiceProvider' error in AspNet Core/EF Core project ObjectDisposedException:无法访问已处置的对象。 对象名称:“调度程序” - ObjectDisposedException: Cannot access a disposed object. Object name: 'Dispatcher' C#&#39;无法访问已处置的对象。 对象名称:“ SslStream”。 - C# 'Cannot access a disposed object. Object name: 'SslStream'.' HangFire“无法访问已处置的对象。对象名称:'SqlDelegatedTransaction'” - HangFire "Cannot access a disposed object. Object name: 'SqlDelegatedTransaction'" 无法访问已处置的对象。 对象名称:&#39;tlsxyz&#39; - Cannot access a disposed object. Object name: 'tlsxyz' 无法访问已处置的对象。 对象名称:“ NumericUpDown” - Cannot access a disposed object. Object name: 'NumericUpDown' 无法访问已处置的对象。\\ r \\ n对象名称:“ ApplicationUserManager” - Cannot access a disposed object.\r\nObject name: 'ApplicationUserManager' .Net Core 2.1 - 无法访问已处置的 object.Object 名称:'IServiceProvider' - .Net Core 2.1 - Cannot access a disposed object.Object name: 'IServiceProvider'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM