7

When I have a return type of 'string' in my WebAPI controller, the SuccessStatusCode returns 'OK' in my MVC Controller, but when the return type is of a model named 'USER', I get this Internal Server Error. Here's my code:

WebAPI:

public class UserController : ApiController
{
    OnlineCenterEntities db = new OnlineCenterEntities();

    public USER GetUserInfo(string userName, string domain)
    {
        USER userInfo = (from u in db.USERs
                         where u.USER_NAME.ToUpper() == userName.ToUpper() && u.LDAP_NAME.ToUpper() == domain.ToUpper()
                         select u).FirstOrDefault();

        return userInfo;
    }
}

MVC Controller that calls the WebAPI:

 public class HomeController : Controller
{
    HttpClient client;
    string url = "http://localhost:61566/api/user/";

    public HomeController()
    {
        client = new HttpClient();
        client.BaseAddress = new Uri(url);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<ActionResult> Index(string userName, string domain)
    {
        string GetUserInfoURL = String.Format("GetUserInfo?userName={0}&domain={1}", userName, domain);
        HttpResponseMessage responseMessage = await client.GetAsync(url+GetUserInfoURL);

        if (responseMessage.IsSuccessStatusCode)
        {
            var responseData = responseMessage.Content.ReadAsStringAsync().Result;
            var userInfor = JsonConvert.DeserializeObject<USER>(responseData);
        }

        return View();
    }

USER model:

public partial class USER
{

    public int USER_ID { get; set; }
    public string USER_NAME { get; set; }
    public string FIRST_NAME { get; set; }
    public string LAST_NAME { get; set; }
    public string LDAP_NAME { get; set; }
    public string EMAIL { get; set; }
}

In my WebAPI, if I change the return type from USER to string (and of course, change the return variable type to some string (userInfo.FIRST_NAME)), I get the SuccessStatusCode as 'OK', but as of this code, I get Internal Server Error with StatusCode: 500 (whatever that means). I have tried inserting breakpoint at every possible points, and I know that the api is returning the result fine. I simply don't understand why the following line

HttpResponseMessage responseMessage = await client.GetAsync(url+GetUserInfoURL);

gives InternalServerError error when I have the return type of USER, and return the whole USER model instead of just one string.

Please don't worry about the userName and domain parameters that I'm passing to the controllers, they are working fine!

Bivo Kasaju
  • 1,143
  • 3
  • 13
  • 28
  • "I know that the api is returning the result fine" - no it isn't. It's crashing, most likely from an unhandled exception. :) Change the return type back to `USER` and show us the Fiddler input+output for the request to the API. Then set a breakpoint at the start of `GetUserInfo()` and see if it really exits that method *without* an exception. – bzlm Jul 06 '16 at 19:25
  • @bzlm when I add a break point in the api controller `return userInfo' line, I get the required result and I know it because it shows in the Autos Windows in Visual Studio. The userInfo variable contains all the information on that user. – Bivo Kasaju Jul 06 '16 at 19:29
  • Yes, it exits without an exception. It comes back to the MVC controller and then gives the exception. – Bivo Kasaju Jul 06 '16 at 19:30
  • So is it the MVC client or the API server that's crashing? If it's the client, then probably your attempt to deserialize to JSON is failing? Again, show the fiddle. http://stackoverflow.com/a/24677189/7724 – bzlm Jul 06 '16 at 19:31
  • yeah I'm getting error while trying to deserialize too but before I even get to that line, I get the `SuccessStatusCode:Internal Server Error` instead of `Ok`. – Bivo Kasaju Jul 06 '16 at 19:33
  • To assist with debugging, you'll need to temporarily configure IIS to send the error details to the browser so you can see the exact reason for the 500 error. – Jasen Jul 06 '16 at 19:33
  • And after configuring IIS to show errors, just browse to the API `GetUserInfo()` endpoint (with the same URL your client is using) directly with a browser and see what happens. – bzlm Jul 06 '16 at 19:36
  • @bzlm I'm not familiar with fiddle. What am I supposed to be looking in that link? – Bivo Kasaju Jul 06 '16 at 19:37
  • http://www.devcurry.com/2013/03/debugging-your-aspnet-web-apis-with.html @BivoKasaju. Seriously, if you want to develop web applications you need proper debugging tools for all parts of your application. :) – bzlm Jul 06 '16 at 19:38
  • I tried your example, but instead having a method GetUserInfo, I followed the verb approach with a Get method and works fine. But my User class is not partial. – ramires.cabral Jul 06 '16 at 19:43
  • It might be a problem serializing `USER` as this is a partial class, maybe there is code that is not posted and contains properties with types that are not serializable using (whatever json converter you have initialized). – Igor Jul 06 '16 at 19:45

1 Answers1

1

Typically when this happens, it means it is failing to serialize the response. Once your controller returns a USER instance, somewhere WebAPI has to serialize that into the format requested by the client.

In this case the client requested "application/json". The default JsonMediaTypeFormatter uses JSON.Net to turn your C# object into json for the client. Apparently that serialization step is failing, but the response code doesn't tell you exactly why.

The easiest way to see exactly what is happening is to use a custom MessageHandler which forces the body to buffer earlier so you can see the actual exception. Take a look at this blog post for an example to force it to show you the real failure.

Tim Copenhaver
  • 3,282
  • 13
  • 18