简体   繁体   English

当对象属性不正确时,Wcf(400)Bad Request

[英]Wcf (400) Bad Request when object properties are incorrect

I have a Wcf (ajax enabled) service, that accepts a object for the method call. 我有一个Wcf(启用ajax)服务,它接受方法调用的对象。 My Wcf method looks like this; 我的Wcf方法看起来像这样;

[OperationContract]
[XmlSerializerFormat]
[WebInvoke(Method = "POST", UriTemplate = "/XML/GetTypes", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml)]
XElement XMLGetTypes(TypeRequest TypeRequest)
{
    return Utilities.Convert.ObjectToXElement(TypeRequest.Execute(TypeRequest));
}

The 'TypeRequest' object is as follows; 'TypeRequest'对象如下;

public class
{
    public int Id {get;set;}
    public string Name {get; set;}
}

The problem I'm having is that if I call the method with invalid data like in the request object like; 我遇到的问题是,如果我在请求对象中调用带有无效数据的方法,比如;

<TypeRequest>
<Id>abc</Id>
<Name>Joe King</Name>
</TypeRequest>

As you can see the Id should be a integer, however it is being passed as a string. 正如您所看到的,Id应该是一个整数,但它是作为字符串传递的。 This causes a Bad Request 400 response from the Wcf service. 这导致来自Wcf服务的错误请求400响应。

Ideally I'd like to handle the error, and return a suitable response. 理想情况下,我想处理错误,并返回一个合适的响应。 For example I'd like to return either a JSON or XML response containing the error information. 例如,我想返回包含错误信息的JSON或XML响应。

Is this possible ? 这可能吗 ?

IIS allows you to create error handlers overall in the pipeline. IIS允许您在管道中创建整体错误处理程序。 How you handle the code and what you return is up to you, though I would be careful, as this handles all the errors for an IIS application. 你如何处理代码和你返回的内容取决于你,虽然我会小心,因为它处理IIS应用程序的所有错误。

public class ErrorHttpHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString.Count == 0)
                return;

            string strStatusCode = context.Request.QueryString[0].Split(';').FirstOrDefault() ?? "500";
            int statusCode = 500;
            int.TryParse(strStatusCode, out statusCode);

            string message = "Unhandled server error.";

            switch (statusCode)
            {
                case 400:
                    message = "Bad request.";
                    break;

                case 404:
                    message = "Item not found.";
                    break;
            }

            context.Response.StatusCode = statusCode;
            context.Response.Write(string.Format("<Error><Message>{0}</Message></Error>", message));
        }
    }

and in your web.config, add this code for the handler to be called: 并在您的web.config中,为要调用的处理程序添加此代码:

<system.webServer>
    <httpErrors errorMode="Custom">
      <clear/> 
      <error statusCode="404" path="/application/ErrorHandler" responseMode="ExecuteURL"/>
      <error statusCode="400" path="/application/ErrorHandler" responseMode="ExecuteURL"/>
    </httpErrors>
    <handlers>
      <add name="ErrorHandler" path="ErrorHandler" verb="*" type="Your Application.ErrorHttpHandler, FrameworkAssembly"/>
    </handlers>
  </system.webServer>

All of this was culled from this site . 所有这一切都是从这个网站上挑选出来的。

You can check your parameter using parameter inspector, which will allow you to throw fault exception with the message you need. 您可以使用参数检查器检查参数,这将允许您使用所需的消息引发故障异常。 Also you can provide your client (if it's .net client) with you Parameter inspector attribute. 您也可以使用参数检查器属性为您的客户端(如果它是.net客户端)提供。 As a result the message will not be send till it pass validation, which can save you traffic. 因此,在通过验证之前不会发送消息,这可以节省流量。 Here is a link: WCF Parameter Validation with Interceptor 这是一个链接: 使用Interceptor进行WCF参数验证

And in case your client send you a wrong message. 如果您的客户发送错误信息。 You have to use message inspector: MSDN , Logging all WCF messages 您必须使用消息检查器: MSDN记录所有WCF消息

Here is even better example: http://msdn.microsoft.com/en-us/library/ff647820.aspx 这是更好的例子: http//msdn.microsoft.com/en-us/library/ff647820.aspx

You have to put more attention for methods AfterReceiveRequest. 你必须更多关注AfterReceiveRequest方法。 Please notice that it's required to create a buffered copy of the message, then work with one copy of a message, and return another one. 请注意,需要创建消息的缓冲副本,然后使用消息的一个副本,然后返回另一个消息。

it is possible to do this but you may need to do it a little differently, the easiest way may be to alter your incoming Type request as follows 可以这样做,但您可能需要稍微改变一下,最简单的方法可能是更改您的传入类型请求,如下所示

public IncomingClass
{
    public string Id {get;set;}
    public string Name {get; set;}
}

this will mean that the incoming data is valid, and you won't get the error 400, 这意味着传入的数据是有效的,你不会得到错误400,

you can then validate this using 然后,您可以使用

int myId = incomingClass.Id as int;

if (myId == null)
{
//put suitable error handling here
}

or perhaps better still stick the whole function in a try catch loop, and handle the error that way. 或者更好的是仍然将整个函数粘贴在try catch循环中,并以这种方式处理错误。 I think you will find the error is happening before you are entering your function. 我想你会在输入功能之前发现错误。 your WCF Service is expecting xml that can be translated to the type of Object "TypeRequest" but your xml is invalid. 您的WCF服务期望xml可以转换为Object“TypeRequest”的类型,但您的xml无效。

Hope that helps 希望有所帮助

I think you would need some method interceptors and write the expected logic in there. 我认为你需要一些方法拦截器并在那里写出预期的逻辑。

Here's a good resource on that http://msdn.microsoft.com/en-us/magazine/cc163302.aspx 这是一个很好的资源http://msdn.microsoft.com/en-us/magazine/cc163302.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM