how to convey different message with proper status code - c#

I used the below code in my c# web service project which is a MVC WebAPI. When client calls my service I have three possibilities . One is there is response to return, second one is there is no response to return because "No configuration found" and third one is also no response because "Same configuration is found".
Now my question is can I use the same HttpStatusCode.NoContent for third scenario also by just changing the message ? So the client who receives the response needs to differentiate by message which I feel is not a good solution. I feel I should pick some other status code , but the meaning may not be appropriate.
response.StatusCode = HttpStatusCode.NoContent;
response.ReasonPhrase = "No Configuration Found.";
Can anyone suggest me what is the best approach in this scenario ?

These status codes are HTTP status codes and and are set by W3 with HTTP protocol standarts. This means you can not override and/or change them. They are fixed through all web.
But you are free to throw any of the erronous codes (mostly are 4xx or 5xx format) amd handle them properly on the client-side. As long as you do it properly user will not notify anything wrong.

Related

Why does my Twilio MessagingResponse not work?

The following Twilio code doesn't work. This is my webhook handler in an ASP.NET (Core) 6.0 app.
[AllowAnonymous]
[HttpPost]
[Route("webhook-url")]
public IActionResult PostTwilioMessageReceived([FromForm] TwilioMessageReceivedFormModel formModel)
{
// logging code etc.
var response = new Twilio.TwiML.MessagingResponse();
response.AddText($"You sent '{formModel.Body}' but our systems are dumb and can't process this yet.");
return new TwiMLResult(response);
}
There are no errors. I don't receive the message, and my delivery status webhook doesn't appear to be called.
The method above is called as I see it in my logs.
Note - There is no "to" address. I have adapted sample code from Twilio's documentation which also does nothing to either read the sender address or configure the response with a recipient or other correlation ID.
https://www.twilio.com/docs/whatsapp/tutorial/send-and-receive-media-messages-whatsapp-csharp-aspnet#generate-twiml-in-your-application
I've modified my logging to make doubly sure my webhook is being called. It is. And in Twilio's log there's no acknowledgement of the reply my webhook attempts to produce.
To be clear, the code above is using Twilio's libraries.
The TwiML output of your application would be:
<Response>You sent '...' but our systems are dumb and can't process this yet.</Response>
Unfortunately, that isn't valid TwiML, instead it should look like this:
<Response>
<Message>You sent '...' but our systems are dumb and can't process this yet.</Message>
</Response>
This will respond with a message to the sender. To do this, use the .Message method instead of .AddText:
response.Message($"You sent '{formModel.Body}' but our systems are dumb and can't process this yet.");
Everything else looks fine in your code AFAIK.
Aside: If all you need to do is to respond to the current sender with a single message, you can also respond with plain text and the text/plain content type.
Edit by OP
I also changed the return line to:
return this.TwiML(response);
Which was the advice of Twilio support. I didn't try it my original way, but assumed that if there was some kind of magic that's pre-addressing the response, or correlating it in some way, then it might be in using the helper function on the base controller. Thanks.
It's hard to say what caused this without seeing an error or message log. You should be able to see something in the "Monitor" in the console (more details here).
I've had similar issues in the past with Node.js and the problem was there that I forgot to set the content-type of the response to text/xml. But I'm not sure if this is required in your C# code.

How to return custom 404 response when id not found

