read/get http post data by shopify on url - c#

I have created a webhook
Order payment and given URL http://example.com/shopifydata.htm
Now I want to get all the data posted by shopify on order payment in C#
I have following code
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("http://example.com/shopifydata.htm");
myRequest.Method = "Get";
//if needs credential you can use myRequest.Credentials
using (HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse())
{
StreamReader mysr = new StreamReader(myResponse.GetResponseStream(), Encoding.GetEncoding("GB2312"));
//get the string content you can see what it is
string responseResult = mysr.ReadToEnd();
}
But I am not able to get anything
Where as when I use http://requestb.in/ I am able to get data. But can't get success on my site page
Please advise
Thanks

Related

OneLogin Create Session Login Token API returns status 400 with message: Bad Request

I am developing a C# application which needs to use the onelogin API to retrieve a session token. I am able to authenticate and and create a token with the following code:
WebRequest Authrequest = WebRequest.Create("https://api.us.onelogin.com/auth/oauth2/token");
Authrequest.Method = "POST";
Authrequest.ContentType = "application/json";
Authrequest.Headers.Add("cache-control", "no-cache");
Authrequest.Headers.Add("Authorization: client_id:XXXXXXX7bbf2c50200d8175206f664dc28ffd3ec66eef0bfedb68c3366420dc, client_secret:XXXXXXXXXX6ba2802187feb23f6450c6812b8e6639361d24aa83f12010f ");
using (var streamWriter = new StreamWriter(Authrequest.GetRequestStream()))
{
string Authjson = new JavaScriptSerializer().Serialize(new
{
grant_type = "client_credentials"
});
streamWriter.Write(Authjson);
}
WebResponse AuthReponse;
AuthReponse = Authrequest.GetResponse();
Stream receiveStream = AuthReponse.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream);
JObject incdata = JObject.Parse(readStream.ReadToEnd());
string sToken = incdata["data"][0]["access_token"].Value<string>();
AuthReponse.Close();
However, when running the Create Session Login Token with the following code, it only returns a 400 error, and the message has no detail. Just Bad Request:
//Get the session token for the specified user, using the token recieved from previous web request
WebRequest request = WebRequest.Create("https://api.us.onelogin.com/api/1/login/auth");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("authorization", "bearer:" + sToken);
using (var streamWriter2 = new StreamWriter(request.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(new
{
username_or_email = sUsername,
password = sPassword,
subdomain = "comp-alt-dev"
});
streamWriter2.Write(json);
}
WebResponse response;
response = request.GetResponse();
string streamText = "";
var responseStream = response.GetResponseStream();
using (responseStream)
{
var streamReader = new StreamReader(responseStream);
using (streamReader)
{
streamText = streamReader.ReadToEnd();
streamReader.Close();
//
}
responseStream.Close();
}
Any ideas?
-Thank you
Also for anyone who may be getting this error. in C# the email is case sensitive. I tried User.email.com. In onelogin it was saved as user#email.com. changing the c# to lower case fixed it.
Can you let us know what payload you're sending across the wire to the .../1/login/auth endpoint as well as the response (either as others have suggested as packet snoop, or just as a debug output from the code)
400 means either bad json or the endpoint requires MFA, so this will narrow it down.
~thanks!
Just joining the troubleshooting effort =) -- I can replicate a 400 Bad Request status code with a "bad request" message when the request body contains a username_or_email and/or subdomain value that does not exist, or if the request body is empty.
Can you post what goes over the wire to the OneLogin endpoint...
OK Thanks. So it appears your subdomain does not exist. If you give me an email in the account I can find the correct subdomain value for you.

Paypal PDT returns Fail always to my HTTP post request C# MVC

