使用IParameterInspector验证WCF参数并在客户端处理FaultException

时间:2015-09-28 12:01:27

标签: iphone wcf validation rest parameters

我有一个WCF Rest服务,它在调用实际服务方法之前使用IParameterInspector进行输入参数验证。现在这些休息服务被iPhone消费。如果参数无效,那么我已经抛出了我想在iPhone(或可能是Android)方面处理的错误。 好吧,我在stackoverflow中引用了很多链接,我在下面的代码中使用了以下链接作为参考。

WCF Parameter Validation with Interceptor
以下是我的分步代码段。

=&GT;在FaultException<T>

中使用的FaultExceptionResponse类
[DataContract]
public class FaultExceptionResponse
{
        [DataMember]
        public bool Success { get; set; }

        [DataMember]
        public string ResponseString { get; set; }
}

=&GT;下面的类验证参数。

public class ValidationParameterInspectorAttribute : Attribute, IParameterInspector, IOperationBehavior
    {

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            if (operationName == "GetCommunicationDetailById")
            {
                var communicationChatViewModel = inputs.FirstOrDefault() as CommunicationChatViewModel;

                if (communicationChatViewModel != null &&
                    (communicationChatViewModel.iConsultCommunicationID <= 0))
                {
                    //ErrorLogger.LogErrorMessageToElmah(new ArgumentException("API Name: GetCommunicationDetailById   Parameter cannot be less than zero.", "iConsultCommunicationID"));
                    var fc = new FaultExceptionResponse { Success = false, ResponseString = "Invalid parameter found while fetching communication detail !" };
                    throw new FaultException<FaultExceptionResponse>(fc, new FaultReason(fc.ResponseString));
                }
            }
            return null;
        }

        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.ParameterInspectors.Add(this);
        }

        public void Validate(OperationDescription operationDescription)
        {
        }
    }

=&GT;然后我像这样装饰我的API

[OperationContract]
[ValidationParameterInspector]
[FaultContract(typeof(FaultExceptionResponse))]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "/GetCommunicationDetailById")]
 CommunicationChatDetailList GetCommunicationDetailById(CommunicationChatViewModel communicationParaViewModel);

一切正常但是当参数无效时,在iPhone端抛出此faultException,它只显示以下错误信息。

Error: {
    AFNetworkingOperationFailingURLResponseErrorKey = "<NSHTTPURLResponse: 0x7faa605faa90> { URL: http://192.168.151.40/MyWCF/Service1.svc/GetCommunicationDetailById } { status code: 400, headers {\n    \"Cache-Control\" = private;\n    \"Content-Length\" = 3319;\n    \"Content-Type\" = \"text/html\";\n    Date = \"Fri, 25 Sep 2015 15:45:14 GMT\";\n    Server = \"Microsoft-IIS/7.5\";\n    \"X-AspNet-Version\" = \"4.0.30319\";\n    \"X-Powered-By\" = \"ASP.NET\";\n} }";
    NSErrorFailingURLKey = "http://192.168.151.40/MyWCF/Service1.svc/GetCommunicationDetailById";
    NSLocalizedDescription = "Request failed: bad request (400)";
    NSUnderlyingError = "Error Domain=AFNetworkingErrorDomain Code=-1016 \"Request failed: unacceptable content-type: text/html\" UserInfo={AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x7faa605faa90> { URL: http://192.168.151.40/LKPracooWCF/Service1.svc/GetCommunicationDetailById } { status code: 400, headers {\n    \"Cache-Control\" = private;\n    \"Content-Length\" = 3319;\n    \"Content-Type\" = \"text/html\";\n    Date = \"Fri, 25 Sep 2015 15:45:14 GMT\";\n    Server = \"Microsoft-IIS/7.5\";\n    \"X-AspNet-Version\" = \"4.0.30319\";\n    \"X-Powered-By\" = \"ASP.NET\";\n} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/html, NSErrorFailingURLKey=http://192.168.151.40/LKPracooWCF/Service1.svc/GetCommunicationDetailById
};

我没有找到我的自定义错误消息!!!!现在如果我在高级休息客户端应用程序中测试相同的测试用例,那么我得到了如下所示的自定义错误信息。

Status - 400 Bad Request
<p class="heading1">Request Error</p>
<p>The server encountered an error processing the request. The exception message is 'Invalid parameter found while fetching communication detail !'. See server logs for more details. The exception stack trace is: </p>
<p>......</p>

所以我想要的是如何在客户端(iPhone)端处理这个faultException FaultException<FaultExceptionResponse> ???

2 个答案:

答案 0 :(得分:2)

只需扩展 MattC 给出的答案。非常感谢马特。我发布此详细代码作为答案,仅供未来的读者使用。还有一点,我还在我的博客中写了博客文章 - krishnrajrana.wordpress.com

所以这里的人就是你如何处理客户端的异常(如iPhone设备或Android设备)

public object BeforeCall(string operationName, object[] inputs)
{
    if (operationName == "GetCommunicationDetailById")
    {
        var model = inputs.FirstOrDefault() as TestViewModel;

        if (model != null &&
            (model.iConsultCommunicationID <= 0))
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/json";
            var wfc = new WebFaultException<Response>(new Response(false, "Invalid parameter found while fetching detail !"), System.Net.HttpStatusCode.OK);
            throw wfc;
        }
    }
    else if (operationName == "AnotherMethod")
    {
        ............
    }

    // OR you can use switch case
    switch(operationName)
    {
        Case "Method":
            // your logic
    }

    return null;
}

答案 1 :(得分:1)

问题是你的服务应该返回Json,但异常导致响应内容类型为text / html。您可以使用FaultException删除并切换到WebFaultException并显式设置响应的内容类型。例如:

WebOperationContext.Current.OutgoingResponse.ContentType = "application/json";
var exception = new WebFaultException<string>(
    "{ \"Success\" = \"false\", " + 
    "\"ResponseString\" = \"Invalid parameter found while fetching communication detail !\" }",
    HttpStatusCode.BadRequest);
throw exception;