0

I'm unable to Post a string to a WebAPI from a Console Application:

Console App:

public void Main()
{
    try
    {
        ProcessData().Wait();
    }
    catch (Exception e)
    {
        logger.Log(LogLevel.Info, e);
    }
}

private static async Task ProcessData()
{
    try
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(API_BASE_URL);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // HTTP POST
            var response = await client.PostAsJsonAsync("api/teste", "test_api");
        }
    }
    catch (Exception e)
    {
        logger.Log(LogLevel.Info, e);
    }

I try to call a WebAPI in an MVC4 Web Application:

namespace Heelp.Api
{
    public class TesteController : ApiController
    {
        private readonly ICommentService _commentService;

        public TesteController(ICommentService commentService)
        {
            _commentService = commentService;
        }

        public string Post(string comment)
        {
            var response = "OK";

            try
            {
                _commentService.Create(new Core.DtoModels.CommentDto { CommentType = "Like", Email = "p@p.pt", Message = "comment" });
            }
            catch(Exception e)
            {
                response = e.Message;
            }

            return response;
        }
    }
}

[EDIT]

After testing with fiddler, I get the error:

 {"Message":"An error has occurred.","ExceptionMessage":"Type 'Heelp.Api.TesteController' does not have a default onstructor",
    "ExceptionType":"System.ArgumentException","StackTrace":"   
        at System.Linq.Expressions.Expression.New(Type type)\r\n   at 
        System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at 
        System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, 
        HttpControllerDescriptor controllerDescriptor, Type controllerType)"}

The Route is the Default.

I don't know how to debug it, and why it's not working.

What am I doing wrong here?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Patrick
  • 2,995
  • 14
  • 64
  • 125
  • 1
    Use Visual Studio to debug server and client portions of the code. Use Fiddler to check what is sent over network. Than when you localized your problem update your post (i.e. error messages, where you see unexpected behavior and like). – Alexei Levenkov Jan 25 '14 at 04:09
  • I don't think you forming your call properly. String is one thing, JSON is another. You not posting JSON but act as if you do. Use client.PostAsync and remove any JSON-related headers – T.S. Jan 25 '14 at 04:24
  • Hi, I have put the error I get from fiddler – Patrick Jan 25 '14 at 14:07
  • Check out this article on Autofac with MVC4: [Autofac with MVC4: controller does not have a default constructor][1]. [1]: http://stackoverflow.com/questions/13423992/autofac-with-mvc4-controller-does-not-have-a-default-constructor – Turnkey Jan 25 '14 at 14:49
  • Hi, Thanks I found the problem and the Autofac DI for the ApiControllers were missing. Thanks for your help ;) – Patrick Jan 25 '14 at 15:53
  • Same question [The HttpClient class is built in .NET 4.5, not in .NET 4.0.][1] [1]: http://stackoverflow.com/questions/15176538/net-httpclient-how-to-post-string-value – Joni Boi Jan 25 '15 at 22:06

2 Answers2

1

Here goes my answer, Web API always had this problem with Simple Types. Read Rick Strahls Blog Post on Web API problems with Simple Data Types

What you can do it, have WEB API code in this way -

public HttpResponseMessage Post(FormDataCollection formData)
{
    return null;
}

And let HttpClient request in this way -

    HttpClient client = new HttpClient();
    var nameValues = new Dictionary<string, string>();
    nameValues.Add("Name", "hi");
    var Name = new FormUrlEncodedContent(nameValues);
    client.PostAsync("http://localhost:23133/api/values", Name).ContinueWith(task =>
    {
        var responseNew = task.Result;
        Console.WriteLine(responseNew.Content.ReadAsStringAsync().Result);
    });

that will give the output as follows - enter image description here

[--- EDIT based on question edit ---]

I checked the latest edit on question and the Error because of no Default Constructor. That error is because you got something wrong with Dependency Injection which you are doing for constructor injection. So please check that area. Also use Unity Web API Dependency Injection nuget to get the work done. Here goes complete tutorial in setting up DI using Unity.

Also please check the autofac if you need different versions of it from MVC and Web Api, at least that is the case with Unity though. I think you need to have Autofac.WebApi 3.1.0 for DI to work with Web API controllers.

ramiramilu
  • 17,044
  • 6
  • 49
  • 66
  • @Patrick, Have you setup your Dependency Inject IoC correctly. The error is because of it. There is a specific Unity IoC nuget of Web API, please use it. – ramiramilu Jan 25 '14 at 14:14
  • I already have Autofac installed and configured in this project. The other controllers are exactly the same, so I don't understand why the ApiController does not work, do I have to do something special in the Autofac IoC to solve this? If I removed the controller, I can call the method without any problem – Patrick Jan 25 '14 at 14:31
  • @Patrick, are other ApiControllers are working fine with AutoFac? Check with autofac if you need different versions of it from MVC and Web Api, at least that is the case with Unity though. – ramiramilu Jan 25 '14 at 14:42
  • Hi, Thanks I found the problem and the Autofac DI for the ApiControllers were missing as you were suggesting. Thanks for your help ;) – Patrick Jan 25 '14 at 15:53
  • If my post helps you, I am going to update my answer, can you please mark it out as answer. – ramiramilu Jan 25 '14 at 16:00
  • I only saw your answer regarding Autofac WebApi when I came here to insert my answer. – Patrick Jan 27 '14 at 10:00
0

First of all, thanks for all the help.

The problem was that in the MVC4 project where I add the Api, I was already using Autofac for Dependency Injection, but I was not aware that I also need DI for the ApiControllers.

So I installed using NuGet Autofac.WebApi 3.1.0 and add to the Autofac Config the lines:

In the Begin:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

In the End:

GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Now everything is working fine ! :)

Patrick
  • 2,995
  • 14
  • 64
  • 125