【发布时间】: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& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& 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 中定义的对象类型
-
当我有时间尝试测试构建时,我会回到这个问题。希望到那时还有其他人帮助。奇怪的是这里没有其他回应。