1

This is a follow-up on an earlier question regarding using HttpClient with Web API performing authentication using a custom Message Handler.

I can request data from the server using the provided solution, but now I am having trouble posting JSON data to the server. Whenever I try posting data to the Web API I am returned an Internal Server Error response code.

Here is the code on the client side:

using (var httpClient = new HttpClient())
{
    var request = new HttpRequestMessage();
    request.Headers.Add("X-Token", UserSession.GlobalInstance.SecurityToken);
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    request.Method = HttpMethod.Post;
    request.RequestUri = new Uri(_apiBaseAddress + "api/User");
    request.Content = new ObjectContent<UserDTO>(userDTO, new JsonMediaTypeFormatter());

    var response = httpClient.SendAsync(request).Result;
    if (response.IsSuccessStatusCode)
    {
        // handle result code
    }

    throw new Exception(String.Format("Server generated error response: {0}", response.StatusCode));
}

The declaration for the controller method:

public class UserController : ApiController
{
    public long Post(UserDTO userDTO)
    {
        // create user and return custom result
        // code (e.g. success, duplicate email, etc...)
    }
}

(I've also added [FromBody] to the method parameter, but end up with the same result).

A snapshot of the code for my message handler and routing configuration can be found here.

1 Answer 1

0

Your code works as expected...

The server side. Create a console application and run NuGet

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost

Program.cs

internal class Program
{
    private static IDisposable _server;

    private static void Main(string[] args)
    {
        _server = WebApp.Start<Startup>("http://localhost:12345");
        Console.ReadLine();
        _server.Dispose();
    }
}

Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        app.UseWebApi(config);
    } 
}

WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var userTokenInspector = new UserTokenInspector {InnerHandler = new HttpControllerDispatcher(config)};
        config.Routes.MapHttpRoute(
            "UserAuthenticationApi",
            "api/{controller}/Authenticate",
            new {controller = "User", action = "Authenticate"},
            null
            );

        config.Routes.MapHttpRoute(
            "DefaultApi",
            "api/{controller}/{id}",
            new {id = RouteParameter.Optional},
            null,
            userTokenInspector
            );
    }
}

UserTokenInspector.cs

public class UserTokenInspector : DelegatingHandler {
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
    CancellationToken cancellationToken) {
        const string TOKEN_NAME = "X-Token";

        if (!request.Headers.Contains(TOKEN_NAME)) {
            return Task.FromResult(request.CreateErrorResponse(HttpStatusCode.Unauthorized,
            "Request is missing authorization token."));
        }

        try {
            //var token = UserToken.Decrypt(request.Headers.GetValues(TOKEN_NAME).First());

            // validate token
            // ...
            // ...

            Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("alex"), new string[] { });
        }
        catch {
            return Task.FromResult(request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid token."));
        }

        return base.SendAsync(request, cancellationToken);
    }
}

UserController.cs

public class UserController : ApiController
{
    public long Post(UserDTO userDTO)
    {
        // create user and return custom result
        // code (e.g. success, duplicate email, etc...)
        return 1;
    }
}

UserDto.cs

public class UserDTO
{
    public string Username { get; set; }
}

ValuesController.cs

public class ValuesController : ApiController
{
    public HttpResponseMessage Get()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "yay");
    }
}

The Client... create a Console application and run NuGet:

Install-Package Microsoft.AspNet.WebApi.Client

Program.cs

internal class Program
{
    private static void Main(string[] args)
    {
        var request = new HttpRequestMessage();
        request.Headers.Add("X-Token", "token");
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Method = HttpMethod.Post;
        var baseAddress = "http://localhost:12345/";
        request.RequestUri = new Uri(baseAddress + "api/User");
        var userDto = new UserDTO() {Username = "Alex"};
        request.Content = new ObjectContent<UserDTO>(userDto, new JsonMediaTypeFormatter());
        var httpClient = new HttpClient();
        var response = httpClient.SendAsync(request).Result;
        if (response.IsSuccessStatusCode)
        {
            // handle result code
            Console.WriteLine(response.StatusCode);
            Console.ReadLine();
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.