Reputation: 5058
I am following a tutorial on asp.net core and angular. When I add the Automapper inside my Startup
class it crashes the dotnet cli and couldn't render the page. This is how I use the Automapper in the Startup
:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using aspcoreangular.persistence;
using AutoMapper;
namespace aspcoreangular
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper();
services.AddDbContext<VegaDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
}
}
This is how I use it in the controller. But it doesn't get to this point
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using aspcoreangular.models;
using aspcoreangular.persistence;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace aspcoreangular.Controllers
{
public class MakesController : Controller
{
private readonly VegaDbContext context;
private readonly IMapper mapper;
protected MakesController(VegaDbContext context, IMapper mapper)
{
this.mapper = mapper;
this.context = context;
}
[HttpGet("/api/makes")]
public async Task<IEnumerable<Resources.MakeResource>> GetMakes()
{
var makes = await context.Makes.Include(m => m.Models).ToListAsync();
return mapper.Map<List<Make>, List<Resources.MakeResource>>(makes);
}
}
}
This is the image of the crash: Can you please help me with this? Thank you.
This my MakeResouce class
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using aspcoreangular.models;
namespace aspcoreangular.Controllers.Resources
{
public class MakeResource
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<ModelResource> Models { get; set; }
public MakeResource()
{
Models = new Collection<ModelResource>();
}
}
}
and in my mappingprofile
using aspcoreangular.Controllers.Resources;
using aspcoreangular.models;
using AutoMapper;
namespace aspcoreangular.ClientApp.Mapping
{
public class MappingProfile : Profile
{
protected MappingProfile()
{
CreateMap<Make, MakeResource>();
CreateMap<Model, ModelResource>();
}
}
}
Upvotes: 0
Views: 1369
Reputation: 386
When AutoMapper maps source object to destination object before mapping itself it has to create an instance of the destination object and then Mapper can map properties using reflection. And the error says: No parameterless constructor is defined for this object.
That means: AutoMapper kindly asks System.Activator class to create instance of the destination object for him. But System.Activator fails because it can't find public parameterless contructor in destination class (obviously, System.Activator can use constructor with parameters, but AutoMapper hadn't provided any parameters for constructor). And that is why the third line of the Error message comes from Activator.CreateInstance method.
So, to sum up, you should examine Resources.MakeResource class (as destination) for parameterless constructor.
PS. But I can't tell you on Why this exception crashes the whole Application
Upvotes: 1