当我尝试将数据提交到数据库时,我收到以下错误:
{“Success”:false,“Error”:true,“ErrorType”:2,“Message”:“System.InvalidOperationException:Mapper未初始化。使用适当的配置调用Initialize。如果您尝试使用mapper实例在容器或其他方面,确保您没有对静态Mapper.Map方法的任何调用,并且如果您使用ProjectTo或UseAsDataSource扩展方法,请确保传入适当的IConfigurationProvider实例。\ r \ n在AutoMapper中。 Mapper.get_Instance()\ r \ n在AutoMapper.Mapper.Map(对象源,对象目标,类型sourceType,类型destinationType)\ r \ n在GoalPear.Web.Areas.PM.Controllers.CompanyController.SaveData(CompanyFormViewModel companyFormViewModel)
请告诉我为什么我会收到这个错误,因为我在经过这么多努力后无法弄明白。
这是我的控制器代码
public CompanyController() { }
private readonly ICompanyService _companyService;
public CompanyController(ICompanyService companyService) {
_companyService = companyService;
}
这是控制器中的SaveData方法
[HttpPost]
public JsonResult SaveData(CompanyFormViewModel companyFormViewModel)
{
try
{
int? id = null;
Company company;
if (companyFormViewModel.Id == null)
{
company = new Company();
}
else
{
id = (int)companyFormViewModel.Id;
company = _companyService.GetCompany((int)id);
}
company = (Company)Mapper.Map(
companyFormViewModel,
company,
typeof(CompanyFormViewModel),
typeof(Company));
CompanyValidator companyValidator = new CompanyValidator();
ValidationResult validationResult = companyValidator.Validate(company);
if (validationResult.IsValid) //check for any validation errors
{
if (id == null)
{
_companyService.CreateCompany(company);
}
else
{
_companyService.Update(company);
}
_companyService.SaveCompany();
return new JsonSuccessResult();
}
else
{
Response.StatusCode = (int)ResponseCode.UnprocessableEntity;
return new JsonErrorResult(validationResult);
}
}
catch (Exception ex)
{
Response.StatusCode = (int)ResponseCode.UnprocessableEntity;
return new JsonErrorResult(ex.ToString());
}
}
我的表单视图代码
@using (Html.BeginForm("SaveData", "Company", FormMethod.Post, new { @class = "", @id = "validate", @role = "form" })) {
@*<form id="validate" method="POST" action="javascript:alert('Form #validate submited');">*@
<div class="head tac">
<h1>Register Your Company With Us!!!</h1>
</div>
<div class="block">
<div class="header">
<div class="side pull-right">
<button class="btn btn-default btn-clean" onclick="clear_form('#validate');" type="button">Clear form</button>
</div>
</div>
<div class="content controls">
<div class="form-row">
<div class="col-md-3">Company Name:</div>
<div class="col-md-9">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "validate[required,maxSize[100]]", @placeholder = @Html.DisplayNameFor(model => model.Name) } })
</div>
</div>
<div class="form-row">
<div class="col-md-3">Owner Name:</div>
<div class="col-md-9">
@Html.EditorFor(model => model.Owner, new { htmlAttributes = new { @class = "validate[required,maxSize[60]]", @placeholder = @Html.DisplayNameFor(model => model.Owner) } })
</div>
</div>
<div class="form-row">
<div class="col-md-3">Email:</div>
<div class="col-md-4">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "validate[required,maxSize[60]]" ,@type="email", @placeholder = @Html.DisplayNameFor(model => model.Email) } })
</div>
</div>
<div class="form-row">
<div class="col-md-3">Password:</div>
<div class="col-md-9">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "validate[required,maxSize[100]]", @type="password", @id="password", @placeholder = @Html.DisplayNameFor(model => model.Password) } })
</div>
</div>
<div class="form-row">
<div class="col-md-3">Confirm Password:</div>
<div class="col-md-9">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "validate[required,equals[password]]", @type = "password", @placeholder = @Html.DisplayNameFor(model => model.Password) } })
</div>
</div>
@* I have omitted some code from here for saving your time to read*@
<div class="form-row">
<div class="col-md-3">Address:</div>
<div class="col-md-9">
@Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "validate[required,maxSize[60]]", @placeholder = @Html.DisplayNameFor(model => model.Address) } })
</div>
</div>
</div>
<div class="footer">
<div class="side pull-right">
<div class="btn-group">
<button class="btn btn-default" type="button" onclick="$('#validate').validationEngine('hide');">Hide prompts</button>
<button class="btn btn-success" type="submit">Submit</button>
</div>
</div>
</div>
</div>
}
这是我的公司型号代码
public string Name {get;set;}
public string Logo { get; set; }
public string Address { get; set; }
public string Owner { get; set; }
public int Size { get; set; }
public string Email { get; set; }
public int Phone { get; set; }
public int FaxNo { get; set; }
public string Password { get; set; }
public string Country { get; set; }
public string State { get; set; }
这是ViewModel代码
public CompanyFormViewModel() { }
public int? Id { get; set; }
[DisplayName(" Company Name")]
public string Name { get; set; }
[DisplayName("Owner")]
public string Owner { get; set; }
[DisplayName("Email")]
public string Email { get; set; }
[DisplayName("Password")]
public string Password { get; set; }
[DisplayName("Address")]
public string Address { get; set; }
这是DomainToViewModelMapping Profile
cfg.CreateMap<Company, CompanyFormViewModel>()
.ForMember(vm => vm.Id, map => map.MapFrom(m => m.Id))
.ForMember(vm => vm.Name, map => map.MapFrom(m => m.Name))
.ForMember(vm => vm.Owner, map => map.MapFrom(m => m.Owner))
.ForMember(vm => vm.Email, map => map.MapFrom(m => m.Email))
.ForMember(vm => vm.Password, map => map.MapFrom(m => m.Password))
.ForMember(vm => vm.Address, map => map.MapFrom(m => m.Address));
我的viewModeltoDomainMapping个人资料
cfg.CreateMap<CompanyFormViewModel, Company>()
.ForMember(m => m.Id, map => map.MapFrom(vm => vm.Id))
.ForMember(m => m.Name, map => map.MapFrom(vm => vm.Name))
.ForMember(m => m.Owner, map => map.MapFrom(vm => vm.Owner))
.ForMember(m => m.Email, map => map.MapFrom(vm => vm.Email))
.ForMember(m => m.Password, map => map.MapFrom(vm => vm.Password))
.ForMember(m => m.Address, map => map.MapFrom(vm => vm.Address));
为什么我的mapper错误未初始化?
答案 0 :(得分:7)
无法看到初始化映射的位置。
<强>解决方案:强>
您可以创建映射配置文件,例如:
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Company, CompanyFormViewModel>()
.ForMember(vm => vm.Id, map => map.MapFrom(m => m.Id))
.ForMember(vm => vm.Name, map => map.MapFrom(m => m.Name))
.ForMember(vm => vm.Owner, map => map.MapFrom(m => m.Owner))
.ForMember(vm => vm.Email, map => map.MapFrom(m => m.Email))
.ForMember(vm => vm.Password, map => map.MapFrom(m => m.Password))
.ForMember(vm => vm.Address, map => map.MapFrom(m => m.Address));
CreateMap<CompanyFormViewModel, Company>()
.ForMember(m => m.Id, map => map.MapFrom(vm => vm.Id))
.ForMember(m => m.Name, map => map.MapFrom(vm => vm.Name))
.ForMember(m => m.Owner, map => map.MapFrom(vm => vm.Owner))
.ForMember(m => m.Email, map => map.MapFrom(vm => vm.Email))
.ForMember(m => m.Password, map => map.MapFrom(vm => vm.Password))
.ForMember(m => m.Address, map => map.MapFrom(vm => vm.Address));
}
}
然后在Global.asax.cs
public class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(x =>
{
x.AddProfile<MappingProfile>();
});
Mapper.Configuration.AssertConfigurationIsValid();
}
}
最后,不要忘记在Application_Start()
//Configure Automapper
AutoMapperConfiguration.Configure();
答案 1 :(得分:3)
您需要使用通过配置创建的映射器实例,而不是使用静态Mapper.Map
方法,如下所示:
var mapper = cfg.CreateMapper();
var company = (Company)mapper.Map(companyFormViewModel, company, typeof(CompanyFormViewModel), typeof(Company));
在最新版本中使用mapper的首选方法是通过IMapper
界面。如果您也使用DI容器,则可以绑定/注册IMapper
以通过config.CreateMapper()
方法重载来解析实例,该方法需要实例工厂委托(即容器的实例工厂方法)。如果您没有使用DI容器,您可以创建例如MapperFactory
类,它将负责映射器实例的创建及其配置。
示例:
var config = new MapperConfiguration(cfg =>
{
//cfg.CreateMap()...
//cfg.AddProfile()... etc...
});
var mapper = config.CreateMapper();
答案 2 :(得分:1)
您可能正在使用旧版本的AutoMapper.Extensions.Microsoft.DependencyInjection 从NuGet安装最新版本的 AutoMapper.Extensions.Microsoft.DependencyInjection (我使用v7.0.0),然后将services.AddAutoMapper()更改为 services.AddAutoMapper(typeof(services))在Startup.cs中