指示服务器请求失败的最佳实践方法?我正在编写一个连接到服务的API,该服务要么返回简单的“成功”消息,要么返回100多种不同类型的失败之一。本来我想写一个方法,向这个服务发送请求,如果成功了,这个方法什么都不返回,但是如果由于某种原因失败了,就会抛出异常。我不太介意设计,但另一方面,就在今天,我正在阅读JoshuaBloch的“HowtoDesignaGoodAPIandWhyItMatters”,他在其中说“抛出异常以指示特殊条件.......不要强迫客户使用异常来控制流程。(和“相反,不要默默地失败。”)另一方面,我注意到我正在使用的HttpWebRequest似乎在请求失败时抛出异常,而不是返回包含“500InternalServerError”的返回“信息。在这种情况下报告错误的最佳模式是什么?如果我对每个失败的请求都抛出异常,我会在未来的某个时候感到巨大的痛苦吗?编辑:非常感谢到目前为止的回复。一些改进:编辑第二:基本上我不完全相信使用这两种方法中的哪一种:尝试{ChargeCreditCard(cardNumber,expDate,hugeAmountOMoney);}catch(ChargeFailExceptione){//客户端根据特定异常类型指定的失败类型处理错误}或varstatus=TryChargeCreditCard(cardNumber,expDate,hugeAmountOMoney);if(!status.wasSuccessful){//客户端根据状态中指定的失败类型处理错误}例如,当用户尝试从信用卡中扣款时,卡被拒绝真的是一种特殊情况吗?我开始问这个问题,我是不是在兔子洞里走得太远了?这是要考虑的事项的简短列表。虽然不全面,但我相信这些东西可以帮助您编写更好的代码。底线:异常处理不一定被认为是邪恶的。相反,在写作时问问自己:我如何真正理解我正在解决的问题?通常,这会帮助您成为更好的开发人员。其他开发人员可以阅读吗?一般开发者能合理理解吗?示例:ServiceConnectionException与令人困惑的ServiceDisconnectedConnectionStatusException抛出异常时的情况有多特殊?调用者必须做什么才能实现该方法?这个异常是致命的吗?如果捕获到此异常,是否可以对其执行任何操作?线程中止,内存不足......你不能做任何有用的事情。不要抓住它。异常令人困惑吗?假设您有一个名为CarGetCarFromBigString(stringdesc)的函数,它接受一个字符串并返回一个Car对象。如果此方法的大多数用例是从该字符串生成Car对象,则当无法从该字符串确定Car时不要抛出异常。相反,编写一个类似boolTryGetCarFromBigString(stringdesc,outCar)的方法。这可以很容易地预防吗?假设数组或变量的大小为空,我可以检查吗?为了代码可读性,让我们看看您的上下文。布尔IsServiceAlive(){布尔连接=假;//bool总是被初始化为false,但是为了在这个上下文中的可读性,try{//一些检查Service.Connect();连接=真;}catch(CouldNotConnectToSomeServiceException){//做你需要做的事}returnconnected;}//或者voidIsServiceAlive(){try{//一些检查Service.Connect();}catch(CouldNotConnectToSomeServiceException){//做你需要做的事throw;}}staticvoidMain(string[]args){//sample1if(IsServiceAlive()){//dosomething}//sample2try{if(IsServiceAlive()){//dosomething}}catch(CouldNotConnectToSomeServiceException){//在这里处理}//示例3try{IsServiceAlive();//work}catch(CouldNotConnectToSomeServiceException){//handlehere}}你可以在上面看到,如果上下文只是一个二进制测试,那么示例3中的CouldNotConnectToSomeServiceException会被捕获并且不一定会导致更好的可读性。但是,两者都有效。但真的有必要吗?如果无法连接,您的程序会被擦除吗?这到底有多重要?这些都是你需要考虑的因素。很难说,因为我们无法访问您的所有代码。让我们看看其他一些最有可能导致问题的选项。//当你必须进行50次字符串比较时,代码看起来如何?不漂亮或可扩展。公共类ServiceConnectionStatus{公共字符串描述{get;放;}}和//你的代码在添加了50个之后会怎样?publicenumServiceConnectionStatus{Success,Failure,LightningStormAtDataCenter,UniverseExploded}我认为您需要在设计中考虑一些事项:1)您将如何访问API?如果您通过Web服务公开它,抛出异常可能不是一个好主意。如果API在您提供给人们在他们的应用程序中引用的DLL中,则异常可能没问题。2)为了使失败响应对API使用者有用,需要将多少额外数据与返回值一起传输?如果您需要失败消息中可用的信息(即用户ID和登录名)而不是嵌入该信息的字符串,那么您可以使用自定义异常或包含错误代码和其他可用信息的“ErrorEncountered”类。如果您只需要传回代码,则代表成功(0)或失败(任何非零值)的ENum可能是合适的。3)在原始响应中忘记了这一点:.Net框架中的异常是昂贵的。如果您的API将偶尔被调用一次,则无需考虑它。但是,例如,如果为高流量站点中提供的每个网页调用API,您绝对不希望抛出异常以指示请求失败。所以简短的回答是,这真的取决于。我非常喜欢“抛出异常以表明特殊情况”的想法。他们必须有这个名字是有原因的。在常规应用程序中,您可以在File.Open()之前使用File.Exists()以防止抛出异常。由于异常难以处理,因此会出现错误。但是,在客户端-服务器环境中,您可能希望避免发送两个请求并创建一个FileOpenResponse类来发送状态和数据(例如本例中的文件句柄)。以上就是C#学习教程:提示服务器请求失败的最佳实践方法?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
