For example, ExceptionHandlerMiddleware Middleware code on Github
uses this as:
if (context.Response.HasStarted ||...)
I don't quite get it, how can the web server starts to send response to clients when the request still in the pipeline assuming the ExceptionHandlerMiddleware is the first middleware in the pipeline? Because the request hasn't got out of ExceptionHandlerMiddleware, so it hasn't arrived to the web server, then how could it be that the web server already starts to send responses to client in this scenario?
Any middleware or handler may choose to call WriteAsync (or other similar methods) on the HttpResponse, possibly multiple times.
It's not necessarily possible for all of those writes to just be stored in local buffers, and indeed may not be desirable to just buffer locally. So, sooner or later, those Write calls are going to result in real data being sent over the network.
And, in this concrete example, a handler may have made multiple calls such as the above before it encounters an error condition that causes control to be returned to the ExceptionHandlerMiddleware.
Your specific ExceptionHandlerMiddleware example uses Microsoft.AspNetCore.Http.HttpResponse.HasStarted:
Gets a value indicating whether response headers have been sent to the client.
https://learn.microsoft.com/en-US/dotnet/api/microsoft.aspnetcore.http.httpresponse.hasstarted?view=aspnetcore-5.0
There is also Microsoft.Net.Http.Server.Response.HasStarted:
Indicates if the response status, reason, and headers are prepared to send and can no longer be modified. This is caused by the first write or flush to the response body.
https://learn.microsoft.com/en-US/dotnet/api/microsoft.net.http.server.response.hasstarted?view=aspnetcore-1.1
Each response consis of two parts: Header and Body
These two being sent together to the client, first the headers than the body. So during development, the only opportunity to set any value on the response object that affects the headers is up to the point at which you start sending the body.
As long as you begin sending the body of the response you can no longer change the headers because they are sent as the first part of the response just before the body begins sending.
Related
I have .net core project and add stackify prefix to monitor requests, but in response prefix show only headers but not body of response. It is possible to see all response body?
On prefix site I found information:
It can capture incoming post data, it can also capture the response and the response headers and part of the response body. Right now, we limit that to only be a certain amount of characters so if it’s returning something larger, it won’t capture all of it.
It is possible to change this?
There is not a way to change this at the moment if the response body is too large it will not show up in the traces.
Stackify has an Ideas portal that you can make suggested changes to, their COO gets notified when a new request has been made and when a request has been up voted by several clients. He takes each request into good consideration and arranges them into Stackify's road map. Also you can subscribe to the ideas to keep updated on its progress.
https://ideas.stackify.com
I'm currently working with a number of third parties, sending them data via an HttpPost with an encrypted url string. Each of the third parties sends back an xml string which I then read and use. All is good!
The question I have is this. If I send a request to a third party, and they do not provide a response, what happens? To clarify, I mean that a response string isn't returned in all cases - not just errors and timeouts.
Few things can happen:
A response is sent by the third party: It consists of the desired output (an XML string in your case.
A response is sent, but the content is 0 length: Take it into mind that HTTP response consists of two parts: HTTP headers, and content. In this case third party sends only the headers. You can consider this as String.Empty output.
A response is not sent: Third part should have sent a response according to the HTTP protocol, but they don't. Third party may close the socket or just timeout. That can happen because of an internal problem, or they are just choosing not to respond to you. This will normally result in an exception. What the exception is, though, depends on the methods/library you use to send HTTP requests.
The HTTP protocol does not include a way to not send a response. A response is always sent. It might be zero length, though.
I mean that a response string isn't returned in all cases
Is this a question or an assertion? This statement is false.
and they do not provide a response, what happens?
So what happens in case of a zero-length response? That depends entirely on your code. Neither protocol not framework care about this case.
Couldn't the socket actually be closed before any headers are sent back? Or, if the server is down?
That's a protocol violation. That's not HTTP, then. In such a situation the app is generally notified through an exception.
I was given the task of creating a web based client for a web service.
I began building it out in c# | .net 4.0 | MVC3 (i can use 4.5 if necessary)
Sounded like a piece of cake until I found out that some of their responses would be asynchronous. This is the flow ... you call a method and they return a response of ack or nack letting you know if your request was valid. Upon an ack response you should expect an async response with the data you requested, which will be sent to a callback url that you provide in your request.
Here are my questions:
If I'm building a web app and debugging on localhost:{portnum} how can I give them a callback url.
If I have already received a response (ack/nack) and my function finishes firing isn't my connection to the client then over ? How would I then get the data back to the client? My only thought is maybe using something like signalR, but that seems crazy for a customer buy flow.
Do I have to treat their response like a webhook? Build something separate that just listens and has no knowledge of the initial request. Just save the data to a db and then have the initial request while loop until there is a record for the unique id sent from the webhook.... oye vey
This really has my brain hurting :-/
Any help would be greatly appreciated. Articles, best practices, anything.
Thanks in advance.
If you create your service reference, it will generate a *ServiceMethod*Completed delegate. Register an event handler on it to process your data.
Use the ServiceMethod_Async() method to call the service.
The way I perceived your question is as follows, though please correct me if I'm wrong about this:
1) You send a request to their endpoint with parameters filled with your data. In addition, you send a:
callback url that you provide in your request. (quoted from your question)
2) They (hopefully) send an ack for your valid request
3) They eventually send the completed data to your callback url (which you specified).
If this is the flow, it's not all that uncommon especially if the operations on their side may take long periods of time. So let's say that you have some method, we'll call it HandleResponse(data). If you had originally intended to do this synchronously, which rarely happens in the web world, you would presumably have called HandleResponse( http-webservice-call-tothem );
Instead, since it is they who are initiating the call to HandleResponse, you need to set a route in your web app like /myapp/givemebackmydata/{data} and hook that to HandleResponse. Then, you specify the callbackurl to them as /myapp/givemebackmydata/{data}. Keep in mind without more information I can't say if they will send it as the body of a POST request to your handler or if they will string replace a portion of the url with the actual data, in which case you'd need to substitute {data} in your callback url with whatever placeholder they stipulate in their docs. Do they have docs? If they don't, none of this will help all that much.
Lastly, to get the data back on the client you will likely want some sort of polling loop in your web client, preferably via AJAX. This would run on a setInterval and periodically hit some page on your server that keeps state for whether or not their webservice has called your callback url yet. This is the gnarlier part because you will need to provide state for each request, since multiple people will presumably be waiting for a callback and each callback url hit will map to one of the waiting clients. A GUID may be good for this.
Interesting question, by the way.
I'm trying to extend WebAPI to support returning a response through an HTTP callback.
Workflow:
WebAPI receives a HTTP request with a callback URL.
WebAPI handles the URL normally and if the operation completes in less time than a configured timeout the result is sent synchronously.
If the timeout is exceeded the server needs to send an HTTP response indicating it went async, processing continues.
When processing (eventually) completes the response of the controller is posted to the pre-negotiated callback url.
Controllers need to remain synchronous and unaware of the async/callback functionality.
It appears MessageHandlers are a likely candidate but returning multiple HTTP responses (one for the early 'long task' response and one for the callback) does not appear to be supported.
Can someone provide guidance on what areas of WebAPI are extensible and relevant to this scenario?
I think an HttpMessageHandler will do the trick but not the way I think you're asking for.
One URL will be the main one and will return either the result or the redirection and the other will handle the redirections.
This is a very common scenario. In some cases you'll ask for a list of something and receive the a managed amount of results and a continuation URL if there are more. You requirement might be looked up as being just that where you either only have a continuation or the whole results.
Another way of looking at it as CQRS (Command Query Responsibility Segregation). You issue a command to on URL and retrieve the response from another. As an optimization, the result of invoking the command might be the response instead of the query URL.
Does this help you?
I'm on IIS 6 and I have an ASP.Net 4.0 site that's a single page to serve as a SOAP reverse proxy. I have to modify the return content in order to delete a trouble node from the response and add a tracking node.
In order to facilitate its function as a reverse proxy for all addresses, I have the 404 on the server set to a custom "URL" of "/default.aspx" (the page for my app)
For requests without a payload, it works perfectly - such as for ?WSDL Urls. It requests the proper URL from the target system, gets the response and sends it back - it's pretty utterly transparent in this regard.
However, when a SOAP request is being made with an input payload, the Request.InputStream in the code is always empty. Empty - with one exception - using SOAPUI, I can override the end point and send the request directly to /default.aspx and it will receive the input payload. Thus, I have determined that the custom 404 handler is - when server-side transferring the request - stripping the payload. I know the payload is being sent - I have even wiresharked it on the server to be sure. But then when I add code to log the contents of Request.InputStream it's blank - even though Request.ContentLength shows the right content length for the original request.
I've also been looking for a good way to use ASP.Net to intercept the requests directly rather than allowing the normal IIS 404 handler to take care of it but even with a wildcard mapping, I can't seem to get the settings right nor am I fully confident that it would help. (But I'm hoping it would?)
Finally, I don't have corporate permission to install MVC framework.
Thus, I need either some configuration for IIS I am missing to make this work properly or some other method of ensuring that I get the request payload to my web page.
Thanks!
What about using an HTTP Handler mapped to all requests?
You'll need to add a wildcard application mapping as detailed here and correctly configure your HTTP Handler.