【问题标题】:No MediaTypeFormatter is available to read an object of type `string` from content with media type `text/html`没有 MediaTypeFormatter 可用于从媒体类型为“text/html”的内容中读取“字符串”类型的对象
【发布时间】:2018-07-03 09:42:12
【问题描述】:

HttpClient:

public string BridgeSP(long SPId)
{
    using (var client = new HttpClient())
    {

        ReadConfig();

        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", GenerateAuthenticationToken());
        client.BaseAddress = new Uri(ApiBaseUrl);

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        //HTTP POST
        var responseTask = client.PostAsJsonAsync(ApiActionName + "/" + SPId, SPId);
        responseTask.Wait();

        var result = responseTask.Result;
        var readTask = result.Content.ReadAsAsync<string>();
        readTask.Wait();
        response = result.StatusCode + "|" + readTask.Result;
    }
    return response;
}

WebApi:

[BasicAuthenticationAttribute]
[ActionName("BridgeSP")]
[System.Web.Http.HttpPost]
public HttpResponseMessage Post(long SPId)
{
    try
    {
        Utility.QBUpdateVendor(SPId);
        return Request.CreateResponse(HttpStatusCode.OK, "SP Bridged Successful ");
    }
    catch(Exception ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message.ToString());
    }
}

WebApiConfig.cs:

config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

为什么在调用 web api 时会抛出这个错误?

【问题讨论】:

标签: asp.net-web-api asp.net-web-api2


【解决方案1】:

为什么在调用 web api 时会抛出这个错误?

我敢打赌,由于路由配置错误,您的请求会因 404 HTTP 错误而失败(见下文)。响应包含带有错误描述的 html 有效负载。但是在客户端,您不会检查 http 错误代码并尝试反序列化响应正文,因为它包含 JSON 字符串。这就是为什么您会收到“No MediaTypeFormatter is available to read an object of type of string from content with media type text/html”错误的原因。

您必须在您的代码中进行一些修复以避免这种情况。

首先,您尝试在 URL 和请求正文中传递 SPId。虽然有可能,但最好避免这种冗余。您应该选择是要在 URL 中还是在正文中传递此 id。对于标识资源的单个数字参数,最好传入 URL,因为它符合 REST 原则。这是客户端的适当更改:

var responseTask = client.PostAsync(ApiActionName + "/" + SPId, null);

PostAsynccontent 参数中传递null 将发送POST 请求 没有身体。

您还应该调整您的服务器部分。您必须指定路由,以便可以从请求 URL 中提取 SPId 的值:

[HttpPost]
[Route("BridgeSP/{SPId}")]
public HttpResponseMessage Post(long SPId)
{
    //  ...

现在可以通过http://localhost/BridgeSP/123 URL 访问您的操作。如果要在 URL 中保留控制器名称,还应该为控制器设置 Route 属性。查看这篇关于attribute routing的文章了解更多详情。

然后在客户端中,您应该在反序列化正文之前检查响应代码。这将防止您遇到您询问的奇怪异常。最简单的方法是调用 HttpResponseMessage.EnsureSuccessStatusCode() 方法,如果请求完成并出现一些 HTTP 错误,该方法将抛出。

这里是调整后的客户端代码:

public string BridgeSP(long SPId)
{
    using (var client = new HttpClient())
    {

        ReadConfig();

        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", GenerateAuthenticationToken());
        client.BaseAddress = new Uri(ApiBaseUrl);

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        //HTTP POST
        var responseTask = client.PostAsync(ApiActionName + "/" + SPId, null);
        var result = responseTask.Result;
        //  This will throw if request finished with some HTTP error
        result.EnsureSuccessStatusCode();

        var readTask = result.Content.ReadAsAsync<string>();
        readTask.Wait();
        response = result.StatusCode + "|" + readTask.Result;
    }
    return response;
}

确保在客户端 ("/BridgeSP" + "/" + SPId) 配置了正确的 API URL。

【讨论】:

    【解决方案2】:

    根据MSFT documentation,您应该发送不带变量 SPId 的 uri

    在这一行:

    var responseTask = client.PostAsJsonAsync(ApiActionName + "/" + SPId, SPId);
    

    您将带有SPId 的内容发送到网址“...ApiActionName/SPId”,但是,应该使用如下内容:

    var response = httpClient.PostAsJsonAsync(String.Format("{0}/{1}", controller, action), request).Result;
    

    最后,您应该调用 response.EnsureSuccessStatusCode() 以确保响应指示成功(通常为 200 OK)。如果不是这样,它会引发异常。

    最后还有一个属性到 api 发布 [Route("BridgeSP/{SPId}")]

    或者this post 可以帮助你

    【讨论】:

      猜你喜欢
      • 2018-05-29
      • 1970-01-01
      • 2012-09-12
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-26
      相关资源
      最近更新 更多