在方法中使用Try和Catch来验证HttpWebRequest

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在方法中使用Try和Catch来验证HttpWebRequest相关的知识,希望对你有一定的参考价值。

我正在学习C#,这个类我从API获取JSON信息,然后从我调用我的类“MyClass”的表单中将值放在相应的字段中,但我不知道如何检测是否与API不成功,我知道必须使用try和catch,这就是为什么我把它放在我的“MyClass”类中,但我不知道如何正确地进行验证:

我有这些定义的类:

public class Lawyer
{
    public string type { get; set; }
    public string numdoc { get; set; }
    public string name { get; set; }
    public string date { get; set; }
}

public class Worker
{
    public string time { get; set; }
    public string service { get; set; }
}

public class Result
{
    public string id { get; set; }
    public string name { get; set; }
    public string Condition { get; set; }
    public string PLE { get; set; }
    public List<Lawyer> lawyers { get; set; }
    public List<Worker> workers { get; set; }
}

public class RootObject
{
    public bool success { get; set; }
    public Result result { get; set; }
}

它是我的“MyClass”(我尝试使用“try”和“catch”但我不知道这是否是正确的方法...):

class MyClass 
{
    public RootObject MyMethod(int inRUC){
  try {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"https://www.example.com/api/?get=" + inRUC);
        HttpWebResponse response;

        response = (HttpWebResponse)request.GetResponse();
        Stream stream = response.GetResponseStream();
        StreamReader reader = new StreamReader(stream);
        {
            var json = reader.ReadToEnd();
            return JsonConvert.DeserializeObject<RootObject>(json);
        }
      }
  catch (Exception)
        {
         return null;
        }
    }
}

这是我的表单中调用类的部分,它工作正常,但我不知道如何从这里验证与API的连接是否成功:

private void Button1_ClickBefore(object sboObject, SAPbouiCOM.SBOItemEventArg pVal, out bool BubbleEvent)
{
    if (string.IsNullOrEmpty(txtRuc1.Value.ToString()))
    {
        BubbleEvent = false;
    }
    else
    {
        BubbleEvent = true;

        int para = 0;
        int.TryParse(txtRuc1.Value, out para);

        MyClass obj = new MyClass();
        EditText1.Value = obj.MyMethod(para).result.name;
    }

}
答案

不要这样做:

catch (Exception)
{
    return null;
}

这将简单地“吞下”任何运行时错误。如果连接失败,obj.MyMethod(para).result.name;会给你一个NullpointerException,它不会告诉你到底出了什么问题。而是看看“MyMethod”中可能出现的问题以及可能导致的特定异常。只捕获您知道如何处理的异常。如果您(还)不知道如何处理特定异常,请不要抓住它。这将导致程序崩溃,并显示一些有意义的错误消息。从那里开始工作。尝试一下您可以提出的所有内容以使连接失败并观察抛出哪些异常,这样您就可以想出一种方法来防止这些情况或从中恢复。

另一答案

你的疑问是正确的。在您的情况下,这不是处理异常的正确方法。

您应该使用WebException,这将使您有机会阅读服务器发送的响应。在这里,您可以检查从API收到的错误响应的详细信息并采取适当的措施。以下是示例代码供您参考。您可以根据需要进行调整。

        catch (WebException e)
        {
            using (WebResponse response = e.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse)response;
                Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
                using (Stream data = response.GetResponseStream())
                {
                    string text = new StreamReader(data).ReadToEnd();
                    Console.WriteLine(text);
                }
            }
        }

您可以从这里获得有关WbeException的更多详细信息:https://docs.microsoft.com/en-us/dotnet/api/system.net.webexception?view=netframework-4.7.2

还有一些代码示例的详细信息:https://docs.microsoft.com/en-us/dotnet/framework/network-programming/handling-errors

另一答案

您不应仅为方法创建类。您可以将此方法放在UI事件处理程序旁边 - 如果仅在那里使用它。或者为所有API调用创建一个静态帮助器类 - 如果您在调用之间重用某些内容(如cookie),则不是静态的。但是然后为整个UI或最多为表单创建一个实例。

请注意,API调用可能在技术上成功,您仍然会收到错误消息。在尝试反序列化之前检查StatusCode property。如果存在网络或http级问题,您很可能会获得IOExceptionWebException。如果服务器代码出错或您传递了无效参数,您将获得不同于200的状态代码(OK) - 还有其他成功状态代码。但是你也可以获得内容解析异常。始终记录此类异常,即使是暂时的,但永远不会只是注意到它!

但我建议你使用HttpClient class而不是HttpContentExtensions methods。有许多优点,因为它针对API调用进行了优化,并且支持所有操作的异步。后一个包使用任何方法读取或发送时都可以轻松处理自定义对象。请注意,HttpClient实例甚至是跨线程的optimized可重用性 - 因此您的应用程序中只能有一个或几个。不幸的是,我没有在本主题中找到任何完整的教程来链接。

以上是关于在方法中使用Try和Catch来验证HttpWebRequest的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 try 和 catch 处理 axios 中的 404 错误

捕获异常

在 C++ 和 C# 中使用 try/catch 的正确方法是啥? [复制]

如何在 JS 中使用 try、catch、.then 链接和异步等待来解决承诺?

异常-笔记-01

try-catch的使用以及细节