【问题标题】:Handling parameter parsing errors in WCF service处理 WCF 服务中的参数解析错误
【发布时间】:2014-08-06 15:46:35
【问题描述】:

我有一个 wcf 服务,它接收 DateTime 作为参数。如果日期时间输入不正确,它会返回一个我不想要的 html 页面。有没有办法让它返回一个自定义对象?

例子:

[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetData?DataDate={DataDate})]
Data[] GetData(DateTime DataDate);

因此,例如,如果我在月份编号无效的情况下传递此 url,它会返回一个网页错误,这对通过另一个应用程序发送消息的人没有用。

http://localhost/API/GetData?DataDate=2014-108-06 

回复:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"[]>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Request Error</title>
    <style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style>
  </head>
  <body>
    <div id="content">
      <p class="heading1">Request Error</p>
      <p xmlns="">The server encountered an error processing the request. Please see the <a rel="help-page" href="http://localhost:1234/CheckAPI/help">service help page</a> for constructing valid requests to the service.</p>
    </div>
  </body>
</html>

如果我的代码中出现错误,我会返回一个自定义错误对象,例如:

<Error>
  <ErrorCode>4</ErrorCode>
  <ErrorDescription>No data found for specified date. </ErrorDescription>
</Error>

理想情况下,我希望能够返回错误,例如:

<Error>
  <ErrorCode>5</ErrorCode>
  <ErrorDescription>Error parsing DataDate value.</ErrorDescription>
</Error>

编辑:我已经尝试实现 IErrorHandler 和 IParameterInspector 但这些仅允许我在参数已经验证后处理错误。堆栈跟踪如下:

<ExceptionType>System.FormatException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>String was not recognized as a valid DateTime.</Message>
<StackTrace>
at System.DateTime.Parse(String s, IFormatProvider provider, DateTimeStyles styles)
at System.ServiceModel.Dispatcher.QueryStringConverter.ConvertStringToValue(String parameter, Type parameterType)
at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
</StackTrace>

【问题讨论】:

  • 当 WCF 方法遇到异常时,它会将其包装在 WebFaultException 类中,并为错误设置一个 HttpStatusCode。接收端从 WCF 服务返回适当的异常,从而引发错误,导致您被发送到错误页面。为了解决这个问题,您必须将 TryCatch 块放入 WCF 服务方法中,并返回某种对象。
  • @Ryios 是的,这就是我目前对自定义错误对象所做的事情,但我提供的示例在它到达我的 WCF 服务方法之前会导致异常。
  • 啊,因为参数的输入无效。尝试阅读这篇关于 WCF 服务的输入验证的文章。 msdn.microsoft.com/en-us/library/ff647875.aspx 通过实现 IParameterInspector 并使用 BeforeCall,您可以验证输入,并返回所述响应,或者允许调用。
  • @Ryios 我已经实现了 IParameterInspector,但它仍然像以前一样失败。 BeforeCall 允许我根据自己的条件验证对象,但它仍然需要匹配我的 OperationContract 中定义的对象类型
  • 当我有时间尝试测试构建时,我会回到这个问题。希望到那时还有其他人帮助。奇怪的是这里没有其他回应。

标签: c# wcf parsing exception


【解决方案1】:

当您应用检查器时,您还可以通过反射访问方法:OperationDescription.SyncMethod。 然后您可以检查方法参数并决定如何检查参数。 例如,您可以访问方法参数的自定义属性,并将这些属性传递给您的 ParametersInspectorContructor - 这样您的检查员就会知道如何验证提供的参数。

但无论如何,WCF 都会按以下顺序调用此指令:

internal void InvokeBegin(ref MessageRpc rpc)
{
...
this.InitializeCallContext(ref rpc);
object target = rpc.Instance;
this.DeserializeInputs(ref rpc);
this.InspectInputs(ref rpc);
...

如您所见,检查仅在反序列化后发生,因此您必须提供自己的 Formatter 来处理格式错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 2017-02-28
    • 2015-01-14
    • 1970-01-01
    相关资源
    最近更新 更多