.net HTTP客户端-系统发生异常-服务器状态代码500

vsdwdz23  于 2023-02-06  发布在  .NET
关注(0)|答案(1)|浏览(208)

下面是我的WCF服务契约,其中一个方法签名:

[WebInvoke(UriTemplate = "", Method = "POST")]
public InventoryResponse Post(InventoryRequest inventoryRequest)
{

这个REST端点在fiddler中工作,当我向该端点发出POST请求时,我成功地取回了json:
我要发布到的终结点:http://localhost/Inventory/

标题:

然而,这并没有,它试图调用同一个网址。我最终得到了一个500服务器端的错误,在respnse说“内部服务器错误”,这可能意味着一些代码失败,但然后怎么来的fiddler调用工程...似乎这并不加起来。

using (var client = new HttpClient())
    {
        var postUri= "http://localhost/Inventory/";
        client.BaseAddress = new Uri(postUri);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        inventoryResponse = client.PostAsJsonAsync("", inventoryRequest).Result.Content.ReadAsAsync<InventoryResponse>().Result;

    }

这个错误表示我认为我没有从服务中获取一个json对象:

System.Net.Http.UnsupportedMediaTypeException: No MediaTypeFormatter is available to read an object of type 'InventoryResponse' from content with media type 'text/html'.

System.AggregateException: One or more errors occurred. ---> System.Runtime.Serialization.SerializationException: Error in line 1 position 70. Expecting element 'InventoryPostResponse' from namespace 'http://schemas.datacontract.org/2004/07/EventInventory.Applications.WebService.Jetson.Responses.BulkPosting'.. Encountered 'Element'  with name 'Fault', namespace 'http://schemas.microsoft.com/ws/2005/05/envelope/none'.
8ehkhllq

8ehkhllq1#

    • 编辑1:**

似乎是HTTPClient的一些限制,我终于为自己解决了一个问题,以下是我的建议:
1.更改服务合同中的UriTemplate:

[WebInvoke(UriTemplate = "Inventory", Method = "POST")]
public InventoryResponse Post(InventoryRequest inventoryRequest)

1.将终结点地址更改为

http://localhost

1.再次尝试使用HTTPClient访问该服务:

using (var client = new HttpClient())
{
    var postUri= "http://localhost/";
    client.BaseAddress = new Uri(postUri);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    inventoryResponse = client.PostAsJsonAsync("Inventory", inventoryRequest).Result.Content.ReadAsAsync<InventoryResponse>().Result;

}

最后,它应该起作用了。

    • 上一个答案:**

您的客户端没有发送正确的请求,服务器期望xml,但客户端发送了其他内容(似乎是json,内容类型是文本)。
1.您可以使用稍有不同的方式在客户端上进行调用:在客户端库中引用服务接口和数据契约(不应该有服务实现,但如果是为了测试,也可以),并将代码替换为:

ChannelFactory<YourServiceInterface> myChannelFactory = new ChannelFactory<YourServiceInterface>("MyService"); //MyServive clinet endpoint name

// Create a channel.
YourServiceInterface wcfClient1 = myChannelFactory.CreateChannel();
var resp = wcfClient1.Post(inventoryRequest);

((IClientChannel)wcfClient1).Close();

如果你关心异步操作,你可以用TPL,用一个任务

  1. Fiddler有一个选项可以捕获来自其他客户端的每个请求。这样做并向我们发送请求和响应的内容。
    1.这肯定是你的客户端有问题。你可以试试这个代码,它必须工作(它为我工作,我已经检查):
public class WebRequestor
{
    public void MakeCall(DividendEvents dividends, Uri uri)
    {
        var postData = Serialize(dividends);
        var request = FormWebRequest(postData, uri);

        var response = request.GetResponse();

        Console.WriteLine(((HttpWebResponse)response).StatusDescription);
        var dataStream = response.GetResponseStream();
        var reader = new StreamReader(dataStream);

        // Read the content of response, if you need to have to deserialize it (in the same way as Serialize method does serialization)
        string responseFromServer = reader.ReadToEnd();

        reader.Close();
        dataStream.Close();
        response.Close();
    }

    private static WebRequest FormWebRequest(string postData, Uri uri)
    {
        WebRequest request = WebRequest.Create(uri);
        request.Method = "POST";
        request.ContentType = "application/json";

        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        request.ContentLength = byteArray.Length;
        // Get the request stream.
        Stream dataStream = request.GetRequestStream();
        // Write the data to the request stream.
        dataStream.Write(byteArray, 0, byteArray.Length);
        // Close the Stream object.
        dataStream.Close();
        return request;
    }

    private static string Serialize(object data)
    {
        var stream1 = new MemoryStream();
        var testSer = new DataContractJsonSerializer(data.GetType());
        testSer.WriteObject(stream1, data);
        stream1.Seek(0, SeekOrigin.Begin);
        var sreader = new StreamReader(stream1);
        var cont = sreader.ReadToEnd();
        return cont;
    }
}

下面是实际调用:

var div = new DividendEvents() {Events = new[] {1, 2, 3}, Id = "GOOGL"};
        new WebRequestor().MakeCall(div, new Uri("http://localhost:9002/Pricing/Dividends"));

相关问题