TeamBrett
TeamBrett

Reputation: 499

MVC WebAPI Status 500 Authentication Error when using httpclient and json

I've been banging on this all day and it's time to get some help. I am trying to call a .net MVC WebAPI application from some .net code. I am receiving a status code of 500 from the WebAPI with no real information even after upping the error detail policy to always. So I popped open Fiddler and now I can at least see a little bit more. This is what I'm receiving back from IIS via Fiddler after a call from .net:

{"Message":"An error has occurred.","ExceptionMessage":"User credentials are invalid.","ExceptionType":"System.Exception","StackTrace":" at RemoteManagementService.Controllers.ProvisioningController.PostLogOn(RequestModel`1 request) etc...

(The stack trace references the closing bracket of my action method as the erroring line)

.net HttpClient calling code:

this.DefaultRequestHeaders.Add("Origin", "http://localhost:1181");  
this.DefaultRequestHeaders.Referrer = new Uri("http://localhost:1181/Provisioner/Edit/1");
    
//this.PostAsync<RequestModel<string>>(address + "PostLogOn", request, new media JsonMediaTypeFormatter())
this.PostAsync<RequestModel<string>>(address + "PostLogOn", request, new XmlMediaTypeFormatter())
    .ContinueWith(
        (postTask) =>
        {
            postTask.Result.Content.ReadAsAsync<string>().ContinueWith(
                (readTask) =>
                {
                    myvalue = readTask.Result;
                }).Wait();
        }).Wait();

jquery calling code:

jQuery.support.cors = true;

$.ajax({
    type: 'POST',
    url: 'http://me.mywebsite.com/provisioning/api/provisioning/PostLogOn',
    datatype: 'json',
    data: { datum: 'this is my data' },
    success: function (data) {
        alert(data);
    },
    error: function (data) {
        alert(data);
    }
});

What has really frustrated me is that when I make the same call using jquery, I seem to be able to initiate the controller action (I still get an error but that's because I can't format RequestModel<> in a valid way from my html page and am receive parsing exceptions after successfully entering the method)

jquery request from chrome:

POST /provisioning/api/provisioning/PostLogOn HTTP/1.1
Host: me.mywebsite.com
Connection: keep-alive
Content-Length: 21
Origin: http://localhost:1181
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.92 Safari/537.4
Content-Type: application/x-www-form-urlencoded
Accept: */*
Referer: http://localhost:1181/Provisioner/Edit/1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

.net HttpClient Request:

POST /provisioning/api/provisioning/PostLogOn HTTP/1.1
Accept: application/json
Origin: http://localhost:1181
Referer: http://localhost:1181/Provisioner/Edit/1
Content-Type: application/xml; charset=utf-8
Host: me.mywebsite.com
Content-Length: 420
Expect: 100-continue
Connection: Keep-Alive

And for good measure, the response I recieve(the only difference between jquery and .net being the size)

HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://localhost:1181
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 10 Oct 2012 06:34:46 GMT
Content-Length: 823

I do not have any authorization attributes on my controller or actions. I have a session key but it's not integrated into my framework and is simply data as part of my RequestModel<>. When I run the apps in debug mode from VS, everything works fine. This is only occurring after I deploy the WebAPI to my website. The jQuery call started working after I added the cors Origin handler into my API configuration startup which makes me think this is a cross domain issue, but the .net code has the same origin header... The biggest difference I'm seeing is that the ajax call is ultimately formatting things as form-urlencoded even though I specify a json datatype. I've tried both json and xml from .net to no avail. I've also tried a UrlEncodedMediaTypeFormatter but it's apparently not smart enough to serialize my data. Interestingly, if I try a simple GET from the browser URL bar on a test action, I can get a response too. Do I need to tell HttpClient I'm going cross domain similar to jQuery.support.cors = true somehow?

Any suggestions or insights would be greatly appreciated as I've reached the limits of my Google skills and personal knowledge.

Upvotes: 1

Views: 2022

Answers (2)

HamidReza
HamidReza

Reputation: 1934

or remove authorize attribute from your method or api controller and or add allowAnonymous attribute to your api method

[AllowAnonymous]
[HttpPost]
public HttpResponseMessage PostLogOn(string datum)
{
   return Request.CreateResponse(HttpStatusCode.OK);
}

Upvotes: 1

TeamBrett
TeamBrett

Reputation: 499

I have managed to resolve my issue. tugberk is correct in that it was a problem in my code. My original cross domain assumption was correct, when I added the cors message handler to my api configuration the issue was resolved and is the reason I was able to finally get the error message I had.

The reason I was getting invalid credentials was because the connection string lookup (registry) was available when I ran on my development machine but not after I deployed to the IIS server. Deploying to a fully configured beta environment was successful. My confusion stemmed from initial cross domain problems and 14 hours of diagnosing the problem.

Upvotes: 1

Related Questions