I always wonder what is the best error response code in folowing situation:
public IActionResult Index(Guid id)
{
    var entity = _dbContext.Entities.Find(id);
 
    if (entity == null)
    {
         return NotFound(); //??
    }
    return View(entity)
}
404 - Not Found seems most appropriate, however, from debugging point of view, non-existing ID and wrong controller/action names are very different errors.
Anyway, I've decided to return custom error page with more explanatory message, so I can differentiate between 404 and 404.
How to return custom 404 page from Controller's Action and default 404 in other cases?
I would like to avoid returning HttpResponseMessage, since I would need to change return type of the Action.
PS: In comments you may vote for 404 resp other response code you would use in this particular case.
Take a look at this question first.
Theoreticaly you shouldn't use HttpStatus-codes as Application Error Codes.
However, on a public website, 404 has one specific meaning:
The requested resource could not be found but may be available in the
future. Subsequent requests by the client are permissible.
Calling /getresource/347d2f3a-bd0f-4d0b-8c05-2e7f3f8f265e is a resource. If this is not available you should use 404. If it is available, then 200. That's perfectly fine.
Google even says, you should send 404. From the google support:
Returning a code other than 404 or 410 for a non-existent page (or
redirecting users to another page, such as the homepage, instead of
returning a 404) can be problematic. Firstly, it tells search engines
that there’s a real page at that URL. As a result, that URL may be
crawled and its content indexed. Because of the time Googlebot spends
on non-existent pages, your unique URLs may not be discovered as
quickly or visited as frequently and your site’s crawl coverage may be
impacted (also, you probably don’t want your site to rank well for the
search query
For the implementation, I would just throw a custom NotFoundException (If you want to setup more meaningfull information) with all the data you need, and handle it globaly through the ExceptionFilterAttribute. There you can turn it into a 404 response.
Of course you can let the original exception just bubble up to the ExceptionFilterAttribute, but then you have not that many possibilites for making it meaningfull.
You can utilize the CreateResponse extension method and would do something as follows:
return Request.CreateResponse(HttpStatusCode.NotFound, "foobar");
I've used the HttpStatusCode.NoContent for something like this before. It really depends on what your business logic is and how you want to handle these cases. NoContent will result in a successful http call where as NotFound will be an error. NotFound will trigger your default MVC error page route(if you have that setup) and NoContent won't. Is this a response that is possible through normal use/traversing of the app or is it only something that will occur if a malicious user is tampering with urls? All of those pieces are what I take into consideration determining which http status code I want to return. Hope this helps!

What HTTP response code should be used when a client misses their chance to accept an offer

I am writing a web application in C#. One piece of functionality is that the server will send out a push notification offering a client the opportunity to do a round of work. The client can accept or refuse this work.
However, if the client takes too long to respond, the server will see this as an implicit refusal and offer the round of work to someone else.
Here is an extract of the controller endpoint on the server, where a client can post it's acceptance of the current round
public HttpResponseMessage PostAcceptRound(PersonData accepter){
Round currentRound = repo.GetCurrentRound();
if(currentRound.offeredTo.id == accepter.id){
repo.RoundAccepted(currentRound.id);
return Request.CreateResponse<String>(HttpStatusCode.OK, "Round has been accepted");
}
else{
//return appropriate response
}
}
My question is: what is the appropriate response for the client taking too long to accept?
My initial reaction was that I should sent a "BadRequest" error response. However, it is not as if a person refusing late is poorly formed request or something that is unexpected. Indeed, it seems as if accepting too late will be a situation that will happen often within the use of this application.
408 = 'Request Timeout' seems to me to most appropriate.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Http status code with a valid xml string response

I am trying to determine the right status code to apply where the response is not empty.
When a user requests a file and the file does not exist in the server. The user is returned an error message in xml format. I have my own logs but I want to try to make it obvious in IIS logs as well.
Currently the IIS logs a status 200 for all responses. But I want to set a different status code is the server does not find the file.
The problem is during unit testing I found the response is empty if the status code is not 200. I have tried (410, 206, 204). So the client does not receive the error message.
Just want to know if there is any status code I can set and also send the error message.
I am using C# ASP.NET Web Service.
Thanks.
Why are you sending HTTP status codes and not your own application status codes?
IIS logs will never record the code that you return in XML, it will only log the status code it receives from the server that serves your web service. Your XML is merely data as far as IIS is concerned, unless you have a special handler or filter or something installed. Otherwise IIS will only concern itself with the values of your HTTP response headers.
EDIT:
When you set HTTP Status Codes manaully the server will still act within the guidelines of the HTTP spec which states that only a 200 will be accompanied by a full response body.
An HTTP/1.1 404 - Not Found is appropriate - and most servers will allow you to return content, since often you want to return a user-readable HTML page to show that you didn't actually hit a real page.

Is My site down, not working or has an error?

I want to create a small windows application will go automatically every time period to my site and check if its running fine, if it found it down, not working or have an error "Examples: 404, network error, connection to db failed" it will show a message on my screen.
How can i know that there is an error there programmaticly using any .NET language?
It's pretty easy to do with a WebClient. It would look something like this:
WebClient client = new WebClient();
try
{
string response =
client.DownloadString("http://www.example.com/tester.cgi");
// We at least got the file back from the server
// You could optionally look at the contents of the file
// for additional error indicators
if (response.Contains("ERROR: Something"))
{
// Handle
}
}
catch (WebException ex)
{
// We couldn't get the file.
// ... handle, depending on the ex
//
// For example, by looking at ex.Status:
switch (ex.Status)
{
case WebExceptionStatus.NameResolutionFailure:
// ...
break;
// ...
}
}
You could hook that up to a Timer's Tick event or something to periodically make the check.
Why bother? You can get a much better solution for cheap from a provider like RedAlert
The nice thing about this is:
1) It tests your site from outside your firewall, so it can detect a wider variety of problems.
2) It is an impartial 3rd party so you can prove uptime if you need to for an SLA.
3) For a small premium you can have the thing try and diagnose the problems.
4) It can page or e-mail you when there is a problem.
5) You don't need to commission a new server.
Geez, I sound like an ad for the guys, but I promise I don't work for them or get a kickback. I have just been happy with the service for our servers.
BTW: I checked pricing and it is about $20 per site/month. So you could probably pay for a year of the service in less time than it will take to build it yourself.
Wanting to perform the same functionality I first looked into third party solutions. One particular service that is free and has been fairly accurate is MonitorUs.
If, however, you are wanting to build your own then I would have one recommendation. Consider using a Head request instead of a get request:
The HEAD method is identical to GET
except that the server MUST NOT return
a message-body in the response. The
metainformation contained in the HTTP
headers in response to a HEAD request
SHOULD be identical to the information
sent in response to a GET request.
This method can be used for obtaining
metainformation about the entity
implied by the request without
transferring the entity-body itself.
This method is often used for testing
hypertext links for validity,
accessibility, and recent
modification. w3.org
Here's a link to Peter Bromberg's article that explains how to perform a Head request in C#.
Use the System.Net.WebClient object. It's easier to use than HttpWebRequest. It has a "DownloadString" method that will download the contents of a URL into a string. That method may also throw a WebException error if the server returns a 500. For other errors you can parse the string and look for key words.
Use HttpWebRequest, and wrap it in a try catch for WebException. The error code in the exception object will give you the code. 404, etc. If it is 500, you could print the message.
If you do this, create a special page that exercises any special subsystems, like the data base, file IO, etc, and serves up the results in plain text, not html. This will allow you to parse the returned data easier, and will also catch things like DB or IO problems that may not give you a 404 or 500 HTTP error.
Try Adventnet's Application Manager (http://www.manageengine.com/products/applications_manager/), it is free for 5 monitors, and provides excellent monitoring capabilities
You could configure the actions that can be done in case of a failure like send email etc.
If you'd prefer to get email/SMS when your sites are down, try the Are My Sites Up web-based solution.

Categories