I am facing very weird kind of problem that after successful payment transaction, I am not able to get TransactionId appended with returningUrl. Since Paypal auto redirects me to my ReturnUrl which I have mentioned in PDT settings page, and Paypal appends the trasactionId to this returningUrl named tx and using that trasactionId I make a Post request to this Url
https://www.sandbox.paypal.com/cgi-bin/webscr
But here is the problem that I am not able to get that transactionId? what could be the problem kindly any body help me in this issue. This is my code that I am using to make an HTTP post request.
string authTokenTest = "sMfRi9rJN3AjqsejnMxFfkeIwhwrCmVZz3nplUy9V6a9Yq0_2YdugSvZYNa";
//used this but could not retrieved "tx"
//string txToken = Request.QueryString.Get("tx");
//Then used this but no use
var queryValues = HttpUtility.ParseQueryString(Request.Url.Query);
var txToken = queryValues["tx"];
string query = string.Format("cmd=_notify-synch&tx={0}&at={1}", txToken, authTokenTest);
//// Create the request back
string strSandbox = "https://www.sandbox.paypal.com/cgi-bin/webscr";
string url = strSandbox;
/// to use HTTP 1.1 and TLS 1.2
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
ServicePointManager.DefaultConnectionLimit = 9999;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
// Set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = query.Length;
// Write the request back IPN strings
StreamWriter stOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
stOut.Write(query);
stOut.Close();
// Do the request to PayPal and get the response
HttpWebResponse payResp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(payResp.GetResponseStream());
string strResponse = sr.ReadToEnd();
sr.Close();
If I make a direct request to this URL via browser and append a TransactionId and IdentityToken then I get the success response, but in this way I am not getting any way the transactionId and my Response is always Fail. Kindly help my in this problem. What could be the issue in my code or any other problem to resolve this issue. Thanks for your time.
I use MVC and so use model binding to get the tx value from the query string. But I don't think that's your problem.
The Return URL has to be set, as you said you did. Also PDT has to be turned on in the same place the URL is specified. Also, unfortunately, customers will not be returned automatically to your site if they use a credit card instead of a PayPal account.
I'm implementing IPN though because credit card customers may not return to the site.

How can i login to linkedin using HTTP POST Request with C#

