I'm getting the error "HTTP Error 414. The request URL is too long." From the following article, I understand that this is due to a very long query string:
http://www.mytecbits.com/microsoft/iis/query-string-too-long
In web.config, I have maxQueryStringLength="2097151". Is this the maximum value?
In order to solve this problem, should I set maxUrl in web.config? If so, what's the maximum value supported?
What should I do to fix this error?
The GET request should never be this long. You need to change it to POST method instead since it was designed to transmit block of data such as forms.
An excerpt from the RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1:
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line. POST is designed to
allow a uniform method to cover the following functions:
Annotation of existing resources;
Posting a message to a bulletinboard, newsgroup, mailing list, or
similar group of articles;
Providing a block of data, such as the result of submitting a
form, to a data-handling process;
Extending a database through an appendoperation.
Related
I get this error when using the CustomVisionPredictionClient like so:
var predictionApi = new CustomVisionPredictionClient()
{
ApiKey = _predictionKey,
Endpoint = "https://westeurope.api.cognitive.microsoft.com"
};
var result = await predictionApi.ClassifyImageAsync(project.Id, _modelName, imageData);
The project/project id is retrieved via the training API, on which I can call GetProjects() without a problem. It should be correct, if I change it to something wrong I get a "not found" exception.
_modelName is the published name of the iteration ("xxxRecognition", see screenshot below), it should also be correct, when I change it I get "not found".
imageData is just a FileStream from a PNG image.
The problem was that I created an "Object Detection" type project and tried to use it with ClassifyImage() which has to be used with "Classification" type projects. So I have to use DetectImage() instead. :)
There's two items to address here.
Your particular "Bad Request"
Your example, specifically, has one or more of these problems that you haven't really included.
The _modelName is malformed
The imageData is not formatted properly
Some configuration, likely of request headers, is missing or incorrect
That's about the most we can provide from the example you've given. But here's the other concern that will benefit you greatly in the future: "Bad Request" tells you a lot about what's happened.
More about "Bad Request" in general
If you look at ranges within HTTP status codes you'll notice a pattern in the "error" ranges.
In 4xx the requester (you) did something wrong and you can correct it.
In 5xx the responder did something wrong and you cannot correct it.
Beneath that:
In 404 Not Found it seems the request was formed well but the responder cannot find what you've asked for
In 401 Unauthorized you didn't provide any kind of identity
In 403 Forbidden you did provide an identity but you're not allowed to perform this action
But in 400 Bad Request the responder couldn't validate your request as good input at all. That means you can look at the API documentation again, compare it with your implementation, and try again.
As the title says I am wondering if it possible to return information from the controller based on the success of the PUT request.
In this case I am using the put request to use my email service to send emails. Is there a way to return a results object that lists the statuses for each email so I can display on the front end which emails failed and why?
Thanks in advance for any advice.
Ideally PUT request(successful) is used to:
1.) Update an existing resource -200 OK with NO response body
2.) Creation of new resource (If the Request-URI does not point to an existing resource, origin server can create the resource with that URI) - 201 Created with some meta data ,resource identifier in the response body.
So as per the recommendation ,it should not be returned in the response of PUT request and a subsequent GET call should be made to get the status of the emails.
Refer the HTTP specification :
RF2616 -https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Sorry for my english.
In Delphi I have an idHttp component with the hoWaitForUnexpectedData option activated.
When I send a POST request to a URL, it redirects the client to a second URL with the same POST request and headers. Also, the server response contains "Connection: keep-alive" in its header.
However, when I try to do the same request in C# with a HttpWebRequest component, it redirects to the second URL using the method GET.
I need the C# HttpWebRequest component to work like the Delphi idHTTP one does. I don't understand why it uses a GET instead of a POST when following the redirection.
Here's my code in Delphi, using hoWaitForUnexpectedData:
// The server is supposed to send a 'Content-Length' header without sending
// the actual data. 1xx, 204, and 304 replies are not supposed to contain
// entity bodies, either...
if TextIsSame(ARequest.Method, Id_HTTPMethodHead) or
TextIsSame(ARequest.MethodOverride, Id_HTTPMethodHead) or
((AResponse.ResponseCode div 100) = 1) or
(AResponse.ResponseCode = 204) or
(AResponse.ResponseCode = 304) then
begin
// Have noticed one case where a non-conforming server did send an
// entity body in response to a HEAD request. If requested, ignore
// anything the server may send by accident
if not (hoWaitForUnexpectedData in FOptions) then begin
Exit;
end;
Result := CheckForPendingData(100);
end
else if (AResponse.ResponseCode div 100) = 3 then
begin
// This is a workaround for buggy HTTP 1.1 servers which
// does not return any body with 302 response code
Result := CheckForPendingData(5000);
end else begin
Result := True;
end;
An HTTP redirect, by definition from the standard, should be handled using a GET. Therefore, if you send a POST and get a redirect as an answer, the expected behavior is to perform a GET to the redirect address. I suspect the old Delphi component is following old practices and replicates the call including with the POST verb.
I would try to disable AllowAutoRedirect in the HttpWebRequest object and handle this manually, as your case seems to differ from the standard.
The hoWaitForUnexpectedData option has no effect on how TIdHTTP handles redirects, and neither does the section of code you quoted.
However, the hoTreat302Like303 option does affect redirect handling. If TIdHTTP receives a 303 redirect, or receives a 302 redirect with hoTreat302Like303 enabled, TIdHTTP sends the new request as a GET. Otherwise, it sends the new request using the same verb as the redirected request. This is by design, and there is a series of comments in the implementation code of the TIdHTTPProtocol.ProcessResponse() method explaining the rational behind this behavior:
// GDG 21/11/2003. If it's a 303, we should do a get this time
// RLebeau 7/15/2004 - do a GET on 302 as well, as mentioned in RFC 2616
// RLebeau 1/11/2008 - turns out both situations are WRONG! RFCs 2068 and
// 2616 specifically state that changing the method to GET in response
// to 302 and 303 is errorneous. Indy 9 did it right by reusing the
// original method and source again and only changing the URL, so lets
// revert back to that same behavior!
// RLebeau 12/28/2012 - one more time. RFCs 2068 and 2616 actually say that
// changing the method in response to 302 is erroneous, but changing the
// method to GET in response to 303 is intentional and why 303 was introduced
// in the first place. Erroneous clients treat 302 as 303, though. Now
// encountering servers that actually expect this 303 behavior, so we have
// to enable it again! Adding an optional HTTPOption flag so clients can
// enable the erroneous 302 behavior if they really need it.
The jist of it is that the HTTP spec says to send a GET for a 303 redirect, whereas it is ambiguous about whether to send a GET for 302. Some browsers do, some do not. That is why the hoTreat302Like303 option was added, though it is disabled by default for backwards compatibility with earlier Indy versions.
So, the behavior you describe means you must be encountering a 302 redirect, with hoTreat302Like303 disabled (which it is default). If you enable that option, TIdHTTP will behave more like HttpWebRequest, not the other way around.
I'm not sure what response code to use when the request is valid but there is no result for the given parameter
The JSON returns a success of true/false and a message
When I do a GET and there is some data I use:
200 HttpStatusCode.OK
However where there is no data should I still use OK and return the JSON success / message or should I use 400 HttpStatusCode.BadRequest to indicate something in the request is bad.
It depends on what does it mean for the client to not have results.
Typically lack of data would still be http 200 ok.
e.g. /employees etc.
However, for some scenarios you could return
HTTP 404 Not Found.
Especially when the client expects a particular resource to be present.
e.g. employees/update/32
Normally any other response code (204 etc.) though technically valid and fitting, might confuse the client.
Also, 400 Bad Request should also be not used, if there is nothing wrong with the request.
If the operation was successful but there is really no response data, use the status 204 NO CONTENT. If an expected entity was missing, return 404 NOT FOUND. If there was some sort of internal error, return 500 SERVER ERROR.
According to the HTTP/1.1 spec,
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.
If the client is a user agent, it SHOULD NOT change its document view
from that which caused the request to be sent. This response is
primarily intended to allow input for actions to take place without
causing a change to the user agent's active document view, although
any new or updated metainformation SHOULD be applied to the document
currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always
terminated by the first empty line after the header fields.
If ther was nothing wrong with the request but you just don't have any data (i.e. search returns 0 rows) than I would not use BadRequest:
BadRequest is sent when no other error is applicable, or if the exact
error is unknown or does not have its own error code.
http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode%28v=vs.110%29.aspx
I've encountered an issue with HttpWebRequest that if the URI is over 2048 characters long the request fails and returns a 404 error even though the server is perfectly capable of servicing a request with a URI that long. I know this since the same URI that causes an error if submitted via HttpWebRequest works fine when pasted directly into a browser address bar.
My current workaround is to allow users to set a compatability flag to say that it's safe to send the parameters as a POST request instead in the case where the URI would be too long but this is not ideal since the protocol I'm using is RESTful and GET should be used for queries. Plus there is no guarentee that other implementors of the protocol will accept POSTed queries
Is there another class in .Net that has equivalent functionality to HttpWebRequest that doesn't suffer from the URI length limit that I could use?
I'm aware of WebClient but I don't really want to use that as I need to be able to fully control the HTTP Headers which WebClient restricts the ability to do.
Edit
Because Shoban asked for it:
http://localhost/BBCDemo/sparql/?query=PREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0D%0APREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0APREFIX+xsd%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%23%3E%0D%0APREFIX+skos%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23%3E%0D%0APREFIX+dc%3A+%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%0D%0APREFIX+po%3A+%3Chttp%3A%2F%2Fpurl.org%2Fontology%2Fpo%2F%3E%0D%0APREFIX+timeline%3A+%3Chttp%3A%2F%2Fpurl.org%2FNET%2Fc4dm%2Ftimeline.owl%23%3E%0D%0ASELECT+*+WHERE+{%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+dc%3Atitle+%3Ftitle+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Ashort_synopsis+%3Fsynopsis-short+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Amedium_synopsis+%3Fsynopsis-med+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Along_synopsis+%3Fsynopsis-long+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Amasterbrand+%3Fchannel+.%0D%0A++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Agenre+%3Fgenre+.%0D%0A++++%3Fchannel+dc%3Atitle+%3Fchanneltitle+.%0D%0A++++OPTIONAL+{%0D%0A++++++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Abrand+%3Fbrand+.%0D%0A++++++++%3Fbrand+dc%3Atitle+%3Fbrandtitle+.%0D%0A++++}%0D%0A++++OPTIONAL+{%0D%0A++++++++%3Chttp%3A%2F%2Fwww.bbc.co.uk%2Fprogrammes%2Fb00n4d6y%23programme%3E+po%3Aversion+%3Fver+.%0D%0A++++++++%3Fver+po%3Atime+%3Finterval+.%0D%0A++++++++%3Finterval+timeline%3Astart+%3Fstart+.%0D%0A++++++++%3Finterval+timeline%3Aend+%3Fend+.%0D%0A++++}%0D%0A}&default-graph-uri=&timeout=30000
Which is the following encoded onto the querystring:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX po: <http://purl.org/ontology/po/>
PREFIX timeline: <http://purl.org/NET/c4dm/timeline.owl#>
SELECT * WHERE {
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> dc:title ?title .
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:short_synopsis ?synopsis-short .
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:medium_synopsis ?synopsis-med .
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:long_synopsis ?synopsis-long .
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:masterbrand ?channel .
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:genre ?genre .
?channel dc:title ?channeltitle .
OPTIONAL {
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:brand ?brand .
?brand dc:title ?brandtitle .
}
OPTIONAL {
<http://www.bbc.co.uk/programmes/b00n4d6y#programme> po:version ?ver .
?ver po:time ?interval .
?interval timeline:start ?start .
?interval timeline:end ?end .
}
}
the protocol I'm using is RESTful and GET should be used for queries.
There's no reason POST can't also be used for queries; for really long request data you have to, as very-long-URIs aren't globally supported, and have never been. This is one area where HTTP does not live up to the REST ideal.
The reason POST generally isn't used on a plain-HTML level is to stop the browser prompting for reloads, and promote eg. bookmarking. But for HttpWebRequest you don't have either of those concerns, so go ahead and POST it. Web applications should use a parameter or a URI path part to distinguish write requests from queries, not merely the request method. (Of course a write request from a GET method should still be denied.)
I don't think HttpWebRequest is actually incompatible with GET URLs of the size you are talking about. I say this based on two things:
In my own work I use HttpWebRequest to send HTTP GET requests longer than 2048 characters without trouble. I'm not sure what my longest ones are, but we're talking 10,000+ characters. (This is primarily between a web application and an instance of Solr running under Tomcat.)
.NET does have some limits on GET URL lengths, but the ones I'm aware of are much higher than 2048 characters. For example, I learned today from my profiler that WebRequest.Create(string url) calls the Uri class constructor, and that is documented to throw a UriFormatException if "the length of uriString exceeds 65534 characters."
I'm not sure where your problem might be, if it's not HttpWebRequest itself. Do you know under what conditions your web service will return HTTP 404 (i.e. "not found")? (I assume the 404 is coming from your web service, rather than being faked inside the depths of .NET.) I'd also want to double-check that the address you're pasting into the browser is actually the same one that's being sent by .NET; as feroze suggested, you should use a network sniffing tool for this. If the two addresses are the same, then maybe next compare how the HTTP headers vary between the .NET case and the browser case. (Incidentally, I personally find Fiddler a bit handier than wireshark for HTTP debugging tasks along these lines.)
See also this somewhat related question: How does HttpWebRequest differ (functional) from pasteing a URL into an address bar?
Here's a snippet which constructs HttpWebRequest instances with bigger and bigger url values until an exception gets thrown:
using System.Net;
...
StringBuilder url = new StringBuilder("http://example.com?p=");
try
{
for (int i = 1; i < Int32.MaxValue; i++)
{
url.Append("0");
HttpWebRequest request = HttpWebRequest.CreateHttp(url.ToString());
}
}
catch (Exception ex)
{
Console.Out.WriteLine("Error occurred at url length: " + url.Length);
Console.Out.WriteLine(ex.GetType().ToString() + ": " + ex.Message);
return;
}
Console.Out.WriteLine("Completed without error!");
On my machine (in LINQPad running .Net 4.5), this snippet outputs:
Error occurred at url length: 65520
System.UriFormatException: Invalid URI: The Uri string is too long.
Your query string is wrong according to RFC3986. '{' and '}' characters are not allowed in a URI.