0

The problem as reported by the error message is:

"An error occurred when trying to create a controller of type 'BooksController'. Make sure that the controller has a parameterless public constructor."

I'm trying to have the controller successfully execute and/or return a value.

This is a WebApi project using an AngularJs app as the frontend. Any calls to this controller return a 500 error with the above message. Ishould also add that I am using Insight.Database

I have tried creating a new controller and adding and removing the constructor. But I wan't able to get any better hints about what I'm doing wrong.

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Data.SqlClient;
using System.Configuration;
using System.Threading.Tasks; 
using Insight.Database;
using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.SqlServer;
using Wallet.Models.Books;
using Wallet.Models.Stores; 
using Wallet.Models.Database;

namespace Wallet.Controllers
{
    [Authorize]
    [RoutePrefix("api/books")]
    public class BooksController : ApiController
    {
        private IBooksDataAccess access; 
        public BooksController()
        {
            access = HttpContext.Current.GetOwinContext().Get<SqlConnection>()
                .As<IBooksDataAccess>(); 
        }

        // POST api/books/GetActions
        [HttpPost]
        [Route("GetActions")] 
        public IList<HistoryAction> ActionsHH([FromBody] Dictionary<string, string> input)
        {
            var name = input["name"]; 
            var results = access.GetHistoricalActions(name); 
            return results; 
        }

        // POST api/books/InsertTransaction
        [HttpPost]
        [Route("InsertTransaction")] 
        public void InsertTx([FromBody] Dictionary<string, string> input)
        {
        }
    }
}

And here's the IBookDataAccess

namespace Wallet.Models.Database
{
    [Sql(Schema = "Models")]
    public interface IBooksDataAccess
    {
        IList<HistoryAction> GetHistoricalActions(string UserName);
        int InsertTransaction(Dictionary<string, string> transaction); 
    }
}
  • Possibly a duplicate question. The same has been discussed here.. http://stackoverflow.com/questions/24014644/make-sure-that-the-controller-has-a-parameterless-public-constructor did you try this link? – Vim Apr 17 '15 at 18:31
  • I'm sorry, I put up the wrong code. However the error persists regardless of whether or not a constructor is there. – Evan DiBona Apr 17 '15 at 18:54
  • @Vim I did come across that while searching, but even after adding a constructor(empty or not) the error still occurs. – Evan DiBona Apr 17 '15 at 19:11
  • I'm not familiar with WebAPI or Angular.js, but the error stating that a parameterless constructor is needed implies to me that it's a serialization issue. This in turn leads me to suggest you ensure a parameterless constructor exists but without any content, and add an Initialize() method, setting your `access` member variable there instead. This will ensure an instance of the class can be created during serialization without executing code that may not be valid in that context. (Obviously you'll then need to call Initialize() when using the class.) – Reg Edit Apr 17 '15 at 19:25
  • Is the error same for blank constructor? If not, then post that error message. – Arindam Nayak Apr 17 '15 at 20:13
  • @ArindamNayak Yes the error is exactly the same. – Evan DiBona Apr 17 '15 at 20:57
  • @RegEdit Thank you for the ideas! I wouldn't have thought the object would get serialized, is that something that always happens to these objects? – Evan DiBona Apr 17 '15 at 21:03
  • First, and unrelated to your problem, consider modifying`private IBooksDataAccess access;` to `private readonly IBooksDataAccess access;`, since it's only being set from the constructor. Is your controller's base actually `ApiController` or a custom class? – boosts Apr 20 '15 at 04:45
  • @boosts It is actually`ApiController` – Evan DiBona Apr 20 '15 at 15:38
  • How are you registering the `IBooksDataAccess` service? Can you share its implementation? – boosts Apr 20 '15 at 15:49
  • Does it work if you comment out the `access =` line? or put try catch around it and log the exception? – Ian Mercer Apr 20 '15 at 16:50

1 Answers1

0

This error will occur when the controller cannot find a parameter-less constructor, or in the case when an exception is thrown in the constructor. It looks like you are using Insight.Database, given the .As extension.

If Insight fails to generate the dynamic assembly, it will throw an exception (which you are not catching, since you instantiate the insight auto-interface builder in your member declaration.)

I will have to do some testing, but I believe I recall having issues with the name "transaction" being interpreted as the T-SQL type.

Can you try creating a constructor for your controller, and assigning the database object inside of a try/catch block inside of it?

T. Parrish
  • 61
  • 2