没有MediaTypeFormatter可用于从媒体类型为“text / html”

时间:2018-01-24 11:03:00

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

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时会抛出此错误?

2 个答案:

答案 0 :(得分:0)

根据MSFT documentation你应该发送没有变量SPId的uri

在这一行:

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

您将带有SPId的内容发送到网址&#34; ... ApiActionName / SPId&#34;但是,应该使用以下内容:

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

最后,您应该调用response.EnsureSuccessStatusCode()以确保响应指示成功(通常为200 OK)。如果情况并非如此,则会引发异常。

最后,api发布[Route("BridgeSP/{SPId}")]

的方法属性

或者this post可以帮助你

答案 1 :(得分:0)

  

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

我打赌你的请求由于错误配置的路由而导致404 HTTP错误失败(见下文)。响应包含带有错误描述的html有效负载。但在客户端,您不检查http错误代码并尝试反序列化响应正文,因为它包含JSON字符串。这就是为什么你得到“没有MediaTypeFormatter可以从媒体类型为string的内容中读取text/html类型的对象”错误。

您必须在代码中进行多项修复才能避免这种情况。

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

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

null的{​​{1}}参数中传递content将发送POST请求 没有身体。

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

SPId

现在可以通过[HttpPost] [Route("BridgeSP/{SPId}")] public HttpResponseMessage Post(long SPId) { // ... 网址访问您的操作了。如果要在URL中保留控制器名称,还应为控制器设置http://localhost/BridgeSP/123属性。有关详细信息,请查看有关attribute routing的文章。

然后在客户端中,您应该在反序列化主体之前检查响应代码。这可以防止你得到你所询问的奇怪异常。最简单的方法是调用Route方法,如果请求结束时会抛出一些HTTP错误。

以下是调整后的客户代码:

HttpResponseMessage.EnsureSuccessStatusCode()

确保在客户端(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; } )配置了正确的API URL。