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();
Related
I am trying to get a table from the web page https://www.belastingdienst.nl/rekenhulpen/wisselkoersen/ using HtmlAgilityPack.
My code so far is
WebClient webClient = new WebClient();
string page = webClient.DownloadString("https://www.belastingdienst.nl/rekenhulpen/wisselkoersen/");
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(page);
List<List<string>> table = doc.DocumentNode.SelectSingleNode("//table[#class='list_result Result']")
.Descendants("tr")
.Skip(1)
.Where(tr => tr.Elements("td").Count() > 1)
.Select(tr => tr.Elements("td").Select(td => td.InnerText.Trim()).ToList())
.ToList();
My problem is that the webpage creates the table by using JavaScript and when I try to read it it throws a null exception because the web page is showing that I must enable JavaScript.
I also tried to use "GET" method
string Url = "https://www.belastingdienst.nl/rekenhulpen/wisselkoersen/";
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
string result = sr.ReadToEnd();
sr.Close();
myResponse.Close();
with the same results.
I already enable JavaScript in Internet Explorer and change registry as well
if (Environment.Is64BitOperatingSystem)
Regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SOFTWARE\\Wow6432Node\\Microsoft\\Internet Explorer\\MAIN\\FeatureControl\\FEATURE_BROWSER_EMULATION", true);
else //For 32 bit machine
Regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", true);
If I use a WebBrowser component I can see the web page without problem but I still can't get the table to list.
F12 is your friend in any browser.
Select the Network tab and you'll notice that all of the info is in this file :
https://www.belastingdienst.nl/data/douane_wisselkoersen/wks.douane.wisselkoersen.dd201806.xml
(I suppose that the data for july 2018 will be held in a url named *.dd201807.xml)
Using C# you will need to do a GET for that URL and parse it as XML, no need to use HtmlAgilityPack. You will need to construct the current year concatenated with the current month to pick the right URL.
Leuker kan ik het niet maken!
WebClient is an http client, not a web browser, so it won't execute JavaScript. What is need is a headless web browser. See this page for a list of headless web browsers. I have not tried any of them though, so I cannot give you a recommendation here:
Headless browser for C# (.NET)?
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 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.
I ran into a problem. I am .Net Developer and don't know about php, I am working on a CRM which has an API. My Client says it should be simple page should work with simple post. now i don't understand how i can do a simple Post in .Net. I have created an asp.net WebForm. All is working well. The only thing that i have problem with is that i have to return a list of parameters to response. I am using
Response.Write("100 - Click Recorded Successfully.");
but this return a full html Document with the parameter string at the top of the document. I saw one php Api which return only the prameter string like this with out HTML Document:
response=1
&responsetext=SUCCESS
&authcode=123456
&transactionid=2154229522
&avsresponse=N
&cvvresponse=N
&orderid=3592
&type=sale
&response_code=100
can some one suggest me any better way how i can do this. I found many article that explains how to do a simple Get Post in .Net but none of these solved my problem.
Update:
this is the code that i am using from another application to call the page and get response stream
string result = "";
WebRequest objRequest = WebRequest.Create(url + query);
objRequest.Method = "POST";
objRequest.ContentLength = 0;
objRequest.Headers.Add("x-ms-version", "2012-08-01");
objRequest.ContentType = "application/xml";
WebResponse objResponse = objRequest.GetResponse();
using (StreamReader sr =
new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
string temp = result;
where url + query is the address to my page. The result shows this code http://screencast.com/t/eKn4cckXc. I want to get the header line only, that is "100 - Click Recorded Successfully."
You have two options. First is to clear whatever response was already generated on the page, write the text, and then end the response so that nothing else added:
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Type", "text/plain");
Response.Write(Request.Url.Query);
Response.End();
That is if you want to process it on the Page. However a better approach would be to implement Http Handler, in which case all you need to do is:
public void ProcessRequest
{
Response.AddHeader("Content-Type", "text/plain");
Response.Write(Request.Url.Query);
}
Hi,
I have a simple ASP.NET MVC C# webpage that users can submit Title, Descirption, Tags and a link(URL). The post to the service is sent with JASON(AJAX) and works great for the most part. But sometimes the post just hangs and nothing happens when this happens it will also be vary slow to load any other page of this website.
The webmethod is real simple, first it stored the data to the database and then it uses HttpWebRequest to fetch the URL page. The fetched page is then read(header data) and in most cases it stores a image.
I suspect that the hangig is due to HttpWebRequest taking to long. The request method starts with this :
if (url != null && url.Length > 0)
{
request = (HttpWebRequest)HttpWebRequest.Create(url);
dirInfo.Create();
request.UserAgent = ConfigurationManager.AppSettings["DomainName"];
webresponse = (HttpWebResponse)request.BeginGetResponse( .GetResponse();
if (webresponse.ContentType.StartsWith("image/"))
{
using (WebClient tmpClient = new WebClient())
{
client.DownloadFile(url, postThumbnailsTemp + "\\" + fileName);
}
if (SavePostImage(postThumbnailsTemp + "\\" + fileName, postId))
return true;
}
if (webresponse.ContentType.StartsWith("text/html") || webresponse.ContentType.StartsWith("application/xhtml"))
{
var resultStream = webresponse.GetResponseStream();
doc.Load(resultStream);
The question is if it might be better to use a async call here? Like the HttpWebRequest.BeginGetResponse? This would mean that the user might be redirected to the post page before the URL webpage is read and stored.
If you are using web api for example, you can change your api controller action to be async.
If you do so, the response will NOT return to the client until the task has completed but it will also not block other client/threads!
Example
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody]MyObject obj)
Within the method you should also use the async await pattern to create your custom request...
Have some articles for further information of how to build async web apis
http://blogs.msdn.com/b/webdev/archive/2013/09/18/scaffolding-asynchronous-mvc-and-web-api-controllers-for-entity-framework-6.aspx
http://www.dotnetcurry.com/showarticle.aspx?ID=948
and maybe watch this video