Document Moved 201 Remove from WebResponse - c#

I use .NET 4.61. Can I get the response from https://1106-7916.el-alt.com/wp-json/wc/v2/products/407 instead of https://1106-7916.el-alt.com/wp-json/wc/v2/products, which causes a redirect? Can I add code to BuildRequest, shown below, to get that response automatically?
I am using the WooCommerce REST API to create products. Here is my request:
POST-https://1106-7916.el-alt.com/wp-json/wc/v2/products?consumer_key=X
{"attributes":[{"name":"Color","visible":true,"variation":true,"options":["Red","Blue","Green","Orange"]},{"name":"Size","visible":true,"variation":true,"options":["S","M","L"]}],"title":"FooFoo","sku":"TestCreateProductWoo1026","description":"Test","categories":[],"tags":[],"type":"variable"}
Here is the response:
HTTP/1.1 201 Created
Cache-Control: no-cache, must-revalidate, max-age=0
Allow: GET, POST
Location: https://1106-7916.el-alt.com/wp-json/wc/v2/products/407
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found here</body>{"id":407,"name":"Product","slug":"product"}
Here is my code:
private string BuildRequest(string path, IDictionary<string, string> query, HttpMethodTypes httpMethod, object body)
{
string pathAndQuery = BuildParameters(path, query);
string resultData = string.Empty;
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(pathAndQuery);
myHttpWebRequest.Accept = "application/json";
myHttpWebRequest.ContentType = "application/json";
myHttpWebRequest.UserAgent = "JMA Web Technologies";
myHttpWebRequest.AllowAutoRedirect = true;
SetHeaders(myHttpWebRequest);
if (httpMethod != HttpMethodTypes.GET)
myHttpWebRequest.Method = httpMethod.ToString();
SetResponseBody(body, myHttpWebRequest);
WebResponse httpResponse = myHttpWebRequest.GetResponse();
Stream responseStream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
resultData = reader.ReadToEnd();
responseStream.Close();
httpResponse.Close();
return resultData;
}
Any help is greatly appreciated.

Related

Sending Attachment to HttpRequest POST C#

I'm trying to send an attachment using HttpRequest, but the server give me a 500 Internal Server Error.
If i make the same call from SOAP UI, it will success with this result.
HTTP/1.1 200 OK Date: Fri, 30 Apr 2021 13:47:00 GMT Server: Apache Strict-Transport-Security: max-age=63072000; includeSubDomains;
preload Keep-Alive: timeout=5, max=100 Connection: Keep-Alive
Transfer-Encoding: chunked Content-Type: multipart/related;
boundary="MIMEBoundary_ccc0c7786f280ccc7fb981fb343b4463e574457582881961";
type="application/xop+xml";
start="0.dcc0c7786f280ccc7fb981fb343b4463e574457582881961#apache.org";
start-info="text/xml"
--MIMEBoundary_ccc0c7786f280ccc7fb981fb343b4463e574457582881961 Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary Content-ID:
0.dcc0c7786f280ccc7fb981fb343b4463e574457582881961#apache.org
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
...</soapenv:Envelope>
--MIMEBoundary_ccc0c7786f280ccc7fb981fb343b4463e574457582881961--
So i'm mistaking the link between soap request and attachment.
What could be the error inside the code?
The code is called by a c# Web Api and is calling a SOAP POST resource.
public static string Start()
{
var _url = "...";
var _action = "...";
XmlDocument soapEnvelopeXml = SoapEnvelope();
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
Console.Write(soapResult);
}
return "";
}
private static XmlDocument SoapEnvelope()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
#"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
....
</soapenv:Envelope>");
return soapEnvelopeDocument;
}
public static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
var data = GetFromData("dummy.pdf", #"C:\dummy.pdf", webRequest);
stream.Write(data, 0, data.Length);
soapEnvelopeXml.Save(stream);
}
}
public static byte[] GetFromData(string fileName, string filePath, HttpWebRequest request)
{
var attachment = System.IO.File.ReadAllBytes(filePath);
string boundaryString = Guid.NewGuid().ToString();
MemoryStream postDataStream = new MemoryStream();
StreamWriter postDataWriter = new StreamWriter(postDataStream);
request.ContentType = "multipart/form-data; boundary=" + boundaryString;
postDataWriter.Write("\r\n--" + boundaryString + "\r\n");
postDataWriter.Flush();
postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n", "file", fileName, MimeMapping.GetMimeMapping(fileName));
postDataWriter.Flush();
postDataStream.Write(attachment, 0, attachment.Length);
postDataWriter.Write("\r\n--" + boundaryString + "--\r\n");
postDataWriter.Flush();
return postDataStream.ToArray();
}
Thank you

C# - Request Json File with authorization key (cURL example)

