0

Using Visual Studio 2013 I've create a new Web API 2 project and a new MVC project. There will be other clients accessing the API which is the reason it was created. Eventually the clients for the API will be allowing users to create login account using Facebook and other.

The issue I'm running into to trying read an errors returned from the API during a login such as Bad Password. I've seen many, many posts about similar errors to "No MediaTypeFormatter is available to read an object of type something from content with media type 'text/html'." but cannot resolve this issue.

The API is only needs to return json so in my WebApiConfig.cs file is GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

Here is my post in Fiddler

enter image description here

Here is the Response:

enter image description here

and the Textview of the response which looks like json to me enter image description here

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        Yoda test = new Yoda() { email = model.Email, password = model.Password };

        HttpClient client = CreateClient();
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

        //client.DefaultRequestHeaders.TryAddWithoutValidation("content-type", "application/x-www-form-urlencoded");
        client.DefaultRequestHeaders.TryAddWithoutValidation("content-type", "application/json");

        HttpResponseMessage result = await client.PostAsJsonAsync(_apiHostURL, test);

        result.EnsureSuccessStatusCode();

        if (result.IsSuccessStatusCode)
        {
            var token = result.Content.ReadAsAsync<TokenError>(new[] { new JsonMediaTypeFormatter() }).Result;
        }

public class TokenError
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
    [JsonProperty("token_type")]
    public string TokenType { get; set; }
    [JsonProperty("expires_in")]
    public int ExpiresIn { get; set; }
    [JsonProperty("refresh_token")]
    public string RefreshToken { get; set; }
    [JsonProperty("error")]
    public string Error { get; set; }
}

 public class Yoda
{ 
    public string email { get; set; }   

    public string password { get; set; }

    public string grant_type
    {
        get
        {
            return "password";
        }
    }
}

The exact error is "No MediaTypeFormatter is available to read an object of type 'TokenError' from content with media type 'text/html'. "

user3140169
  • 221
  • 3
  • 12

1 Answers1

0

After much searching it appears there wasn't much wrong with my code except that the Token endpoint in Web Api doesn't accept json. I was playing in a console app.

    using Newtonsoft.Json;
    using System.Net.Http.Formatting; //Add reference to project.

    static void Main(string[] args)
    {
        string email = "test@outlook.com";
        string password = "Password@123x";

        HttpResponseMessage lresult = Login(email, password);

        if (lresult.IsSuccessStatusCode)
        {
        // Get token info and bind into Token object.           
            var t = lresult.Content.ReadAsAsync<Token>(new[] { new JsonMediaTypeFormatter() }).Result;
        }
        else
        {
            // Get error info and bind into TokenError object.
            // Doesn't have to be a separate class but shown for simplicity.
            var t = lresult.Content.ReadAsAsync<TokenError>(new[] { new JsonMediaTypeFormatter() }).Result;                
        }
    }

    // Posts as FormUrlEncoded
    public static HttpResponseMessage Login(string email, string password)
    {
        var tokenModel = new Dictionary<string, string>{
            {"grant_type", "password"},
            {"username", email},
            {"password", password},
            };

        using (var client = new HttpClient())
        {
            // IMPORTANT: Do not post as PostAsJsonAsync.
            var response = client.PostAsync("http://localhost:53007/token",
                new FormUrlEncodedContent(tokenModel)).Result;

            return response;
        }
    }

      public class Token
    {
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }

        [JsonProperty("token_type")]
        public string TokenType { get; set; }

        [JsonProperty("expires_in")]
        public int ExpiresIn { get; set; }

        [JsonProperty("userName")]
        public string Username { get; set; }

        [JsonProperty(".issued")]
        public DateTime Issued { get; set; }

        [JsonProperty(".expires")]
        public DateTime Expires { get; set; }
    }

    public class TokenError
    {            
        [JsonProperty("error_description")]
        public string Message { get; set; }
        [JsonProperty("error")]
        public string Error { get; set; }
    }
user3140169
  • 221
  • 3
  • 12