0

Let me describe the sitation.

I use web api and in the controller class where I define my http verbs I noticed that I cannot create a constructor. infact if I add a constructor which is empty it is oke but when I modify this constructor it is not. It gives me the following error when I try to post with postman to the method inside the controller class

{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred when trying to create a controller of type 'DataController'. Make sure that the controller has a parameterless public constructor.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": "   bij System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   bij System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   bij System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
"InnerException": {
    "Message": "An error has occurred.",
    "ExceptionMessage": "Type Chatbot.Controller.DataController heeft geen standaardconstructor",
    "ExceptionType": "System.ArgumentException",
    "StackTrace": "   bij System.Linq.Expressions.Expression.New(Type type)\r\n   bij System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   bij System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   bij System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
}

}

the controller class

 public class DataController : ApiController {
    public string data { get; set; }


    public DataController(string analyticsData) {
        data = analyticsData;
    }

    public void Post([FromBody] dynamic data) {
       _analyticsData.InsertCredentials("fdf", data, "dfdf");

How can I achieve my goal to add a non empty constructor to the controller class without resulting in this error?

[Edit] I want this because of the following reason:

    private  AnalyticsData _analyticsData;

    public CredentialsController(AnalyticsData analyticsData) {
        _analyticsData = analyticsData;
    }

//acces the following method send data to database
_analyticsData.InsertCredentials("fdf", "fdd", "dfdf");

I want to acces this method from the constructor however I already get this error if my constructor is not empty. Like I said when I add a empty constructor next to it it will not anymore receive an error but _analyticsData could not be found since this is only available in the second constructor

[Edit] I am now using Unity to DI this is the line I have added inside my WebApiConfig

container.RegisterType<IAnalyticsData, AnalyticsData>(new HierarchicalLifetimeManager());

I tested this with other classes and interfaces and it works. But It does not work when the class for example AnalyticsData has a constructor inside it. So This only works if I remove the constructor from the AnalyticsData class

Constructor from AnalyticsData class

public AnalyticsData(ResourceFile file, ResourceFile creationFile) {
    var exists = file.Exists();

    _connection = SQLite.Open(file);

    if (!exists && creationFile.Exists()) {
        SQLite.Execute(_connection, creationFile.GetText());
    }
}

The constructor is needed to load the current sqlite database

AnalyticsData = new AnalyticsData(new ResourceFile(Settings.String("DatabaseLocation")), Resources.GetFolder("data").GetFile("create.sql"));

The only problem I am now receiving is that I need to use the constructor I cannot use without it because then I cannot anymore make a connection to the database.

Do I need to do something more then just adding this line?

container.RegisterType<IAnalyticsData, AnalyticsData>(new HierarchicalLifetimeManager());
Bcoded
  • 83
  • 10
  • Create an empty Constructor and create your owns (you must have both). – Emy Blacksmith Apr 24 '18 at 10:59
  • 1
    Your class don't have parameterless constructor. That's clearly stated in the exception message. – Niyoko Apr 24 '18 at 11:01
  • What is `analyticsData` and how is it meant to be used – Nkosi Apr 24 '18 at 11:03
  • When I create an empty constructor next to it it will only take the empty constructor not the one I intend to use but the error will be gone. analyticsData is just an example of receiving an error when I have a constructor which is not empty. – Bcoded Apr 24 '18 at 11:11
  • I have updated my question to give a clear view of what I try to achieve – Bcoded Apr 24 '18 at 11:16
  • how are you going to be passing anything into the constructor of the controller? It's not really your job to instantiate it. Web API is doing this already, and it's not expecting to have to provide a parameter. What's your actual requirement here? Perhaps you're going about it in the wrong way. – ADyson Apr 24 '18 at 11:16
  • What I try to do this is to receive data that came from a post request and hash data within the controller method and send this to the analyticdata class file where I want to store it in a sqitedatabase. The problem is that I try to acces that file but this is only possible by initaiting it inside the constructor. Making it static is not an option – Bcoded Apr 24 '18 at 11:21
  • 1
    @Bcoded Read up on dependency injection in Asp.Net Web API and the DependencyResolver. The framework is unable to resolve the dependency because you have not registered them, which is why it is failing. https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection – Nkosi Apr 24 '18 at 11:26
  • Hmm that make sence.. I will check this out – Bcoded Apr 24 '18 at 11:45
  • " I try to acces that file but this is only possible by initaiting it inside the constructor"....why? That seems unlikely. If it's just a file, you can read it anytime. – ADyson Apr 24 '18 at 12:22
  • I read about depedency injection and registered the classes. I have updated my information with a last problem I m now receiving. – Bcoded Apr 25 '18 at 07:43

1 Answers1

0

When you create a class without a constructor, the compiler automatically creates a parameterless constructor for it. When you create a class with a constructor (with or without parameters), your compiler does not automatically create a paremeterless constructor for the class anymore because there already exists one.

For your solution, you simply need to add the parameterless constructor yourself next to your constructor with parameters:

public class DataController : ApiController {
    public string data { get; set; }

    public DataController() : this("somedefaultvalue") { } //calls the parameter constructor with "somedefaultvalue"

    public DataController(string analyticsData) {
        data = analyticsData;
    }

    //other code
}

Example to see the difference:

static void Main()
{
    var decaultConstr = new IOwnNothing(); //valid
    var customConst = new IOwnAParamConstructor(); // invalid
    var customConst2 = new IOwnAParamConstructor(6); //valid
    var privateConstr = new IOwnAPrivateParamConstructor(); //no constructor available
}

private class IOwnNothing
{
}

private class IOwnAParamConstructor
{
    public IOwnAParamConstructor(int a) { }
}

private class IOwnAPrivateParamConstructor
{
    private IOwnAPrivateParamConstructor(int a) { }
}
Chrᴉz remembers Monica
  • 1,829
  • 1
  • 10
  • 24