I'm trying to do a HTTP GET request for a json file from an api in a C# application. I'm having trouble getting the authorization, request headers and the webresponse (.GetResponse not working).
The example on the api's site is in curl.
curl -H "Authorization: Bearer ACCESS_TOKEN" https://erikberg.com/nba/boxscore/20120621-oklahoma-city-thunder-at-miami-heat.json
Here is my request method, which will also include JSON deseralization
public static string HttpGet(string URI)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
// Not sure if the credentials input is the correct
string cred = $"{"Bearer"} {"ACCESS_TOKEN_IS_A_GUID"}";
req.Headers[HttpRequestHeader.Authorization] = cred;
req.Method = "GET";
// GetResponse() is "red", won't work.
WebResponse response = req.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd().Trim();
}
}
EDIT It was resolved. The problem was that the request was for a GZIP file and that had to be decompressed
var request = (HttpWebRequest)WebRequest.Create(requestUri);
request.UserAgent = userAgent;
request.ContentType = "application/json";
request.Method = WebRequestMethods.Http.Get;
request.Headers[HttpRequestHeader.Authorization] = bearer;
request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";
var response = (HttpWebResponse) request.GetResponse();
string jsonString;
using (var decompress = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
{
using (var sr = new StreamReader(decompress))
jsonString = sr.ReadToEnd().Trim();
}
_Game = JsonConvert.DeserializeObject<Game>(jsonString);
You are not getting it because you don't have access.
The cURL command from API's site(that you mentioned in your question) gives the following JSON
{
"error" : {
"code" : "401",
"description" : "Invalid access token: ACCESS_TOKEN"
}
}
And so does the following code:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("URL");
req.UserAgent = "Bearer";
WebResponse response = req.GetResponse();
So what you need is a valid username/password or userAgent. You might want to contact the site for that.

Get data on error with HttpWebRequest

While interacting with an API there is a situation where they will return a 401 response that also contains data. I would like to return this data regardless of the error code of the response.
I have created a function to submit a either a GET or POST using HttpWebRequest that returns a string containing the response data. The only problem is that if the response is a 401, an error is thrown and the data is not read.
Here is an example of what is returned:
HTTP/1.1 401 Unauthorized
Access-Control-Allow-Credentials: false
Content-Type: application/json; charset=UTF-8
Date: Tue, 19 May 2015 17:56:10 GMT
Vary: Accept-Encoding
Vary: Accept-Encoding
Content-Length: 254
Connection: keep-alive
{"status":"error","message":"access_token (...) was deleted (at Tue May 19 17:52:49 UTC 2015). Use your refresh token (if you have one) to generate a new access_token.","requestId":"..."}
Here is what I have for my function so far:
private string SendHttpRequest(string url, out int statusCode, string method = "GET", object postData = null, string contentType = "application/json")
{
bool isPost = method.Equals("POST", StringComparison.CurrentCultureIgnoreCase);
byte[] content = new ASCIIEncoding().GetBytes(isPost ? JsonConvert.SerializeObject(postData) : "");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = true;
request.Method = method;
request.ContentType = contentType;
request.ContentLength = postData == null ? 0 : content.Length;
if (isPost && postData != null)
{
Stream reqStream = request.GetRequestStream();
reqStream.Write(content, 0, content.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); // Throws error here
string result;
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
statusCode = (int)response.StatusCode;
response.Close();
return result;
}
How can I still get the data for a 401 response? There is no requirement to use HttpWebRequest, that is just what I have been using so far.
The call to GetResponse is throwing a WebException. You can catch that exception and extract the response via the exception's Response property:
private string SendHttpRequest(string url, out int statusCode, string method = "GET", object postData = null, string contentType = "application/json")
{
bool isPost = method.Equals("POST", StringComparison.CurrentCultureIgnoreCase);
byte[] content = new ASCIIEncoding().GetBytes(isPost ? JsonConvert.SerializeObject(postData) : "");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = true;
request.Method = method;
request.ContentType = contentType;
request.ContentLength = postData == null ? 0 : content.Length;
if (isPost && postData != null)
{
Stream reqStream = request.GetRequestStream();
reqStream.Write(content, 0, content.Length);
}
HttpWebResponse response = null;
//Get the response via request.GetResponse, but if that fails,
//retrieve the response from the exception
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
response = (HttpWebResponse)ex.Response;
}
string result;
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
statusCode = (int)response.StatusCode;
response.Close();
return result;
}

WP8 - Login to Website and parse HTML from answer

I want to login to this site: http://subcard.subway.co.uk/de_cardholder/JSP/login_reg.jsp
And i found out that I have to send a POST request to the server and I also know that I have to work with this POST request:
POST /de_cardholder/servlet/SPLoginServlet HTTP/1.1
Host: subcard.subway.co.uk
language=de&userID=ID&password=PASSWORD&transIdentType=1&programID=6
And after the login I want to parse the HTML data. But how can I implement the POST request on WP in C# and is it as easy as I think?
Try this,
Uri RequestUri = new Uri("subcard.subway.co.uk/de_cardholder/servlet/SPLoginServlet HTTP/1.1?language=de&userID=ID&password=PASSWORD&transIdentType=1&programID=6", UriKind.Absolute);
string PostData = "";
WebRequest webRequest;
webRequest = WebRequest.Create(RequestUri);
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
HttpWebResponse response;
string Response;
using (response = (HttpWebResponse)await webRequest.GetResponseAsync()) ;
using (Stream streamResponse = response.GetResponseStream())
using (StreamReader streamReader = new StreamReader(streamResponse))
{
Response = await streamReader.ReadToEndAsync();
}
if(Response != null)
{
//data should be available in Response
}
var postRequest = (HttpWebRequest)WebRequest.Create("your Url here");
postRequest.ContentType = "application/x-www-form-urlencoded";// you can give the type of request content here
postRequest.Method = "POST";
if you have any data to be posted along with the request as part of content and not as part of URL itself you can add this. example:- ( language=de&userID=ID&password=PASSWORD&transIdentType=1&programID=6)
using (var requestStream = await postRequest.GetRequestStreamAsync())
{
byte[] postDataArray = Encoding.UTF8.GetBytes("your request data");
await requestStream.WriteAsync(postDataArray, 0, postDataArray.Length);
}
if you do not have any data to be a send as content ignore the above code
WebResponse postResponse = await postRequest.GetResponseAsync();
if (postResponse != null)
{
var postResponseStream = postResponse.GetResponseStream();
var postStreamReader = new StreamReader(postResponseStream);
string response = await postStreamReader.ReadToEndAsync();// Result comes here
}

json parameter to request on Windows 8 (RT)

I'm looking for solution to send request with JSON like parameter to server.
I use this code,
var httpClient = new HttpClient();
var tempByteArray = Encoding.UTF8.GetBytes("my valid json");
var stream = new MemoryStream(tempByteArray);
var streamContent = new StreamContent(stream);
var request = new HttpRequestMessage(HttpMethod.Post, Constants.LocalServer);
request.Content = streamContent;
request.Headers.TransferEncodingChunked = true;
HttpResponseMessage response = await httpClient.SendAsync(request);
But in response I get:
{
StatusCode: 501,
ReasonPhrase: 'NotImplemented',
Version: 1.0,
Content: System.Net.Http.StreamContent,
Headers: {
X-Squid-Error: ERR_UNSUP_REQ0X-Cache: MISSfromproxy3.itos.orgX-Cache-Lookup: NONEfromproxy3.companyname.org: portProxy-Connection: closeDate: Thu,
18Apr201309: 17: 53GMTServer: squid/2.6.STABLE21Via: 1.0proxy3.companyname.org: port(squid/2.6.STABLE21)Content-Length: 1099Content-Type: text/htmlExpires: Thu,
18Apr201309: 17: 53GMT
}
}
May be have another way to sent request with json parameter on Win8?
UPDATE I found solution:
public static async Task<string> LoadData(string json, string serverUrl)
{
var request = (HttpWebRequest)WebRequest.Create(new Uri(Constants.LocalServer));
request.ContentType = "application/json";
request.Method = "POST";
using (var requestStream = await request.GetRequestStreamAsync())
{
var writer = new StreamWriter(requestStream);
writer.Write(json);
writer.Flush();
}
using (var resp = await request.GetResponseAsync())
{
using (var responseStream = resp.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return = reader.ReadToEnd();
}
}
}
It's work great, but must exists more simple way(i hope). And I'll try to find it.
When I post data using your two code snippets, I see some differences in the requests.
Here is the raw post for the first code sample (that you say does not work):
POST http://testing.foo.com/api/Values HTTP/1.1
Host: testing.foo.com
Expect: 100-continue
Connection: Keep-Alive
Content-Length: 75
{
id:"1",
title:"title text",
post:"post text",
isDeleted:"False"
}
This is the raw post for the code in your update (code that you say works):
POST http://testing.foo.com/api/Values HTTP/1.1
Content-Type: application/json
Host: testing.foo.com
Content-Length: 75
Expect: 100-continue
{
id:"2",
title:"title text",
post:"post text",
isDeleted:"False"
}
The differences in the two requests are as follows:
In the first request, the content type is never set.
In the first request, the content is UTF8 encoded.
To fix your non-working code, I would suggest you try one or both of the following:
Set the content type to application/json
Not UTF8 encode the request
At that moment this solution is most useful.
public static async Task<string> LoadData(string json, string serverUrl)
{
var request = (HttpWebRequest)WebRequest.Create(new Uri(Constants.LocalServer));
request.ContentType = "application/json";
request.Method = "POST";
using (var requestStream = await request.GetRequestStreamAsync())
{
var writer = new StreamWriter(requestStream);
writer.Write(json);
writer.Flush();
}
using (var resp = await request.GetResponseAsync())
{
using (var responseStream = resp.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return = reader.ReadToEnd();
}
}
}

Categories

Resources