I am migrating an old classic asp project over to ASP.NET, but as it is such a big old thing I am doing it in pieces. So I am at a stage where I need them to work together.
The files for both classic asp and .NET are all in the same project.
The old classic asp project uses Session variables (the new .NET project doesn't), so I am attempting to call a classic ASP page to do that.
This is the classic asp "bridge":
<!--#include virtual="/members/includes/db.config.asp" -->
<!--#include virtual="/members/includes/classes/clsLogin.asp" -->
<!--#include virtual="/members/includes/classes/clsAccess.asp" -->
<!--#include virtual="/members/includes/classes/clsUser.asp" -->
<!--#include virtual="/members/includes/classes/clsEntity.asp" -->
<!--#include virtual="/members/includes/classes/Database/clsDatabase.asp" -->
<!--#include virtual="/members/includes/classes/Helper/clsSessionVars.asp" -->
<!--#include virtual="/members/includes/classes/Helper/clsGlobal.asp" --><%'This file has global functions '%>
<%
Dim userId : userId = CStr(Request.QueryString("userId"))
Dim username : username = Cstr(Request.QueryString("username"))
Dim objAccess : Set objAccess = new clsAccess
Dim objDb : Set objDb = new clsDatabase
Dim objUser : Set objUser = new clsUser
Dim objLogin : Set objLogin = new clsLogin
Dim objEntity : Set objEntity = new clsEntity
'Set user session etc.
if(Request.QueryString("function") = "session") then
Dim userRecord : Set userRecord = objUser.GetUserById(userId)
Dim rsEntity : Set rsEntity = objEntity.GetById(userRecord("EntityId"))
'Login classic asp : Sets the session variables.
Call objLogin.LoginUser(userRecord, username, rsEntity)
'Kill the session i.e. Log out
elseif(Request.QueryString("function") = "kill") then
Session.Contents.RemoveAll()
Session.Abandon()
Response.Write("Session Killed")
End if
%>
However, I am having real problems being able to call this from the .NET Controller and get the session variables stored.
I tried with a FileWebRequest:
private void SetClassicASPSessionVars(ApplicationUser user)
{
try
{
string url = "~/members/includes/classes/aspbridge.asp" + "?function=session&userId=" + Url.Encode(user.UserId.ToString()) + "&username=" + Url.Encode(user.UserName);
Uri serverUri = new Uri(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverUri);
request.Method = "POST";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader reader = new StreamReader(response.GetResponseStream());
var content = reader.ReadToEnd();
}
}
catch (WebException we)
{
throw new InvalidOperationException("Error logging in user to classic asp system. User: " + user.UserId + ". Exception: " + we);
}
}
This only read the file and didn't execute the script, so it only returned the source code and didn't create the session variables.
I've also tried with HttpWebRequest:
try
{
string url = "/members/includes/classes/aspbridge.asp" + "?function=session&userId=" + Url.Encode(user.UserId.ToString()) + "&username=" + Url.Encode(user.UserName);
Uri serverUri = new Uri(url, UriKind.Absolute);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serverUri);
request.Method = "POST";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
StreamReader reader = new StreamReader(response.GetResponseStream());
var content = reader.ReadToEnd();
}
}
catch (WebException we)
{
throw new InvalidOperationException("Error logging in user to classic asp system. User: " + user.UserId + ". Exception: " + we);
}
However, I get the error:
Invalid URI: The format of the URI could not be determined.
Can someone please offer me some guidance how I can get the .NET controller to call the classic ASP page.
Thanks in advance,
Rhys
The reason you're getting the URI error is because WebRequest does not send to requests to relative paths to your application, instead it needs an absolute path. It basically needs to reach URL's as a standard web browser would.
Therefore, make sure your URL has a full path/host:
string url = "http://localhost/members/includes/classes/aspbridge.asp" + "?function=session&userId=" + Url.Encode(user.UserId.ToString()) + "&username=" + Url.Encode(user.UserName);
I used localhost here as an example. You would want to set the host to the same host as the calling script obviously.
NOTE: I'm still not sure this will entirely accomplish your objecting of capturing a Classic ASP session in .NET, but this should be a better start.
Related
I'm trying to scrape a web page hosted on a device on my network. I've done this dozens of times with other model devices on the same network. When I browse to the page in IE or Chrome, it's formatted properly and I see the source I'm expecting.
However, when I try to read the response stream in .Net or try running it in Fiddler, I'm given source for what looks like Javascript and session generating scripting rather than the numbers I care about.
I think this page is now hitting a javascript powered landing page, calling back to the printer, then formatting and outputting back into my browser. I think my difference is that calls from inside of Fiddler and .Net GetResponseStream() calls aren't letting the javascript do what it needs to to get all of the data.
Sample
WebRequest ConReq = WebRequest.Create(consumablePage);
WebRequest UseReq = WebRequest.Create(usagePage);
ConReq.Timeout = 15000;
UseReq.Timeout = 20000;
WebResponse ConResp = ConReq.GetResponse();
WebResponse UseResp = UseReq.GetResponse();
Stream Constream = ConResp.GetResponseStream();
StreamReader Consr = new StreamReader(Constream);
Stream Usestream = UseResp.GetResponseStream();
StreamReader Usesr = new StreamReader(Usestream);
string conRead = Consr.ReadToEnd();
string useRead = Usesr.ReadToEnd();
At the end, conRead and useRead both contain:
"<html>\r\n<head>\r\n<script language=\"JavaScript\" type=\"text/javascript\">\r\n<!-- \r\nfunction SetCookie ( inCookieName, inCookieValue, inCookieExpiration)\r\n{\r\n\tdocument.cookie\t\t= inCookieName + \"=\" + escape( inCookieValue ) + \r\n\t\t\t\t\t\t\t( inCookieExpiration ? \"; expires=\" + getExpiryDate(inCookieExpiration) : \"\" ) + \r\n\t\t\t\t\t\t\t\t\"; path=/\";\r\n}\r\n\r\nfunction getExpiryDate(nodays)\r\n{\r\n\tvar UTCstring;\r\n\tToday = new Date();\r\n\tnomilli=Date.parse(Today);\r\n\tToday.setTime(nomilli+nodays*24*60*60*1000);\r\n\tUTCstring = Today.toUTCString();\r\n\treturn UTCstring;\r\n}\r\n\r\nfunction generateSessionID()\r\n{\r\n\tvar \tgetTcpIpAddr = \"10.210.13.138\";\r\n\tvar SESSION_ID =\"SESSION_ID\";\r\n\tvar ipArray = getTcpIpAddr.split(\".\");\r\n\tvar ip = parseInt(ipArray[0], 10) + parseInt(ipArray[1], 10) + parseInt(ipArray[2], 10) + parseInt(ipArray[3], 10);\r\n\tvar d = new Date();\r\n\tID = parseInt((d.getMilliseconds()*ip)/32, 10);\r\n\tSetCookie(SESSION_ID, ID,365);\t//365 - expiry date is 1 year\r\n\twindow.location=window.location.toString();\r\n}\r\n-->\r\n</script>\r\n</head>\r\n<body onLoad=\"generateSessionID()\">\r\n</body>\r\n</html>\r\n"
This picture is an example of a Fiddler GET, and an IE instance of the same page. Note the Fiddler response is only 1075K and the IE response is 6602K.
How can I get a fully parsed response stream back in .Net?
I have to websites - A (written in C# using ASP.NET Web Forms) and B (written in VB using ASP.NET MVC4). Both websites are on different domains, require logging into and do not share the same database. I need to make sure that the users of website A could get access to website B without the need to authenticate on website B.
My proposed solution may not be what you would call a "best practice". I decided to set up a fictitious user on website B, whose credentials and permissions would be used by the users of website A (without their knowledge - hence bypassing the Login Page on website B).
I have the following API request in the code of website A:
HttpWebRequest post = (HttpWebRequest)WebRequest.Create("http://siteB/api/WebsiteA/Authenticate/");
post.Method="POST";
post.KeepAlive = true;
string postData = "email=" + email + "&password=" + password + "&hash=" + hash + "×tamp=" + timestamp + "&returnUrl=" + returnUrl;
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
post.ContentType = "application/x-www-form-urlencoded";
post.ContentLength = byteArray.Length;
Stream dataStream = post.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = post.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
Dictionary<string, string> d = new Dictionary<string, string>();
d = js.Deserialize<Dictionary<string, string>>(responseFromServer);
if (d.First().Value == "ok")
{
HttpContext.Current.Response.Cookies.Add(cookie_AU);
HttpContext.Current.Response.Cookies.Add(cookie_UD);
HttpContext.Current.Response.Cookies.Add(cookie_UL);
HttpContext.Current.Response.Redirect(returnUrl);
}
reader.Close();
dataStream.Close();
response.Close();
On website B I have the following Handler:
Public Class WebsiteAController
Inherits ApiController
<HttpPost()> _
Public Function Authenticate(params As API_AuthModel) As HttpResponseMessage
Try
Dim Result As New API_JSONResult
' Authenticate the message
Dim Auth As New API_Auth
If Auth.AuthenticateMessage(params.Hash, params.Timestamp, params.Email) Then
' If authentication is successful
If Membership.ValidateUser(params.Email, params.Password) Then
Result.status = "ok"
Result.message = SystemAuth.GenerateNewToken() 'token
Else
Result.status = "invalid"
Result.message = "Invalid authentication credentials"
End If
Else
Result.status = "error"
Result.message = "Invalid message"
End If
' Ensure the result is returned as JSON without further serialisation as this has been done already
Dim ResponseMsg = New HttpResponseMessage()
ResponseMsg = ControllerContext.Request.CreateResponse(HttpStatusCode.OK, Result)
ResponseMsg.Content.Headers.ContentType = New MediaTypeHeaderValue("application/json")
Return ResponseMsg
Catch ex As Exception
Return New HttpResponseMessage(HttpStatusCode.NotFound)
End Try
End Function
Unfortunately I have come to understand that this is not working. The main problem being that after my users authenticate successfully, they are not "remembered" as authenticated on website B. And the cookies I add to the response from website A do not seem to help either. I get redirected to the login page on website B. Am I doing something majorly wrong here? People have vaguely mentioned to me that API is stateless, and that I need to pass the Session_ID. If that is the case, how could I get the Session_Id and pass it between the two websites?
If you have any better suggestions/criticism please do share. I am very very new to API and I have spent my last 3 weeks attempting different solutions. It is very likely that I have understood how API works all wrong.
Hello I am making a GUI application on which a user gives his USER ID and Password to login on twitter.
I have the following code but it's not working for me, giving an error of 403 Forbidden
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
// encoding username/password
string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(txtId.Text + ":" + txtPassword.Text));
//connect with verify page
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://api.twitter.com/1.1/account/verify_credentials.xml");
// HttpWebRequest request =(HttpWebRequest)WebRequest.Create("http://twitter.com/account/verify_credentials.xml");
// setting method to GET- This API expects a GET method Call
request.Method = "POST";
// setting authorization levels
request.Headers.Add("Authorization", "Basic " + user);
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
//request.ContentType = "application/x-www-form-urlencoded";
// set the response from the GET command
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
// collect info returned from the GET call
string tempStream = null;
int count = 0;
do
{
count= resStream.Read(buf, 0, buf.Length);
if(count!=0)
{
tempStream= Encoding.ASCII.GetString(buf,0,count);
sb.Append(tempStream);
}
}while(count>0);
//convert result to XML DOC
XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());
// get person name from the newly created xml document
XmlNodeList nodeList = doc.SelectNodes("/user/name");
foreach (XmlNode node in nodeList)
personName = node.InnerText;
label1.Text = "Welcome, " + personName + "!";
also attached the GUI picture
need help if anyone know the solution
Thanks
Twitter no longer provide username/password access by default.
To have access to such a feature you will have to contact them privately with a very strong case (and company) so that they authorize your app to use it.
As an example the last company authorized to access this authentication was Instagram 2 years ago...
What you want to use is the OAuth mechanism to execute your query from an Application and User information.
I would suggest that you use the library that I developed for the Twitter developers using C# (https://github.com/linvi/tweetinvi).
You will be able to do what you want with the following lines of code :
Auth.SetUserCredentials("CONSUMER_KEY", "CONSUMER_SECRET", "ACCESS_TOKEN", "ACCESS_TOKEN_SECRET");
var authenticatedUser = User.GetAuthenticatedUser();
label1.Text = "Welcome, " + authenticatedUser.Name + "!";
I have, in my silverlight application, a call to a aspx page, to create and register a txt file on a directory.
Uri ub = (new Uri(HtmlPage.Document.DocumentUri, "GenereInfos.aspx?&connexion=" + connexion + ";&id=" + this.Id));
if (HtmlPage.IsPopupWindowAllowed)
{
HtmlPopupWindowOptions opt = new HtmlPopupWindowOptions();
HtmlPage.PopupWindow(ub, "file", opt);
}
else
{
HtmlPage.Window.Navigate(ub);
}
I have to go trough my aspx page to generate my txt file, because silverlight don't allow it.
The problem here is, a popup will appear, or the page will load the new uri.
What I want is call the code inside the asp only(which works perfectly), without loading the uri.
Is there a way to do this?
Edit : After DGibbs answer, there is another question now :
WShy can't I use GetResponse() in there?
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(new Uri
(HtmlPage.Document.DocumentUri, "GenereInfos.aspx?&connexion=" + connexion + ";&idPocedure=" + itmProcedure.IdProcedure));
string response = new System.IO.StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd();
Here a little answer : Silverlight is asynchrnous, so, we can't call GetResponse who is synchronous.
So, the best way to call my aspx page, is to use WebClient found here
You could just use WebRequest:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri
(HtmlPage.Document.DocumentUri, "GenereInfos.aspx?&connexion=" + connexion + ";&id=" + this.Id));
string response = new System.IO.StreamReader(req.GetResponse()
.GetResponseStream()).ReadToEnd();
I began to learn ASP.NET and C#, to get more familiar with techniques I want to make plugin for open source BugTracker.Net application. Where I am stacked is that for adding new issue application need to get HttpWebRequest on insert_bug.aspx
I did make basic thing working on code like this:
string Url = "http://localhost:8090/insert_bug.aspx";
string post_data =
"&username=admin"
+ "&password=admin"
+ "&short_desc=Description"
+ "&comment=Comment"
+ "&projectid=1"
byte[] bytes = Encoding.UTF8.GetBytes(post_data);
HttpWebResponse res = null;
try
{
HttpWebRequest req = (HttpWebRequest) System.Net.WebRequest.Create(Url);
req.Credentials = CredentialCache.DefaultCredentials;
req.PreAuthenticate =
req.Method = "POST";
req.ContentType= "application/x-www-form-urlencoded";
req.ContentLength=bytes.Length;
Stream request_stream = req.GetRequestStream();
request_stream.Write(bytes,0,bytes.Length);
request_stream.Close();
res = (HttpWebResponse) req.GetResponse();
}
catch (Exception e)
{
Console.WriteLine("HttpWebRequest error url=" + Url);
Console.WriteLine(e);
}
I want to insert also CATEGORY into my issues and reading code on insert_bug.aspx i fund part for defining category for opening issue
if (Request["$CATEGORY$"] != null && Request["$CATEGORY$"] != "") { categoryid = Convert.ToInt32(Request["$CATEGORY$"]); }
Question:
What and How I can add "$CATEGORY$" to my request so the issues I added have defined category.
If I understand your question correctly, if you want to add a category, you need to look up the category ID and add it as a variable in your POST data. For example, if the category you want has its ID=1 ("bug" in BugTracker.NET), then you'd use this:
string post_data =
"&username=admin"
+ "&password=admin"
+ "&short_desc=Description"
+ "&comment=Comment"
+ "&projectid=1"
+ "&$CATEGORY$=1";
BTW, in simple HTTP client scenarios like this one you're better off using the WebClient class. You can accomplish the same thing in many fewer lines of code.