MVC 5身份验证和HttpClient没有MediaTypeFormatter可用

时间:2013-12-19 20:11:20

标签: c# asp.net-mvc authentication asp.net-web-api asp.net-mvc-5

我有一个MVC 5 Web Api和一个连接它的桌面应用程序。

我有一个控制器并从应用程序连接到它没有任何问题,但当我将[Authorize]属性放在控制器中时,桌面应用程序中的httpclient停止工作并说没有MediaTypeFormatter可用。

我认为HttpClient工作正常,我尝试使用请求标头定义身份验证: httpClient.DefaultRequestHeaders.Authorization 并使用这种方式httpclient = new HttpClient(new HttpClientHandler { Credentials = new NetworkCredential("UserName", "password") });

在使用MVC 4的传递中,它适用于身份验证。

在这种情况下,使用MVC 5,它在使用Anonymous时效果很好,但是当我进行身份验证时,我在httpresponse.Content.ReadAsAsync

中得到了这个例外
No MediaTypeFormatter is available to read an object of type 'Dictionary`2' from content with media type 'text/html'.

我应该在哪里看到?

更新

我将httpResponse读作一个字符串,以查看httpclient的内容,并在字符串中输入登录页面的HTML。显然,身份验证失败,MVC + API重定向到登录页面。 我现在应该怎么做? 为什么身份验证不像以前的MVC 4 Web API那样有效?是因为新的OWIN认证吗?

5 个答案:

答案 0 :(得分:1)

这些问题是因为身份验证无效。 MVC5使用Web Forms身份验证,因此我不得不创建一种新方法来验证HttpClient。

  • 进入/帐户/登录页面并阅读_RequestVerificationToken
  • 发布到/帐户/登录UserName,密码和_RequestVerificationToken

错误是因为,当身份验证失败时,MVC5会将HttpClient重定向到Login Page。所以我没有得到JSON,我得到了HTML。登录页面的HTML。

答案 1 :(得分:0)

尝试:

httpClient.Accept =“text / html,application / xhtml + xml,application / json”;

答案 2 :(得分:0)

这篇文章应该会有所帮助。

http://www.asp.net/web-api/overview/security/basic-authentication

它告诉我们,我们需要为Web API实现身份验证处理程序。

我认为Web API是VS2013中独立的项目类型,请确保您没有使用默认情况下使用表单身份验证的MVC。

如果你必须使用整个MVC软件包,那么你必须像登录Ricardo Polo所说的那样在登录页面上创建一个http帖子,然后将你得到的cookie附加到每个api调用。例如:

HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(string.Format("https://{0}/login", server));
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

bool loginSuccess = false;

if (response.StatusCode == HttpStatusCode.OK)
{
    //If there's a cookie in the response, it means login successful, 
    //and the cookie is the one returned by the server that can be used to identify
    //the client when calling Authorized api calls.
    loginSuccess = (response.Cookies.Count > 0);
}
response.Close();

//Now make a request to the api
HttpWebRequest ApiRequest = (HttpWebRequest)System.Net.WebRequest.Create(string.Format("https://{0}/api/values", server));
ApiRequest.CookieContainer = new CookieContainer();
ApiRequest.CookieContainer.Add(response.Cookies[0]);
//From here add code to get the response.

上面的代码可以使用HttpClient完成。

答案 3 :(得分:0)

当我的Action输入参数是Dictionary时,我有异常,我通过创建自定义模型来解决它,该模型包含我的所有输入参数和Dictionary,之后它正在工作

答案 4 :(得分:0)

Visual Studio中的MVC 5 Web API(Web API 2)模板使用基于Token的OWIN中间件进行身份验证。

阅读以下文章:

验证并获取承载令牌 http://www.asp.net/vnext/overview/authentication/individual-accounts-in-aspnet-web-api

In the Fiddler Composer tab, enter the following URL (remember to change "port" to the actual port number):

http://localhost:port/Token

Leave the request method as POST. Change the Content-Type header to application/x-www-form-urlencoded. Replace the request body with the following:

grant_type=password&username=Alice&password=password123

Click Execute to send the request. Here is the raw HTTP request:

POST http://localhost:49436/Token HTTP/1.1
User-Agent: Fiddler
Host: localhost:49436
Content-Type: application/x-www-form-urlencoded
Content-Length: 55

grant_type=password&username=Alice&password=password123

在MVC 5 Web API模板中,您可以启用基于cookie的身份验证,但要获得Authenticated,您需要通过发送带有三个字段的表单主体的Http Post消息来使用/ Token端点1. grant_type 2. username 3. password 。

在回复此消息时,您将获得一个JSON对象,您可以在其中找到access_token(如果您不想使用基于令牌的授权,则可以忽略),如果配置了使用cookie身份验证,服务器将设置cookie(默认)。默认情况下,从ApiControllers派生的控制器不会在某些VS模板中使用cookie身份验证。您需要存储access_token并将其放在ApiController的所有进一步请求的标头中。 Http标题应该是这样的: Authorization: Bearer [place_accesstoken_without_sorrunding_braces]