Search code examples
c#odatahttpwebrequestwebexception

How to catch ODataErrorException when I am making an OData call through HttpWebRequest in C#?


I am trying to call an OData service from my .Net console application using c#. I am using HttpWebRequest to make the call.

Now if there is an OData specific error, for example, an invalid JSON payload, then an ODataErrorException is thrown from the OData server.

My question is how to catch that ODataErrorException and extract the proper message out of it? The exception gets caught in WebException catch block, and it only shows me "400 Bad Request". But it doesn't show me the actual error reason. If I make the same call through, say Postman, then it gives me a proper exception result.

My Code:-

                byte[] byteArray;
                Stream requestDataStream;
                WebResponse webResponse;
                Stream dataStream;
                StreamReader reader;

                string ODataUrl = "https://someodata.com/data/someentity";

                string jsonPayloadData = "{,\"Key1\":\"Value1\",\"Key2\":\"Value2\",\"Key3\":\"Value3\"}";   /*** a deliberate comma is placed at the start ***/

                byteArray = System.Text.Encoding.UTF8.GetBytes(jsonPayloadData);

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(ODataUrl);
                request.Method = "POST";
                request.ContentType = "application /json;charset=utf-8";
                request.Accept = "application /json";
                request.Headers.Add("Authorization", authHeader);
                request.ContentLength = byteArray.Length;
                requestDataStream = request.GetRequestStream();

                requestDataStream.Write(byteArray, 0, byteArray.Length);
                requestDataStream.Close();

                webResponse = request.GetResponse();
                string desc = ((HttpWebResponse)webResponse).StatusDescription;
                // Get the stream containing content returned by the server.  
                dataStream = webResponse.GetResponseStream();
                // Open the stream using a StreamReader for easy access.  
                reader = new StreamReader(dataStream);
                // Read the content.  
                string jsonData = reader.ReadToEnd();
                Console.WriteLine(jsonData);
                Console.ReadLine(); 
            }
            catch(ODataErrorException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (WebException ex)
            {
                /**** I want to get an ODataErrorException here ****/
                while(ex != null)
                {
                    string message = ex.Message;
                    Console.WriteLine(message);
                    ex = (WebException)ex.InnerException;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

This will throw an exception (beacuse of the redundant comma in the payload) which comes to the WebException catch block. But it gives me only "400 Bad Request". But I want to get the actual exception reason, just like Postman.

The same request from Postman gives me this:-

{
"error": {
    "code": "",
    "message": "An error has occurred.",
    "innererror": {
        "message": "Invalid property identifier character: ,. Path '', line 1, position 1.",
        "type": "Newtonsoft.Json.JsonReaderException",
        "stacktrace": " ...some long stack ..."
    }
}}

Solution

  • Try below code in your catch block:

            catch (WebException webEx)
            {
                if (0 != webEx.Response.ContentLength)
                {
                    using (var stream = webEx.Response.GetResponseStream())
                    {
                        if (null != stream)
                        {
                            using (var reader = new StreamReader(stream))
                            {
                                var errorMsg = reader.ReadToEnd();
                            }
                        }
                    }
                }
            }