Invalid request handling in OData - c#

Im writing an OData webservice with C# and I need some advice on how to handle invalid requests? An example of an error would be if a customer requested a service on an item they no longer own. I would idealy like to report back to the customer exactly why it is invalid as there are multiple possible reasons.
Many thanks

I would recommend using FaultContracts as part of the OperationContract. You can define them just like DataContracts, and handle exceptions just like a custom exception.
[OperationContract]
[FaultContract(typeof(ItemNotOwned))]
Item GetItem(int ItemId);
You would define ItemNotOwned as a seperate contract definition.
Check it out on MSDN: http://msdn.microsoft.com/en-us/library/ms733841.aspx#Y323

Just throw an exception with the message containing that information. The exception will be serialized to the response sent to the client. If you don't care about the response status code, any exception will do and the client will recieve 500 (Internal Server Error). If you want a specific status code throw an instance of DataServiceException.

Look at using QueryInterceptors and ChangeInterceptors
http://robbincremers.me/2012/01/24/wcf-rest-service-with-odata-and-entity-framework-with-client-context-custom-operations-and-operation-interceptors/

Related

SignalR Client - Handler for message that contains no event name?

I am coding a SignalR Hub Client to get data from a web-service, and for one of the more important methods I am invoking on their server, the message I get back contains no "M: eventName" line of the sort I am using to handle the other message types (just "R:[Data] and I:[0]"). I can see the message data is all there when I enable Tracing, but how do I go about handling this with no eventName?
example:
`HubProxy.On<DataClass>("???event-name-here???", update => Console.WriteLine("OUTPUT");`
Message Trace:
23:02:34.9119843 - e1ef32d1-d374-4d7d-82b4-011d906cb096 - WS: OnMessage({"R":{"MarketName":null,"Nounce":136096,"Buys":[{"Quantity":1261.89236694,"Rate":0.00567987},{"Quantity":17.66436734,"Rate":0.00565000},{"Quantity":0.35424250,"Rate":0.00564585},{"Quantity":148.53138590,"Rate":0.00564100},{"Quantity":114.03031557,"Rate":0.00564000},{"Quantity":823.55802148,"Rate":0.00563998},{"Quantity":92.11307737,"Rate":0.00563997},{"Quantity":439.17714798,"Rate":0.00563990},{"Quantity":35.46237619,"Rate":0.00563978},{"Quantity":380.42279579,"Rate":0.00563777},{"Quantity":308.83819198,"Rate":0.00563600},{"Quantity":0.10951077,"Rate":0.00563433},{"Quantity":0.35548667,"Rate":0.00562609},{"Quantity":11.23857359,"Rate":0.00562082},{"Quantity":2.69321221,"Rate":0.00562011},{"Quantity":0.99414299,"Rate":0.00561891},{"Quantity":24.41591498,"Rate":0.00561500},{"Quantity":0.35673516,"Rate":0.00560640},{"Quantity":2.66949153,"Rate":0.00560500},{"Quantity":38.31222855,"Rate":0.00560000},{"Quantity":17.84436494,"Rate":0.00559000},{"Quantity":208.91357967,"Rate":0.00557050},{"Quantity":0.89792884,"Rate":0.00556837},{"Quantity":6.28868665,"Rate":0.00556555},{"Quantity":178.86139272,"Rate":0.00556301},{"Quantity":304.80171408,"Rate":0.00556300},{"Quantity":0.56409118,"Rate":0.00556122},{"Quantity":11.57184239,"Rate":0.00556069},{"Quantity":0.19164392,"Rate":0.00555933},{"Quantity":3.00000000,"Rate":0.00555560},{"Quantity":1579.01........
It looks like that message is not a client-invocation (what you are calling an "event") but the return value of a server call.
To use return values; use Invoke<T> instead of Invoke on the IHubProxy object.

Why does HttpResponseException only allow its message to be read async?

I'm writing a unit test method that exercises code that, under the conditions of my test, is expected to throw an HttpResponseException with a specific response message.
The relevant portion of my test method code looks like this:
try
{
MyClassBeingTested.MyWebServiceMethodBeingTested(myParameters);
}
catch (HttpResponseException ex)
{
string errorMessage = await ex.Response.Content.ReadAsStringAsync();
Assert.IsTrue(errorMessage.Contains("My expected error message string"));
return;
}
Assert.Fail("Expected HttpResponseException didn't get thrown");
This code works, and the test passes.
However, I'd like to better understand understand why my code that reads the error message needs to be constructed this way. The HttpResponseException class only provides async access to its message. I therefore needed to get the message via ReadAsStringAsync(), instead of just being able to synchronously get the message by doing something like ex.Response.Content.Message.
I feel like I might be missing something about why the HttpResponseException class works the way it does. What is the reason that HttpResponseException does not provide synchronous access to its response message?
The HttpResponseException class only provides async access to its message.
HttpResponseException provides you synchronous access to the HTTP response message (Response), which provides you synchronous access to its content (Content). The content of an HTTP stream is what is always read asynchronously. In some uses, the content of an HTTP stream is fully existing in-memory by the time it's used; in other uses, the content of an HTTP stream is streamed over the network.
E.g., if you make an HTTP request with HttpCompletionOption.ResponseHeadersRead, then the response content will be streamed, and it's possible to check the status code and raise an exception before the content of the response actually gets to the box your code is running on.

WCF-Capturing the full HTTP response

I'm using WCF to call a method on a Java web service (using basicHttp with <security mode="Transport">). The service returns some HTML back instead of a SOAPFault. WCF seems to implement some odd truncating of the content returned in the exception, so I can't see the entire error.
Is there a way to get the entire response? Perhaps some configuration I can change to pull back more then 660 bytes? I tried turning on service tracing, but it doesn't seem to capture the entire response. I'm unable to use Fiddler or Charles, because the service is using two-way SSL and it's on a secure network. Here's the exception:
The content type text/html of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 660 bytes of the response were: '<html><head><title>Server - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </he
It seems that an exception occurred on the server side. When exception occurs with httpBinding, HTTP status becomes 404 - NotFound.
It might be as a result of:
Incorrect signature of calling method and actual method, or order of parameters
Failure to serialize or deserialize the result
Some failure with SSL configuration/keys
Internal exception within WCF
In order to eliminate all the above try connecting to it using plain .NET client without SSL. Then add a level of complexity each time.
Hope this helped
Have you set IncludeExceptionDetailInFaults = True in ServiceDebugBehavior?
That might help.
You can try to capture outgoing SOAP request and send that request through HttpWebRequest class. This should allow you capturing whole response.

C# HttpWebRequest.GetResponse - how is StatusCode usage handled for a non-exception vs webexception response?

Can someone help clear up the usage of the "StatusCode" property in HttpWebResponse and WebException?
For example it seems that if:
a) there is no exception, then the HttpWebResponse will have a StatusCode that could have some values that indicate both:
- success (e.g. OK, Accepted etc)
- failure (e.g. UseProxy, RequestTimeout etc)
b) there is a WebExeption throw, which itself has a response object that again has a StatusCode (which I assume is based on the same HttpStatusCode Enumeration.
Question 1
- Is there any consistency in terms of what StatusCode's will trigger a WebException (and you'd pick up the detail within the exception), versus which would come back without an exception but you'd find out the result in the StatusCode of the response object?
Question 2 - Or more specifically what is the pseduo code (or C# code itself) for trying to handle a httpWebRequest.GetResponse call such that you want to differentiate between the categories of responses for the user:
proxy settings / proxy issue
=> so can tell user to fix proxy settings
connectivity issue / web-server down
=> so user is aware of this
server side error (e.g. server is there but there is an issue handling the request - e.g content not there)
=> so user can raise with website manager
success case (and I assume this would be more than just the OK)
=> na (success case)
thanks
In my experience the response status code only returns 200 or 0. Anything else comes through the WebException, including proxy errors like 407 or 417.
The WebException is thrown whenever the web request cannot be executed successfully. For e.g 400 and 500 series of responses.
WebExcpetion has a property named Status which will return the actual status of the response i.e 500 (Internal Server Error).
Here is the list of all response codes: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
===============================================================================
In general:
1xx series of code = provisional response. These are not error codes. For e.g the 100 Continue response which tells that client should continue with its request. Usually WebRequest will not return such response, and handle it itself by sending the rest of request.
2xx series of code = Request was successful received, understood and accepted. These are not error codes. For e.g 200 OK
3xx series of code = Further action needs to be taken. Generally this is not error code (usually its for re-direction) for e.g '301 Moved Permanently', which means that the resource being request is moved to a new location, so any further requests by the client should be on the new URL provided in the response.
OR '305 Use Proxy', which according to you results in an Exception.
4xx series of code = Client errors. These can result in exception. for e.g '400 Bad Request' or '401 Unauthorized'
5xx series of code = Server errors. These can result in exception. for e.g '500 Internal Server Error' or '504 Gateway Timeout'

How to Return Errors from an ASMX Web Service?

My web service method returns a collection object, this will serialize nicely, thanks to the way C# web services work!
But if my code throws an uncaught exception, I want to instead return a custom error object.
Is this possible using C# ASP.NET v2?
For example,
Normal Operation should return:
<Books>
<book>Sample</book>
<book>Sample</book>
</Books>
But on error I want
<error>
<errorMessage></errorMessage>
</error>
Yes, this is possible.
What you'll need to look into is the SoapException class, and specifically the Detail property of the SoapException class.
The SoapException class will effectively render a "Soap Fault", which is the standards-compliant mechanism for returning error information to clients/consumers from a web service method.
The "Detail" property of the SoapException class is of type XmlNode and can thus contain either a single node/element or a hierarchy of child nodes. The Detail node could therefore easily contain and act as the "parent" for the serialized representation of your own custom error object.
From MSDN:
The Detail property is intended for supplying application specific error details related to the Body element of the SOAP request. According to the SOAP specification, if an an error occurrs because the client request could not be processed due to the Body element of the SOAP request, the Detail property must be set. If an error occured in the header entries of the SOAP request, you must throw a SoapHeaderException, so that the error details are returned in the SOAP header. If the error did not occur, due to the processing of the Body element, then the Detail property must not be set.
In building an XmlNode for the Detail property, the Name and Namespace properties of DetailElementName can be used to ensure consistancy [sic] with the SOAP specification.
All immediate child elements of the detail element are called detail entries and each detail entry is encoded as an independent element within the detail element.
Note that if you wish to remain correctly SOAP compliant with your web service responses, you'll need to return a SoapHeaderException rather than a SoapException if the error occurs within the client's header section of the original XML request (this can often be the case when using custom SOAP headers for e.g. security credentials) as detailed above.

Categories