Using Fiddler, I mimicked all the headers that were sent by an actual browser (Chrome).
Then I tried to call the function by
GetResponse("https://www.example.com/");
But get error:
An unhandled exception of type 'System.Net.WebException' occurred in System.dll
Additional information: The operation has timed out
Code:
public static string GetResponse(string sURL, CookieContainer cookies = null, string sParameters = "", string sUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36")
{
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(sURL);
httpRequest.UserAgent = sUserAgent;
if (cookies == null) cookies = new CookieContainer();
httpRequest.CookieContainer = cookies;
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
httpRequest.AllowAutoRedirect = true;
httpRequest.KeepAlive = true;
httpRequest.ProtocolVersion = HttpVersion.Version11;
httpRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
httpRequest.Headers.Add("Accept-Encoding", "gzip, deflate, br");
httpRequest.Headers.Add("Accept-Language", "en-US,en;q=0.8");
httpRequest.Headers.Add("upgrade-insecure-requests", "1");
httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
httpRequest.KeepAlive = true;
if (sParameters == "")
{
httpRequest.Method = "GET";
}
else
{
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
httpRequest.ContentLength = sParameters.Length;
using (Stream stream = httpRequest.GetRequestStream())
{
stream.Write(Encoding.UTF8.GetBytes(sParameters), 0, sParameters.Length);
}
}
HttpWebResponse httpWebResponse = (HttpWebResponse)httpRequest.GetResponse();
string sResponse;
using (Stream stream = httpWebResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding(936));
sResponse = reader.ReadToEnd();
}
return sResponse;
}
After inspecting in Fiddler, compared to a regular browser action, the missing part is cookies, however a cookiecontainer has been attached to the httpwebrequest object in the code. So I don't know why the cookie is missing.
Thank you for your help.
It may look a lot of stuff, but you don't need to be concerned with what this all does right now.
Just create a Button on a Form, then make async it's Click event handler as shown here (the main methods here use all async Http/IO .Net methods).
The remaining code just needs to be pasted (in the same Form, to make it quick).
The StreamObject used to pass data back and forth, after the connection is completed will contain some informations about the WebSite specified in its ResourceURI property (as below).
The StreamObject.Payload is the complete Html page, decoded using it's internal CodePage or the CodePage detected by the server.
If you want to see it, just pass it to a WebBrowser.
Note: I might have left out something, adapting this to be posted here. This will be immediately
obvious. In case, tell me what it is and I'll update this
code.
Also:
Disable Fiddler!
Visual Studio Version: VS Pro 15.7.5
.Net FrameWork: 4.7.1
private async void TestConnection_Click(object sender, EventArgs e)
{
StreamObject sObject = new StreamObject()
{
ResourceURI = new Uri(#"https://www.bestbuy.com/?intl=nosplash"),
ProcessStream = true
};
sObject = await HTTP_GetStream(sObject);
Console.WriteLine(sObject.Payload.Length);
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net.Security;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
public class StreamObject
{
public StreamObject()
{
this.Cookies = new CookieContainer();
}
public Stream ContentStream { get; set; }
public bool ProcessStream { get; set; }
public Uri ResourceURI { get; set; }
public Uri ResponseURI { get; set; }
public string Referer { get; set; }
public string Payload { get; set; }
public string ServerType { get; set; }
public string ServerName { get; set; }
public IPAddress[] ServerIP { get; set; }
public string ContentName { get; set; }
public string ContentType { get; set; }
public string ContentCharSet { get; set; }
public string ContentLanguage { get; set; }
public long ContentLenght { get; set; }
public HttpStatusCode StatusCode { get; set; }
public string StatusDescription { get; set; }
public WebExceptionStatus WebException { get; set; }
public string WebExceptionDescription { get; set; }
public CookieContainer Cookies { get; set; }
}
const uint COR_E_INVALIDOPERATION = 0x80131509;
public async Task<StreamObject> HTTP_GetStream(StreamObject RequestObject)
{
if (string.IsNullOrEmpty(RequestObject.ResourceURI.ToString().Trim()))
return null;
MemoryStream memstream = new MemoryStream();
HttpWebRequest httpRequest;
CookieContainer CookieJar = new CookieContainer();
HttpStatusCode StatusCode = HttpStatusCode.OK;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 10;
ServicePointManager.ServerCertificateValidationCallback += TlsValidationCallback;
httpRequest = WebRequest.CreateHttp(RequestObject.ResourceURI);
try
{
HTTP_RequestHeadersInit(ref httpRequest, CookieJar, RequestObject);
httpRequest.Method = "GET";
using (HttpWebResponse httpResponse = (HttpWebResponse)await httpRequest.GetResponseAsync())
{
Stream ResponseStream = httpResponse.GetResponseStream();
//SslProtocols Protocol = ExtractSslProtocol(ResponseStream);
if (StatusCode == HttpStatusCode.OK)
{
await ResponseStream.CopyToAsync(memstream);
RequestObject.ContentStream = memstream;
RequestObject.ResponseURI = httpResponse.ResponseUri;
RequestObject.ContentLenght = memstream.Length;
RequestObject.ContentCharSet = httpResponse.CharacterSet ?? string.Empty;
RequestObject.ContentLanguage = httpResponse.Headers["Content-Language"] ?? string.Empty;
RequestObject.ContentType = httpResponse.ContentType.ToLower();
if (RequestObject.ContentType.IndexOf(#"/") > -1)
{
do {
RequestObject.ContentType = RequestObject.ContentType.Substring(RequestObject.ContentType.IndexOf(#"/") + 1);
if (RequestObject.ContentType.IndexOf(#"/") < 0)
break;
} while (true);
if (RequestObject.ContentType.IndexOf(";")> -1)
RequestObject.ContentType = RequestObject.ContentType.Substring(0, RequestObject.ContentType.IndexOf(#";"));
RequestObject.ContentType = "." + RequestObject.ContentType;
}
RequestObject.ContentName = httpResponse.Headers["Content-Disposition"] ?? string.Empty;
if (RequestObject.ContentName.Length == 0)
RequestObject.ContentName = RequestObject.ResourceURI.Segments.Last();
RequestObject.ServerType = httpResponse.Server;
RequestObject.ServerName = RequestObject.ResponseURI.DnsSafeHost;
RequestObject.ServerIP = await Dns.GetHostAddressesAsync(RequestObject.ServerName);
RequestObject.StatusCode = StatusCode;
RequestObject.StatusDescription = httpResponse.StatusDescription;
if (RequestObject.ProcessStream)
RequestObject.Payload = ProcessResponse(RequestObject.ContentStream,
Encoding.GetEncoding(RequestObject.ContentCharSet),
httpResponse.ContentEncoding);
}
}
}
catch (WebException exW)
{
if (exW.Response != null)
{
RequestObject.StatusCode = ((HttpWebResponse)exW.Response).StatusCode;
RequestObject.StatusDescription = ((HttpWebResponse)exW.Response).StatusDescription;
}
RequestObject.WebException = exW.Status;
RequestObject.WebExceptionDescription = exW.Message;
}
catch (Exception exS)
{
if ((uint)exS.HResult == COR_E_INVALIDOPERATION)
{
//RequestObject.WebException = PingHostAddress("8.8.8.8", 500) > 0
// ? WebExceptionStatus.NameResolutionFailure
// : WebExceptionStatus.ConnectFailure;
RequestObject.WebException = WebExceptionStatus.ConnectFailure;
RequestObject.WebExceptionDescription = RequestObject.WebException.ToString();
}
else
{
RequestObject.WebException = WebExceptionStatus.RequestCanceled;
RequestObject.WebExceptionDescription = RequestObject.WebException.ToString();
}
}
finally
{
ServicePointManager.ServerCertificateValidationCallback -= TlsValidationCallback;
}
RequestObject.Cookies = httpRequest.CookieContainer;
RequestObject.StatusCode = StatusCode;
return RequestObject;
} //HTTP_GetStream
private bool TlsValidationCallback(object sender, X509Certificate CACert, X509Chain CAChain, SslPolicyErrors sslPolicyErrors)
{
//if (sslPolicyErrors == SslPolicyErrors.None)
// return true;
X509Certificate2 _Certificate = new X509Certificate2(CACert);
//X509Certificate2 _CACert = new X509Certificate2(#"[localstorage]/ca.cert");
//CAChain.ChainPolicy.ExtraStore.Add(_CACert);
//X509Certificate2 cert = GetCertificateFromStore(thumbprint);
X509Certificate2 cert = (X509Certificate2)CACert;
//CspKeyContainerInfo cpsKey = (CspKeyContainerInfo)((RSACryptoServiceProvider)cert.PublicKey.Key).CspKeyContainerInfo;
//if (cert.HasPrivateKey) { RSA rsaKey = (RSA)cert.GetRSAPrivateKey(); }
//if (cpsKey.Accessible) { Console.WriteLine("Exportable: {0}", cpsKey.Exportable); }
// next line generates exception "Key does not exist"
//bool isexportable = provider.CspKeyContainerInfo.Exportable;
CAChain.Build(_Certificate);
foreach (X509ChainStatus CACStatus in CAChain.ChainStatus)
{
if ((CACStatus.Status != X509ChainStatusFlags.NoError) &
(CACStatus.Status != X509ChainStatusFlags.UntrustedRoot))
return false;
}
return true;
}
private void HTTP_RequestHeadersInit(ref HttpWebRequest httpreq, CookieContainer cookiecontainer, StreamObject postdata)
{
httpreq.Date = DateTime.Now;
httpreq.Timeout = 30000;
httpreq.ReadWriteTimeout = 30000;
httpreq.CookieContainer = cookiecontainer;
httpreq.KeepAlive = true;
httpreq.AllowAutoRedirect = true;
httpreq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
httpreq.ServicePoint.MaxIdleTime = 30000;
httpreq.Referer = postdata.Referer;
httpreq.UserAgent = "Mozilla / 5.0(Windows NT 6.1; WOW64; Trident / 7.0; rv: 11.0) like Gecko";
//httpreq.UserAgent = "Mozilla/5.0 (Windows NT 10; Win64; x64; rv:56.0) Gecko/20100101 Firefox/61.0";
httpreq.Accept = "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
httpreq.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US;q=0.8,en-GB;q=0.5,en;q=0.3");
httpreq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8");
httpreq.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");
httpreq.Headers.Add("DNT", "1");
if (postdata != null && postdata.UseProxy)
{
if (postdata.ProxyParameters != null)
{
if ((postdata.ProxyParameters.Host.Length > 0))
{
httpreq.Proxy = new WebProxy(postdata.ProxyParameters.Host, postdata.ProxyParameters.Port);
}
else
{
httpreq.Proxy = new WebProxy(postdata.ProxyParameters.Uri, postdata.ProxyParameters.BypassLocal);
}
httpreq.Proxy.Credentials = new NetworkCredential(postdata.ProxyParameters.Credentials.UserID,
postdata.ProxyParameters.Credentials.Password);
}
else
{
httpreq.Proxy = WebRequest.GetSystemWebProxy();
}
}
}
private string ProcessResponse(Stream stream, Encoding encoding, string ContentEncoding)
{
string html = string.Empty;
stream.Position = 0;
try
{
using (MemoryStream memStream = new MemoryStream())
{
if (ContentEncoding.Contains("gzip"))
{
using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress))
{
gzipStream.CopyTo(memStream);
};
}
else if (ContentEncoding.Contains("deflate"))
{
using (DeflateStream deflStream = new DeflateStream(stream, CompressionMode.Decompress))
{
deflStream.CopyTo(memStream);
};
}
else
{
stream.CopyTo(memStream);
}
memStream.Position = 0;
using (StreamReader reader = new StreamReader(memStream, encoding))
{
html = reader.ReadToEnd();
html = DecodeMetaCharSetEncoding(memStream, html, encoding);
};
};
}
catch (Exception)
{
return string.Empty;
}
return html;
}
private string DecodeMetaCharSetEncoding(Stream memStream, string _html, Encoding _encode)
{
Match _match = new Regex("<meta\\s+.*?charset\\s*=\\s*\"?(?<charset>[A-Za-z0-9_-]+)\"?",
RegexOptions.Singleline |
RegexOptions.IgnoreCase).Match(_html);
if (_match.Success)
{
string charset = _match.Groups["charset"].Value.ToLower() ?? "utf-8";
if ((charset == "unicode") | (charset == "utf-7") | (charset == "utf-16"))
charset = "utf-8";
try
{
Encoding metaEncoding = Encoding.GetEncoding(charset);
if (_encode.WebName != metaEncoding.WebName)
{
memStream.Position = 0L;
using (StreamReader recodeReader = new StreamReader(memStream, metaEncoding))
{ _html = recodeReader.ReadToEnd().Trim(); }
}
}
catch (ArgumentException)
{
_html = string.Empty;
}
catch (Exception)
{
_html = string.Empty;
}
}
return _html;
}
Related
How I can change this function to async with Framework 4.6.1? The DGV has a lot of data and blocks the rest of the processes.
DGV is updated every 30 seconds with timer.
any other solution do not block the next process until this is finnished?
I may have something wrong, I am starting in the world of programming and I have many things to learn.
private void FillTimes()
{
var strResponse = CallJson($"RESTAPI URL");
if (strResponse != null)
{
var jResult = JsonConvert.DeserializeObject<JsonResults>(strResponse);
BindingSource bsResults = new BindingSource();
bsResults.DataSource = jResult.Results;
if (bsResults.DataSource != null)
{
DgvOnline.DataSource = bsResults.DataSource;
}
}
}
CallJson
private string CallJson(string strURL)
{
RestTiming rJson = new RestTiming();
rJson.endPoint = strURL;
rJson.token = apiToken;
string strResponse = string.Empty;
strResponse = rJson.makeRequest();
return strResponse;
}
ResTiming
using System;
using System.IO;
using System.Net;
using System.Windows.Forms;
namespace Timing
{
public enum httpVerb
{
GET,
POST,
PUT,
DELETE
}
class RestTiming
{
public string endPoint { get; set; }
public string token { get; set; }
public httpVerb httpMethod { get; set; }
public string userName { get; set; }
public string userPassword { get; set; }
public string postJSON { get; set; }
public RestTiming()
{
endPoint = string.Empty;
token = string.Empty;
}
public string makeRequest()
{
if (InternetAvailable())
{
string strResponseValue = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = httpMethod.ToString();
request.ContentType = "application/json";
request.Accept = "application/json";
request.Headers.Add("Authorization", token);
request.UserAgent = #"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";
if ((request.Method == "POST" || request.Method == "PUT") && postJSON != string.Empty)
{
using (StreamWriter swJSONPayload = new StreamWriter(request.GetRequestStream()))
{
swJSONPayload.Write(postJSON);
swJSONPayload.Close();
}
}
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
// Process the response stream... (could be JSON, XML or HTML etc...)
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
strResponseValue = reader.ReadToEnd();
}// End of StreamReader
}
}// End of using ResponseStream
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.Unauthorized)
{
MessageBox.Show("Unauthorized", "Unauthorized", MessageBoxButtons.OK, MessageBoxIcon.Stop);
Environment.Exit(1);
}
}
}
return strResponseValue;
}
else
{
return null;
}
}
private static Boolean InternetAvailable()
{
try
{
using (WebClient client = new WebClient())
{
using (client.OpenRead("http://www.google.com/"))
{
return true;
}
}
}
catch
{
return false;
}
}
}
}
Thanks
I'm not going to weigh in on whether your code should be async or not.
If you want the synchronous work to happen in a background thread, you can execute it using Task.Run as follows:
private async Task FillTimes()
{
return Task.Run(() => {
{
var strResponse = CallJson($"RESTAPI URL");
if (strResponse != null)
{
var jResult = JsonConvert.DeserializeObject<JsonResults>(strResponse);
BindingSource bsResults = new BindingSource();
bsResults.DataSource = jResult.Results;
if (bsResults.DataSource != null)
{
DgvOnline.DataSource = bsResults.DataSource;
}
}
}
}
Update
If CallJson is IO Bound work then you could make that async, also you would append the Async suffix to the the method name to be consistent. Your resulting method would look like this.
private async Task FillTimes()
{
var strResponse = await CallJsonAsync($"RESTAPI URL");
if (strResponse != null)
{
var jResult = JsonConvert.DeserializeObject<JsonResults>(strResponse);
BindingSource bsResults = new BindingSource();
bsResults.DataSource = jResult.Results;
if (bsResults.DataSource != null)
{
DgvOnline.DataSource = bsResults.DataSource;
}
}
}
And your async method would look like this
private async Task<responseType> CallJsonAsync(<something>)
{
...
await SomethingAsync(...);
...
return something;
}
Original
How I can change this function to async with Framework 4.6.1
There is no obvious IO Bound work, and no method that would lend itself towards an async call (that i can see).
So to answer the question, "How I can change this function to async?", the answer is you shouldn't, let it be synchronous.
If this does not update the UI, you could call this method from a Task, and await that
Updated
class RestTiming
{
public string endPoint { get; set; }
public string token { get; set; }
public httpVerb httpMethod { get; set; }
public string userName { get; set; }
public string userPassword { get; set; }
public string postJSON { get; set; }
public RestTiming()
{
endPoint = string.Empty;
token = string.Empty;
}
public async Task<string> makeRequest() //1. Changed to async and return type
{
if (InternetAvailable())
{
string strResponseValue = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = httpMethod.ToString();
request.ContentType = "application/json";
request.Accept = "application/json";
request.Headers.Add("Authorization", token);
request.UserAgent = #"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";
if ((request.Method == "POST" || request.Method == "PUT") && postJSON != string.Empty)
{
using (StreamWriter swJSONPayload = new StreamWriter(await request.GetRequestStreamAsync())) //2. changed to asynchronous call
{
swJSONPayload.Write(postJSON);
swJSONPayload.Close();
}
}
WebResponse response = null; //(a) updated
try
{
response =await request.GetResponseAsync();
// Process the response stream... (could be JSON, XML or HTML etc...)
using (Stream responseStream =response.GetResponseStream()) //(b) updated
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
strResponseValue = await reader.ReadToEndAsync(); // (c) updated
}// End of StreamReader
}
}// End of using ResponseStream
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
{
var resp = (HttpWebResponse)ex.Response;
if (resp.StatusCode == HttpStatusCode.Unauthorized)
{
MessageBox.Show("Unauthorized", "Unauthorized", MessageBoxButtons.OK, MessageBoxIcon.Stop);
Environment.Exit(1);
}
}
}
return strResponseValue;
}
else
{
return null;
}
}
private static Boolean InternetAvailable()
{
try
{
using (WebClient client = new WebClient())
{
using (client.OpenRead("http://www.google.com/"))
{
return true;
}
}
}
Changes in the second method
private async Task<string> CallJson(string strURL) //1. Changed to async and return type
{
RestTiming rJson = new RestTiming();
rJson.endPoint = strURL;
rJson.token = apiToken;
string strResponse = string.Empty;
strResponse =await rJson.makeRequest(); //2. made asynchronous
return strResponse;
}
The change in the first method
private async Task FillTimes() // 1. Make async and change return type
{
var strResponse =await CallJson($"RESTAPI URL"); // 2. add await to make asynchronous
...
}
Please let me know if this helps.
Additionally, check this link (Getting the Response of a Asynchronous HttpWebRequest)
Trying to call REST service using C# application:
namespace SrvClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public class RestClient
{
public string EndPoint { get; set; }
public HttpVerb Method { get; set; }
public string ContentType { get; set; }
public string PostData { get; set; }
public RestClient()
{
EndPoint = "";
Method = HttpVerb.GET;
ContentType = "text/xml";
PostData = "";
}
public RestClient(string endpoint)
{
EndPoint = endpoint;
Method = HttpVerb.GET;
ContentType = "text/xml";
PostData = "";
}
public RestClient(string endpoint, HttpVerb method)
{
EndPoint = endpoint;
Method = method;
ContentType = "text/xml";
PostData = "";
}
public RestClient(string endpoint, HttpVerb method, string postData)
{
EndPoint = endpoint;
Method = method;
ContentType = "text/xml";
PostData = postData;
}
public string MakeRequest()
{
return MakeRequest("");
}
public string MakeRequest(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create(EndPoint + parameters);
request.Method = Method.ToString();
request.ContentLength = 0;
request.ContentType = ContentType;
if (!string.IsNullOrEmpty(PostData) && Method == HttpVerb.PUT)
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(PostData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// grab the response
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
return responseValue;
}
}
} // class
private void button1_Click(object sender, EventArgs e)
{
var client = new RestClient();
client.EndPoint = #"http://localhost:11332";
client.Method = HttpVerb.GET;
client.PostData = "{postData: value}";
var json = client.MakeRequest("/Account/Login");
}
}
}
As call result I have string:
"<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\t<meta charset=\"utf-8\" />\r\n\t<title>Login - My ASP.NET Application</title>\r\n\t\r\n</head>\r\n<body>\r\n\t\t<p>Welcome login)</p>\r\n\t\r\n\r\n\r\n<h2>Login</h2>\r\n\r\n<form action=\"/Account/Login\" method=\"post\"><input name=\"__RequestVerificationToken\" type=\"hidden\" value=\"_fykbIPsr7u1kGba8zUirPqbqnMG_-eyztTSwSJxB3XksVdrUrLWjsyC9NXWugXn34AxZerny4coFb5_6ILNpMmmG4GZgI-U_Oqhl1VQSzk1\" />\t<p>username:<br /><input class=\"text-box single-line\" id=\"UserName\" name=\"UserName\" type=\"text\" value=\"\" /></p>\r\n\t<p>pin:<br /><input class=\"text-box single-line\" id=\"Pin\" name=\"Pin\" type=\"text\" value=\"\" /></p>\r\n\t<p><input type=\"submit\" value=\"login\" /></p>\r\n</form>\r\n\t<script type=\"text/javascript\" src=\"/Content/js/jquery-2.1.4.min.js\"></script>\r\n\t<script type=\"text/javascript\" src=\"/Content/js/jquery-ui-1.11.4.min.js\"></script>\r\n\t\r\n\r\n<!-- Visual Studio Browser Link -->\r\n<script type=\"application/json\" id=\"__browserLink_initializationData\">\r\n {\"appName\":\"Unknown\",\"requestId\":\"fba1d156c3114ecbbe989a83cd4616c7\"}\r\n</script>\r\n<script type=\"text/javascript\" src=\"http://localhost:21213/b011fdffd90446038f2d9d01cd2a32bf/browserLink\" async=\"async\"></script>\r\n<!-- End Browser Link -->\r\n\r\n</body>\r\n</html>\r\n"
Looks like I need to login. How to make login call in this case?
I am working on a requirement where I need to create multiple issues in one go by Using the REST API. However, I start with uploading a single issue because I am new in API integration. I write few lines of code in c#. Here is my code:
static void Main(string[] args)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
JiraCreateIssueRequest jcir = new JiraCreateIssueRequest();
//////////////////////////////////////////////////////////////////
string sUsername = "aaa#xyz.com";
string sPassword = "TestPassword";
string uri = #"https://domain.atlassian.net/rest/api/2/issue";
Uri address = new Uri(uri);
HttpWebRequest request;
//HttpWebResponse response = null;
StreamReader sr;
string sData = null;
string returnXML = string.Empty;
if (address == null) { throw new ArgumentNullException("address"); }
//jcir.project.ID = 100;
//jcir.Summary = "This issue is created by JIRA REST Api";
//jcir.Description = "This issue is created by JIRA REST Api";
//jcir.IssueType.ID = 1;
sData = #"{""fields"":{""project"":{""key"": ""SITT""},""summary"": ""REST API Uploading"",""description"":""Creating an issue via REST API"",""issuetype"": {""name"": ""Test""}}}";
//sData = jcir.ToString();
try
{
// Create and initialize the web request
request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
// Add the Authorization header to the web request
request.Credentials = new NetworkCredential(sUsername, sPassword);
//Write Data
if (sData != null)
{
byte[] byteData = UTF8Encoding.UTF8.GetBytes(sData);
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
string str = reader.ReadToEnd();
}
}
}
catch (WebException wex)
{
// This exception will be raised if the server didn't return 200 - OK
// Try to retrieve more information about the error
if (wex.Response != null)
{
using (HttpWebResponse errorResponse = (HttpWebResponse)wex.Response)
{
try
{
string sError = string.Format("The server returned '{0}' with the status code {1} ({2:d}).",
errorResponse.StatusDescription, errorResponse.StatusCode,
errorResponse.StatusCode);
sr = new StreamReader(errorResponse.GetResponseStream(), Encoding.UTF8);
returnXML = sr.ReadToEnd();
}
finally
{
if (errorResponse != null) errorResponse.Close();
}
}
}
else
{
throw new Exception(wex.Message);
}
}
}
public class JiraCreateIssueRequest
{
protected JavaScriptSerializer jss = new JavaScriptSerializer();
public JiraProject project = new JiraProject();
public string Summary { get; set; }
public string Description { get; set; }
public JiraIssueType IssueType = new JiraIssueType();
public override string ToString()
{
return jss.Serialize(this);
}
}
public class JiraCreateIssueResponse
{
}
public class JiraProject
{
public int ID { get; set; }
//public string Key { get; set; }
}
public class JiraIssueType
{
public int ID { get; set; }
//public string Name { get; set; }
}
But when I am running the above code, I am getting the '400' error. I googled it and found that this usually this error comes when the URL or the Username/Password are incorrect. I cross checked both the things however its correct.
May I know why this error is coming or what will be the resolution of the problem?
Your password is not your login password, it's an API token that you get from here:
https://id.atlassian.com/manage/api-tokens
Generate a token, then use that as your password.
I have following nested JSON:
{"Command":"helo",
"parameter" : {"Configured":false, "ApplicationString":"Something", "Hostname":"some",
"IPAddress":"0.0.0.0",
"UniqueID":"",
"Username":"me"}}
And I need to pass this string as JSON object to POST call to my web service in C#. Could anyone help me how to do this step?
Note: I am able to pass simple JSON like below:
var request = (HttpWebRequest)WebRequest.Create("http://localhost:8084");
request.ContentType = "text/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
Command = "test",
name="pooja"
});
streamWriter.Write(json);
}
If I follow the same way to pass nested json like below :
string json = new JavaScriptSerializer().Serialize(new
{
Command = "test",
parameter = new JavaScriptSerializer().Serialize(new
{
Command = "test",
}),
});
I get below output :
{"Command":"test","parameter":"{\"Command\":\"test\"}"}
Let me know if you have any issues.
void Main()
{
CommandParamater exampleCommand = new CommandParamater
{
Command = "Foo",
Parameter = new Parameter
{
ApplicationString = "App String Foo",
Configured = true,
Hostname = "Bar",
IPAddress = "8.8.8.8",
UniqueID = Guid.NewGuid().ToString(),
Username = "FooBar"
}
};
string uri = "http://localhost:8084";
string data = JsonConvert.SerializeObject(exampleCommand);
Html htmlClient = new Html();
htmlClient.Post(uri, data, "application/json");
}
public class Html
{
public string Post(string uri, string data, string contentType)
{
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.ContentType = contentType;
request.ContentLength = dataBytes.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(dataBytes, 0, dataBytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
public class Parameter
{
[JsonProperty("Configured")]
public bool Configured { get; set; }
[JsonProperty("ApplicationString")]
public string ApplicationString { get; set; }
[JsonProperty("Hostname")]
public string Hostname { get; set; }
[JsonProperty("IPAddress")]
public string IPAddress { get; set; }
[JsonProperty("UniqueID")]
public string UniqueID { get; set; }
[JsonProperty("Username")]
public string Username { get; set; }
}
public class CommandParamater
{
[JsonProperty("Command")]
public string Command { get; set; }
[JsonProperty("parameter")]
public Parameter Parameter { get; set; }
}
It may help you.
private string MakeRequest(string uri, string jsnPostData, string method)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
if (request != null)
{
request.Method = method;
request.Timeout = 2000000;
request.ContentType = "application/json";
request.KeepAlive = true;
byte[] data = Encoding.UTF8.GetBytes(jsnPostData);
Stream dataStream = request.GetRequestStream();
dataStream.Write(data, 0, data.Length);
dataStream.Close();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string result = new StreamReader(response.GetResponseStream()).ReadToEnd();
return result;
}
else
return "";
}
catch (Exception ex)
{
Response.Write("<b>Error :</b>" + ex.Message + "</br>");
return "";
}
}
I got the following problem:
I am trying to implement Instagram into my website. However I am stuck on the step where I need to get the Acces token. The api's documentation says I need to request it like this :
curl \-F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri=YOUR-REDIRECT-URI' \
-F 'code=CODE' \https://api.instagram.com/oauth/access_token
I use ASP.NET so I found this equivalent OAuth 2.0 In .NET With Instagram API:
NameValueCollection parameters = new NameValueCollection();
parameters.Add("client_id", "ssdfsdfsdfsdfsdf");
parameters.Add("client_secret", "sdsdfdsfsdfsdfsdfsdfsdf");
parameters.Add("grant_type", "authorization_code");
parameters.Add("redirect_uri", "http://localhost:2422/LoginsGuests/GetLoginPage");
parameters.Add("code", code);
WebClient client = new WebClient();
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", parameters);
var response = System.Text.Encoding.Default.GetString(result);
However I keep getting:
System.Net.WebException: The remote server returned an error: (400) Bad Request.
What I am i doing wrong?
Almost there the instagram api expects a POST not a GET.
Add the "POST" parameter.
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "POST", parameters);
Also check the instagram settings -> redirect url.
Then this may help don't forget to add a reference to Newtonsoft.Json. Is in .Net version 4.5.1:
using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;
namespace Instagram
{
public class InstagramClient
{
public InstagramClient(string code)
{
GetToken(code);
}
private void GetToken(string code)
{
using (var wb = new WebClient())
{
var parameters = new NameValueCollection
{
{"client_id", "ClientId"},
{"client_secret", "ClientSecret"},
{"grant_type", "authorization_code"},
{"redirect_uri", "RedirectUri"},
{"code", code}
};
var response = wb.UploadValues("https://api.instagram.com/oauth/access_token", "POST", parameters);
string json = Encoding.ASCII.GetString(response);
try
{
var OauthResponse = (InstagramOAuthResponse) Newtonsoft.Json.JsonConvert.DeserializeObject(json, typeof(InstagramOAuthResponse));
}
catch (Exception ex)
{
//handle ex if needed.
}
}
}
public class InstagramOAuthResponse
{
public string access_token { get; set; }
public User user { get; set; }
}
public class User : System.Security.Principal.IIdentity
{
public string username { get; set; }
public string website { get; set; }
public string profile_picture { get; set; }
public string full_name { get; set; }
public string bio { get; set; }
public string id { get; set; }
public string OAuthToken { get; set; }
public string AuthenticationType
{
get { return "Instagram"; }
}
public bool IsAuthenticated
{
get { return !string.IsNullOrEmpty(id); }
}
public string Name
{
get
{
return String.IsNullOrEmpty(full_name) ? "unknown" : full_name;
}
}
}
}
}
If you prefer HttpWebRequest class:
var request = (HttpWebRequest)WebRequest.Create("https://api.instagram.com/oauth/access_token/");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var requestDetails = "client_id=" + AppConfig.InstagramClientId;
requestDetails += "&client_secret=" + AppConfig.InstagramClientSecret;
requestDetails += "&grant_type=authorization_code";
requestDetails += "&redirect_uri=" + redirectUrl;
requestDetails += "&code=" + exchangeCode;
byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
request.ContentLength = bytes.Length;
using (Stream outputStream = request.GetRequestStream())
{
outputStream.Write(bytes, 0, bytes.Length);
}
var response = request.GetResponse();
var code = ((HttpWebResponse)response).StatusCode;
if (code == HttpStatusCode.OK)
{
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var jsonString = streamReader.ReadToEnd();
var accessToken = ParseAccessToken(jsonString);
return accessToken;
}
}