【问题标题】:Use Try and Catch in a method to verify HttpWebRequest在方法中使用 Try 和 Catch 来验证 HttpWebRequest
【发布时间】:2019-02-08 03:32:17
【问题描述】:

我正在学习 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;
    }

}

【问题讨论】:

    标签: c# methods return httpwebrequest


    【解决方案1】:

    不要这样做:

    catch (Exception)
    {
        return null;
    }
    

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

    【讨论】:

    • 这似乎是一个过于宽泛和不具体的答案,但我认为这个问题非常基本,一些基本建议可能会有所帮助。
    【解决方案2】:

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

    您应该使用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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-14
        • 2021-08-24
        • 1970-01-01
        • 2023-03-21
        • 2023-01-31
        • 1970-01-01
        • 2019-06-14
        • 1970-01-01
        相关资源
        最近更新 更多