web-dev-qa-db-ja.com

Automapper、Mapper初期化されていません。適切な構成で初期化を呼び出す

データベースにデータを送信しようとすると、次のエラーが発生します。

{"Success":false、 "Error":true、 "ErrorType":2、 "Message": "System.InvalidOperationException:マッパーが初期化されていません。適切な構成でInitializeを呼び出します。そうでない場合は、静的なMapper.Mapメソッドへの呼び出しがないことを確認し、ProjectToまたはUseAsDataSource拡張メソッドを使用している場合は、適切なIConfigurationProviderインスタンスを渡すようにしてください。\ r\n AutoMapper.Mapper.get_Instance ()\ r\n AutoMapper.Mapper.Map(Object source、Object destination、Type sourceType、Type destinationType)\ r\n at 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プロファイルです

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));

マッパーが初期化されていないというエラーが発生するのはなぜですか?

11
mac

マッピングを初期化する場所が表示されません。

解決策:

たとえば、マッピングプロファイルを作成できます。

_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();
_
7
Salomon Zhang

静的な_Mapper.Map_メソッドを使用する代わりに、次のように構成によって作成されたマッパーインスタンスを使用する必要があります。

_var mapper = cfg.CreateMapper();
var company = (Company)mapper.Map(companyFormViewModel, company, typeof(CompanyFormViewModel), typeof(Company));
_

最新バージョンでマッパーを使用する好ましい方法は、IMapperインターフェイスを使用することです。 DIコンテナーも使用している場合は、IMapperをバインド/登録して、インスタンスファクトリーデリゲート(コンテナーのインスタンスファクトリーメソッド)を取るconfig.CreateMapper()メソッドオーバーロードを介してインスタンスを解決できます。 DIコンテナを使用していない場合は、たとえば、マッパーインスタンスの作成とその構成を担当するMapperFactoryクラスを作成できます。

例:

_ var config = new MapperConfiguration(cfg =>
            {
                //cfg.CreateMap()...
                //cfg.AddProfile()... etc...
            });
var mapper = config.CreateMapper();
_
3
Darjan Bogdan