C# 如何捕获/处理WCF中由于类型转换或通过postman调用时向变量传递无效值而发生的异常
我是WCF的初学者。在构建RestFul API时,我面临一些崩溃问题 在我通过WCF处理异常的过程中,我从以下各种来源获得了帮助: 通过实现全局错误处理程序,应用程序的内部异常可以顺利处理(通过在try-catch时钟中处理它们)。但我不知道如何处理铸造异常。即,如果变量获得无效值,则会导致应用程序崩溃的异常 编辑: 我有一个下面的DataContract类C# 如何捕获/处理WCF中由于类型转换或通过postman调用时向变量传递无效值而发生的异常,c#,asp.net,.net,wcf,exception,C#,Asp.net,.net,Wcf,Exception,我是WCF的初学者。在构建RestFul API时,我面临一些崩溃问题 在我通过WCF处理异常的过程中,我从以下各种来源获得了帮助: 通过实现全局错误处理程序,应用程序的内部异常可以顺利处理(通过在try-catch时钟中处理它们)。但我不知道如何处理铸造异常。即,如果变量获得无效值,则会导致应用程序崩溃的异常 编辑: 我有一个下面的DataContract类 using System; using System.Collections.Generic; using System.Compo
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Web;
namespace StilaarAPI.DataContracts
{
[DataContract]
public class Products
{
[DataMember]
[Required(ErrorMessage = "product Name is required")]
[StringLength(50, MinimumLength = 5, ErrorMessage = "Address Feild length should be between 5 and 50")]
public string ProductName { get; set; }
[Required(ErrorMessage = "ProductID is requied")]
[DataMember]
public int ProductID { get; set; }
}
}
下面(支持Ajax的WCF服务使用上述DataContract类作为输入参数)
[运营合同]
[WebInvoke(Method=“POST”,RequestFormat=WebMessageFormat.Json,ResponseFormat=WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.Wrapped)]
公共字符串GetProduct(产品专业版)
{
尝试
{
string test=“一切正常:D”;
回归试验;
//ResultDo result=新的ResultDo();
//var problemTypes=\u riderOrderDeliveryBL.GetProblemType();
}
catch(NotFoundException-ex)
{
NotFoundFault故障=新的NotFoundFault();
fault.Error=“未找到产品”;
fault.StatusCode=HttpStatusCode.NotFound;
抛出新的WebFaultException(
故障,HttpStatusCode.NotFound);
}
}
从邮递员处调用上述服务只需给出简单的结果:
这很好,现在如果我在输入变量上运行不同的输入场景:
从将null值设置为产品名称开始,它给出了以下结果
不错,因为我的验证工作正常,并且异常得到了处理,所以我得到了上面的结果。
现在进入下一个场景,如果我将ID设置为null,则会出现以下输出:
现在,我的问题是如何防止应用程序像这样崩溃:
以下是我的IError处理程序类:
public class GlobalErrorBehaviorAttribute : Attribute, IServiceBehavior
{
private readonly Type errorHandlerType;
/// <summary>
/// Dependency injection to dynamically inject error handler if we have multiple global error handlers
/// </summary>
/// <param name="errorHandlerType"></param>
public GlobalErrorBehaviorAttribute(Type errorHandlerType)
{
this.errorHandlerType = errorHandlerType;
}
#region IServiceBehavior Members
void IServiceBehavior.Validate(ServiceDescription description,
ServiceHostBase serviceHostBase)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription description,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
/// <summary>
/// Registering the instance of global error handler in dispatch behavior of the service
/// </summary>
/// <param name="description"></param>
/// <param name="serviceHostBase"></param>
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description,
ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler;
try
{
errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
}
catch (MissingMethodException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must have a public empty constructor.", e);
}
catch (InvalidCastException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must implement System.ServiceModel.Dispatcher.IErrorHandler.", e);
}
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
#endregion IServiceBehavior Members
}
public class GlobalErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error,System.ServiceModel.Channels.MessageVersion version,ref System.ServiceModel.Channels.Message fault)
{
//if (error is FaultException)
// return;
var jsonError = new CustomFault
{
Error = "Something went wrong",
Details = error.GetType().FullName
};
fault = Message.CreateMessage(version, "", jsonError,
new DataContractJsonSerializer(typeof(CustomFault)));
// Tell WCF to use JSON encoding rather than default XML
var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
// Modify response
var rmp = new HttpResponseMessageProperty
{
StatusCode = HttpStatusCode.BadRequest,
StatusDescription = "Bad Request",
};
rmp.Headers[HttpResponseHeader.ContentType] = "application/json";
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);
}
}
public class ExtendedWebHttpBehavior : WebHttpBehavior
{
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// clear default erro handlers.
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
// add our own error handler.
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new GlobalErrorHandler());
//BehaviorExtensionElement
}
}
公共类GlobalErrorBehaviorAttribute:属性,IServiceBehavior
{
私有只读类型errorHandlerType;
///
///如果我们有多个全局错误处理程序,则使用依赖项注入动态注入错误处理程序
///
///
公共全局错误行为属性(类型errorHandlerType)
{
this.errorHandlerType=errorHandlerType;
}
#区域代理行为成员
无效IServiceBehavior.Validate(服务描述,
服务主机库(服务主机库)
{
}
void IServiceBehavior.AddBindingParameters(服务描述,
ServiceHostBase ServiceHostBase,
集合终结点、BindingParameterCollection参数)
{
}
///
///在服务的分派行为中注册全局错误处理程序实例
///
///
///
无效IServiceBehavior.ApplyDispatchBehavior(服务描述,
服务主机库(服务主机库)
{
IErrorHandler errorHandler;
尝试
{
errorHandler=(IErrorHandler)Activator.CreateInstance(errorHandlerType);
}
捕获(丢失方法异常e)
{
抛出新ArgumentException(“ErrorBehaviorAttribute构造函数中指定的errorHandlerType必须具有公共空构造函数。”,e);
}
捕获(无效卡斯特例外e)
{
抛出新ArgumentException(“ErrorBehaviorAttribute构造函数中指定的errorHandlerType必须实现System.ServiceModel.Dispatcher.IErrorHandler.”,e);
}
foreach(serviceHostBase.ChannelDispatchers中的ChannelDispatcherBase ChannelDispatcherBase)
{
ChannelDispatcher ChannelDispatcher=作为ChannelDispatcher的ChannelDispatcher数据库;
channelDispatcher.errorHandler.Add(errorHandler);
}
}
#末端区域IServiceBehavior成员
}
公共类GlobalErrorHandler:IErrorHandler
{
公共布尔句柄错误(异常错误)
{
返回true;
}
公共默认值(异常错误,System.ServiceModel.Channels.MessageVersion版本,参考System.ServiceModel.Channels.Message故障)
{
//如果(错误为FaultException)
//返回;
var jsonError=new CustomFault
{
Error=“出了问题”,
详细信息=错误。GetType().FullName
};
fault=Message.CreateMessage(版本为“”,jsonError,
新的DataContractJsonSerializer(typeof(CustomFault));
//告诉WCF使用JSON编码而不是默认的XML
var wbf=新的WebBodyFormatMessageProperty(WebContentFormat.Json);
Add(WebBodyFormatMessageProperty.Name,wbf);
//修改响应
var rmp=新的HttpResponseMessageProperty
{
StatusCode=HttpStatusCode.BadRequest,
StatusDescription=“错误请求”,
};
rmp.Headers[HttpResponseHeader.ContentType]=“应用程序/json”;
Add(HttpResponseMessageProperty.Name,rmp);
}
}
公共类扩展WebHttpBehavior:WebHttpBehavior
{
受保护的覆盖无效AddServerErrorHandler(ServiceEndpoint端点、EndpointDispatcher端点Dispatcher)
{
//清除默认错误处理程序。
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
//添加我们自己的错误处理程序。
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(新的GlobalErrorHandler());
//行为扩展元素
}
}
当我将断点设置为提供故障时,它会显示以下异常,好像是因为p
public class GlobalErrorBehaviorAttribute : Attribute, IServiceBehavior
{
private readonly Type errorHandlerType;
/// <summary>
/// Dependency injection to dynamically inject error handler if we have multiple global error handlers
/// </summary>
/// <param name="errorHandlerType"></param>
public GlobalErrorBehaviorAttribute(Type errorHandlerType)
{
this.errorHandlerType = errorHandlerType;
}
#region IServiceBehavior Members
void IServiceBehavior.Validate(ServiceDescription description,
ServiceHostBase serviceHostBase)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription description,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
/// <summary>
/// Registering the instance of global error handler in dispatch behavior of the service
/// </summary>
/// <param name="description"></param>
/// <param name="serviceHostBase"></param>
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description,
ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler;
try
{
errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
}
catch (MissingMethodException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must have a public empty constructor.", e);
}
catch (InvalidCastException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must implement System.ServiceModel.Dispatcher.IErrorHandler.", e);
}
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
#endregion IServiceBehavior Members
}
public class GlobalErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error,System.ServiceModel.Channels.MessageVersion version,ref System.ServiceModel.Channels.Message fault)
{
//if (error is FaultException)
// return;
var jsonError = new CustomFault
{
Error = "Something went wrong",
Details = error.GetType().FullName
};
fault = Message.CreateMessage(version, "", jsonError,
new DataContractJsonSerializer(typeof(CustomFault)));
// Tell WCF to use JSON encoding rather than default XML
var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
// Modify response
var rmp = new HttpResponseMessageProperty
{
StatusCode = HttpStatusCode.BadRequest,
StatusDescription = "Bad Request",
};
rmp.Headers[HttpResponseHeader.ContentType] = "application/json";
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);
}
}
public class ExtendedWebHttpBehavior : WebHttpBehavior
{
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// clear default erro handlers.
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
// add our own error handler.
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new GlobalErrorHandler());
//BehaviorExtensionElement
}
}
?xml version="1.0" encoding="utf-8"?>
<!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="https://localhost:44326/ServiceContracts/CustomerAccount.svc/help">service help page</a> for
constructing valid requests to the service.</p>
</div>
</body>
</html>
{"Id":null,"Name":"Apple"}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
MyError myerror = new MyError()
{
Details = error.Message,
Error = "Hello"
};
fault = Message.CreateMessage(version, "messsagefault", myerror);
}
FaultException faultException = new FaultException(error.Message);
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, error.Message);