I am working on a simple Windows Forms program that take a username and password from a "Textbox" then it show my linked-in name in a "Messagebox".
I want to accomplish the code with the using of "HttpWebRequest" or using any method to send my POST request to Linked-in then i can get the response and find my name to shown it in a "Messagebox".
I am familiar with creating a "GET" Request and also i made some "POST" Requests but in this case i didn't know how can i send my "txt_UserName.Text" and "txt_Password" with the POST Request and how can i receives the Response.
I tried to using Fiddler to capture POST request (=POST) from linkedin when i try to login but it captures more than 4 requests when i see the header of them it seem like a GET Request this is an example of one:
GET /nhome/?trk= HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
and all of them have a multiple cookies values.
This is my POST request code:
public void SubmitData()
{
try
{
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("http://www.linkedin.com");
// Set the Method property of the request to POST.
request.Method = "POST";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
//Content Length
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader sr = new StreamReader(dataStream);
MessageBox.Show(sr.ReadToEnd());
sr.Close();
dataStream.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
Now the only thing i wish to know, how can i send my username and password as a values to login to linked-in?
Edit:
Below is my second try, it's ok, i can now send the User and Password in postData and i can store the Cookies and retrive it. but there are two issues:
1- how can i make sure that the login is accomplished and not failed
2- if the login is accomplished i want to know what is the second step to get my name from profile, is it made another request or what ?
private void button1_Click(object sender, EventArgs e)
{
PostMessage();
}
private void PostMessage()
{
try {
// POST Data and the POST uri
string postData = "isJsEnabled=true&source_app=&session_key=" + textBox1.Text + "&session_password=" + textBox2.Text + "&signin=Sign+In&session_redirect=";
string uri = "https://www.linkedin.com/uas/login-submit";
// Encoding the POST Data
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Create the POST Request
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(uri);
//POST Parameters (Method and etc.)
WebReq.Method = "POST";
WebReq.ContentType = "application/x-www-form-urlencoded";
WebReq.ContentLength = byteArray.Length;
// Set the POST Request Cookies
var cookieContainer = new CookieContainer();
WebReq.CookieContainer = cookieContainer;
// Get the request stream.
Stream dataStream = WebReq.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
HttpWebResponse response = (HttpWebResponse)WebReq.GetResponse();
dataStream = response.GetResponseStream();
StreamReader sr = new StreamReader(dataStream);
//MessageBox.Show(sr.ReadToEnd());
sr.Close();
dataStream.Close();
if (response.StatusCode != HttpStatusCode.OK)
{
MessageBox.Show(" Error: " + response.StatusDescription);
response.Close();
}
foreach (Cookie cook in response.Cookies)
{
MessageBox.Show(cook.Name + " " + cook.Value);
}
}
catch (Exception ex)
{
MessageBox.Show("POST Message Error: " + ex.Message);
}
}
I used Fiddler while I was logging in and found a request to https://www.linkedin.com/uas/login-submit containing the username and password. Found it? Now, if you want to look at it completely from an HTTP Request perspective, you will have to figure out how to generate the other data in the post data/cookie header using the other requests and responses that your browser sent and received to and from the site before this particular request (the information should be there). I think this will lead you to what you need to do, but there's some work to be done!
You're going to need more than you think to log in there is good documentation on how to do this just here, you are going to need an auth token etc, This is because like other services, for example google, they are using oauth2 to secure applications etc.
oauth works by issuing tokens and refreshing tokens and there's a bit of a learning curve but its not especially difficult.
Essentially the following happens
You register your application with linked in and they give you a
client secret.
You pass this code to linked in in your application
and they will generate an auth screen saying that the application is
requesting permission.
you then approve this and it will give you an access token
You then log in with the access token (access tokens on linkedin are valid for 60 days, you must refresh them by this time).
On the plus side the linked in api is pretty straight forward and once authorised you will be able to get stuff pretty easily. All of this is detailed in the link provided in nice step by step stages.
By the way there is also a nuget package that gives you access to profile information.
Try Install-Package LinkedIn
I should point out that the nuget package above gives you a login provider to help authenticate if you don't want to roll your own.
Added after your comments below.
If all you want to do is know how to send a post request here's a generic bit of code that does just that:
string url = "www.foo.bar.com";
using (var webClient= new WebClient())
{
var data = new NameValueCollection();
data["username"] = "<yourusername>";
data["password"] = "<yourPassword>";
var response = webClient.UploadValues(url, "POST", data);
}
note: because its a web uri you should use POST in the method argument here.
The problem you up against is that Linkedin uses a redirect within the login session and is differcult to catch.
So somehow within the login session you need to code that it redirects to the https://www.linkedin.com/nhome/?trk= this provides the user page access.
I am also testing with this, however did not manage to figure this part out, normally
httpWebRequest.AllowAutoRedirect = true;
should do the trick but not in this case it does not work.
So if you find the solution let me know, if I find will post it also.

Help Rendering ASP.NET MVC View from a Console App

I have created an ASP.NET MVC View. On my MVC WebApp, it works great.
I would like to be able to (from a console app) render the View out as an HTML Email. I'm wondering what the best way to do this is going to be, the part I'm struggling with is Rendering the View.
Is there any way to do this from a console application?
The webapp simply calls a web-service and formats the data nicely so the console application will have access to the same web-service; however, the ActionResult on the controller is protected by [Authorize] attributes, so not just anyone can get at it.
Yes you can. I assume you are using forms authentication. Just authenticate, grab the session header cookie and copy it to your new web request.
I ended up using HttpWebRequest and the info provided here: http://odetocode.com/articles/162.aspx
From the article:
// first, request the login form to get the viewstate value
HttpWebRequest webRequest = WebRequest.Create(LOGIN_URL) as HttpWebRequest;
StreamReader responseReader = new StreamReader(
webRequest.GetResponse().GetResponseStream()
);
string responseData = responseReader.ReadToEnd();
responseReader.Close();
// extract the viewstate value and build out POST data
string viewState = ExtractViewState(responseData);
string postData =
String.Format(
"__VIEWSTATE={0}&UsernameTextBox={1}&PasswordTextBox={2}&LoginButton=Login",
viewState, USERNAME, PASSWORD
);
// have a cookie container ready to receive the forms auth cookie
CookieContainer cookies = new CookieContainer();
// now post to the login form
webRequest = WebRequest.Create(LOGIN_URL) as HttpWebRequest;
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.CookieContainer = cookies;
// write the form values into the request message
StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
requestWriter.Write(postData);
requestWriter.Close();
// we don't need the contents of the response, just the cookie it issues
webRequest.GetResponse().Close();
// now we can send out cookie along with a request for the protected page
webRequest = WebRequest.Create(SECRET_PAGE_URL) as HttpWebRequest;
webRequest.CookieContainer = cookies;
responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
// and read the response
responseData = responseReader.ReadToEnd();
responseReader.Close();
Response.Write(responseData);

How to make my web scraper log in to this website via C#

I have an application that reads parts of the source code on a website. That all works; but the problem is that the page in question requires the user to be logged in to access this source code. What my program needs a way to initially log the user into the website- after that is done, I'll be able to access and read the source code.
The website that needs to be logged into is:
mmoinn.com/index.do?PageModule=UsersLogin
You can continue using WebClient to POST (instead of GET, which is the HTTP verb you're currently using with DownloadString), but I think you'll find it easier to work with the (slightly) lower-level classes WebRequest and WebResponse.
There are two parts to this - the first is to post the login form, the second is recovering the "Set-cookie" header and sending that back to the server as "Cookie" along with your GET request. The server will use this cookie to identify you from now on (assuming it's using cookie-based authentication which I'm fairly confident it is as that page returns a Set-cookie header which includes "PHPSESSID").
POSTing to the login form
Form posts are easy to simulate, it's just a case of formatting your post data as follows:
field1=value1&field2=value2
Using WebRequest and code I adapted from Scott Hanselman, here's how you'd POST form data to your login form:
string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin"; // NOTE: This is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag
string formParams = string.Format("email_address={0}&password={1}", "your email", "your password");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
Here's an example of what you should see in the Set-cookie header for your login form:
PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_host=-
GETting the page behind the login form
Now you can perform your GET request to a page that you need to be logged in for.
string pageSource;
string getUrl = "the url of the page behind the login";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
EDIT:
If you need to view the results of the first POST, you can recover the HTML it returned with:
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
Place this directly below cookieHeader = resp.Headers["Set-cookie"]; and then inspect the string held in pageSource.
You can simplify things quite a bit by creating a class that derives from WebClient, overriding its GetWebRequest method and setting a CookieContainer object on it. If you always set the same CookieContainer instance, then cookie management will be handled automatically for you.
But the only way to get at the HttpWebRequest before it is sent is to inherit from WebClient and override that method.
public class CookieAwareWebClient : WebClient
{
private CookieContainer cookie = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = cookie;
}
return request;
}
}
var client = new CookieAwareWebClient();
client.BaseAddress = #"https://www.site.com/any/base/url/";
var loginData = new NameValueCollection();
loginData.Add("login", "YourLogin");
loginData.Add("password", "YourPassword");
client.UploadValues("login.php", "POST", loginData);
//Now you are logged in and can request pages
string htmlSource = client.DownloadString("index.php");
Matthew Brindley, your code worked very good for some website I needed (with login), but I needed to change to HttpWebRequest and HttpWebResponse otherwise I get a 404 Bad Request from the remote server. Also I would like to share my workaround using your code, and is that I tried it to login to a website based on moodle, but it didn't work at your step "GETting the page behind the login form" because when successfully POSTing the login, the Header 'Set-Cookie' didn't return anything despite other websites does.
So I think this where we need to store cookies for next Requests, so I added this.
To the "POSTing to the login form" code block :
var cookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.CookieContainer = cookies;
And To the "GETting the page behind the login form" :
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(resp.Cookies);
getRequest.Headers.Add("Cookie", cookieHeader);
Doing this, lets me Log me in and get the source code of the "page behind login" (website based moodle) I know this is a vague use of the CookieContainer and HTTPCookies because we may ask first is there a previously set of cookies saved before sending the request to the server. This works without problem anyway, but here's a good info to read about WebRequest and WebResponse with sample projects and tutorial:
Retrieving HTTP content in .NET
How to use HttpWebRequest and HttpWebResponse in .NET
Sometimes, it may help switching off AllowAutoRedirect and setting both login POST and page GET requests the same user agent.
request.UserAgent = userAgent;
request.AllowAutoRedirect = false;

Categories

Resources