1

I've created two projects:

Web Project, that contains all the viewmodels/data/controllers etc. And a Web Api project to allow form capture.

I simply want to capture the data in the web Api and save it to the database where it will become accessible to the front end.

I am experiencing an issue initialzing the DBcontext within the Api controller and need help.

namespace ZebraCRM.API2.Controllers

    {
        [Route("api/[controller]")]
        public class LeadsController : Controller
        {
        private readonly ApplicationDbContext _context;

        public LeadController(ApplicationDbContext context)
        {
            _context = context;
        }


            // POST api/values
            [HttpPost]
            public void Post(Lead formData)
            {
                formData.DateCreated = DateTime.Now;

                _context.Lead.Add(formData);
                _context.SaveChanges();
        }
    }

The above idea was taken from the controller in the main web project, but is obviously not the right approach in this situation.

the debug outputs the following

System.InvalidOperationException: Unable to resolve service for type 'ZebraCRM.Web.Data.ApplicationDbContext' while attempting to activate 'ZebraCRM.API2.Controllers.LeadsController'.
Hamza
  • 45
  • 8
PowerMan2015
  • 1,307
  • 5
  • 19
  • 40
  • 1
    Okay, so did you set up Dependency Injection anywhere? If not, constructor injection won't work. You'll need to just manually assign the field value and eliminate the constructor parameter. – mason Sep 22 '17 at 16:44
  • no dependency injection has been set up. Could you please show an example? im still a little confused – PowerMan2015 Sep 22 '17 at 16:45
  • 1
    There are plenty of online tutorials on DI and many frameworks to choose from. – Igor Sep 22 '17 at 16:50

1 Answers1

1

The framework doesn't know how to constructor a LeadController because it doesn't know how to satisfy the ApplicationDbContext context parameter when it calls the constructor. To solve this, you could simply assign the value as part of your constructor, eliminating the parameter.

namespace ZebraCRM.API2.Controllers
{
    [Route("api/[controller]")]
    public class LeadsController : Controller
    {
        private readonly ApplicationDbContext _context;

        public LeadController()
        {
            _context = new ApplicationDbContext();
        }        

        // POST api/values
        [HttpPost]
        public void Post(Lead formData)
        {
            formData.DateCreated = DateTime.Now;        
            _context.Lead.Add(formData);
            _context.SaveChanges();
        }
    }
}

Or, if you do want to leave the constructor parameter in place, you'll need a DI container such as AutoFac or Ninject. If you're new to DI, I suggest you watch this video. When you set things up for Dependency Injection, you will basically pass something to the framework that says "When constructing an object that needs an X, here's how you give it an X". This allows you to better follow SOLID principles. An object can demand an IRepository (an interface) and as part of your DI setup you can say "when an object demands an IRepository, I want to pass it a SqlServerRepository (which would implement IRepository)". Then if you later decided to switch to MySQL, you could modify the setup to use a MySqlRepository instead of SqlServerRepository, without needing to modify anything about the controller, since the controller would use the repository via the interface.

mason
  • 31,774
  • 10
  • 77
  • 121
  • im getting an error on "new ApplicationDbContext();" its looking some DbContextOptions – PowerMan2015 Sep 22 '17 at 16:55
  • @PowerMan2015 You're going to have to be more specific than "an error". Post the exact error message. – mason Sep 22 '17 at 16:56
  • There is no given argument that corresponds to the require formal parameter 'options'. This is within VS and not at runtime – PowerMan2015 Sep 22 '17 at 16:57
  • Well, then pass it an instance of options when you call the constructor. Or create a parameterless constructor that handles it for you. – mason Sep 22 '17 at 16:58
  • i wish i could pass it. I have no idea what its for or where i get it. – PowerMan2015 Sep 22 '17 at 17:01
  • @PowerMan2015 See [What goes into DbContextOptions when invoking a new DbContext?](https://stackoverflow.com/questions/38417051) – mason Sep 22 '17 at 17:05