how external counter get unique visitors? - c#

how do external counter track unique visitors via image
i'd also like to get Referrer if possible.
something like img="http://www.somecounterdomain.com/count.php?page=83599"
i'm using ASP.NET, c#
i'm aware of a user can "cheat" but would like to make that posibility minimal.
additional difficulty is that i should trach external server and can't implement c# code there.
what i can is only imlement a counter imag or smth like that.
i try to use generated image.
thx for answers.

Basically what you need to do is the following.
1- Create either a .ashx or .aspx. Assuming you go with .aspx and call it StatServer.aspx, the Page_Load function will read the query string and write the data to a database, you will see the querystring in step 2. If you want, you can return a image which can be rendered. Some rough code will look something like this.
private void Page_Load(object sender, EventArgs e)
{
WriteQueryStringInformationToDB(Request.QueryString);
Image image = LoadYourImageHere();
using (MemoryStream stream = new MemoryStream())
{
base.Response.Clear();
base.Response.ContentType = "image/png";
image.Save(stream, ImageFormat.Png);
stream.WriteTo(base.Response.OutputStream);
base.Response.End();
}
}
2- This is the magic, you create a small .js file. In this file you have a function lets call it mystats() which will essentially gather the client side information and make a call to the URL hosting the page you created in step 1. The client side information like screen size, referer etc. is all passed on the querystring. One important thing to include in the function is an ID which indicates which which counter you are updating, that way you can use your counter on multiple sites. A very simple .js might look something like this. (Note tested etc... :))
function mystats(id)
{
// Base URL including the ID of the counter
var url="http://yourdomainorservername/statserver.aspx?id="+id;
// Add the referer to the url querystring
url += "&r=" + escape(document.referrer);
// Add screen width + height
url += "&w=" + screen.width + "&h=" + screen.height;
document.write('<img src="'+url+'" border=0 alt="Site statistics">');
}
3- On the web pages that you want to apply the counter, you add a script block that includes the the .js file from your server and calls the mystats function from an img tag, this causes the js code to collect the info and send a request to your server, which in turn updates the DB and returns the image stream to display.

Getting the 'referer' is easy and for counting unique visitors you'll need to set/check for cookies.

Related

Using a php script to store an image in a specific folder on a server

In my application I'm saving an image and transferring to a server through the use of a php script whose sole job is to pass this image to the server which saves it in the root of the server.
The code I have for my upload is as follows:
NameValueCollection nvc = new NameValueCollection();
nvc.Add("id", "TTR");
nvc.Add("btn-submit-photo", "Upload");
UploadToServer.HttpUploadFile(Settings.Default.ServerAddress , sfd.FileName.ToString(), "file", "image/jpeg", nvc);
Settings.Default.ServerAddress holds the location of my upload php script which the following:
http://server.foo.com/images/upload.php
I have another php script that returns a string of all the file and folders held on my server that is returned and displayed in a text box.
I'm calling this like so:
using (var client = new WebClient())
{
result = client.DownloadString("http://server.foo.com/images/getDirectoryList.php");
}
What I need to do is have a way so that I can choose the location of where the my image is stored. My feeling is telling that I need to do is have a way so that when a user selects anything with .folder, the old string list disappears and the images and files is stored within that folder.
I believe the call I need to make is something like this:
http://server.foo.com/images/getDirectoyList.php?dir=test_folder
But I'm stuck on trying to implement what I want. For one, the list I get back is all highlight and say I get something like
Image 1
Image 2
Test_folder.folder
I have no way of being able to simply click on Image 2 and have it highlight the whole thing. Instead is simply places the cursor where I clicked. Likewise I have no idea of how I would pass this information over to the my upload code so that my chosen directory is used to store the image as opposed to the root.
Has anyone ever attempted something like this before?
Do you have any links or advice that could help me achieve what it is I want to achieve?
Additionally, but not important, would I be able to ever create a new directory / folder on my server through my C# winform application without having to touch either the php scripts or the server itself?

How to Fetch and Display an Image from the Database in ASP.Net and C#

There are so many good tutorials out there about inserting an image inside a table in a database, using the FileUpload controller.
Yet I cannot find a good tutorial about how to fetch these images and display them.
When I used to store the image name or path in the database (as a Varchar), It would be very simple by doing something like this...
HTML/ASP:
<img src="" runat="server" id="myImage" />
C#:
myImage.Src = myReader.getValue(0).toString();
The Result:
<img src="/Images/pic.png" runat="server" id="myImage" />
And Voila, the picture will be displayed.
But Now I would like to fetch uploaded images, not a path, means the type of the table column is IMAGE.
Some tutorials will eventually lead to display a picture in FULL SCREEN.
I do not want that, I simply want to fetch and display the image the same way it is displayed in the previous example, with a given size and place inside my web page.
Why am I uploading images to the database? Because these images are "Profile Pictures", not public pictures, I do not want a guest to simply browse for /Images/ to find all the pictures of my web site, public and private.
First of all, to do what you want, I would just copy the file to a temporary location and use that location for the "src" attribute. Later, you could delete the file. The much more complicated way is to create an aspx page that writes the image to the webpage as a binary stream. This page would grab the image from the database and just write the stream out in the response. You would then use this aspx page in the src attribute of your image. However, storing the image path in the database and actual file on the file system doesn't mean that the folder has to be browse-able or public. You can turn directory browsing off for example.
Create a custom IHttpHandler implementation that can serve your images from your database. You could, for example, get the bytes into a stream and copy that stream to the output of the web response.
Here is a simple example:
public class MyImageHandler : IHttpHandler
{
public bool IsReusable { get { return true; } }
public void ProcessRequest(HttpContext ctx)
{
Stream yourStream = ...; // This is where you get your data from your database
ctx.Response.ContentType = "image/jpeg";
yourStream.CopyTo(ctx.Response.OutputStream);
}
}
Then you need to configure it to respond to the URLs you wish.
You could either use the Web.config file to do this
Or create an .ashx file and have it point to your own HTTP handler
If you have any questions about it, just write a comment.
You will need an aspx page reading the image from the database and returning the raw bytes.
Here's a quick sketch how to do this:
byte[] data = (byte[])myReader.getValue(0);
Response.ContentType = "image/jpeg"; //or whatever your used image type is
Response.OutputStream.Write(data, 0, data.Length);
Response.End();
An alternative would be to implement a custom HttpHandler for this.
The other part is "calling" this page from your img tags with a parameter specifying the image id:
myImage.Src = "/image.aspx?id=" + myReader.getValue(0).toString();

Writing Rendered HTML To A File

I have a web app that displays a table the user can edit. In the process of editing, various inner HTML of the original table gets replaced with edits made by the user. Once the user is finished I would like to save the resulting table in a .html file so that I can include it in a PowerPoint slide without having to recreate it. Basically I want to capture the .aspx file as is after editing and write this to a file.
Any advice is appreciated.
Regards.
Basically I want to capture the .aspx file as is
Because you state "capture the ASPX", I'm assuming the data edits are persisted somewhere (memory/database). This means it is straightforward to override the Render() method of the control/page and redirect (or copy) the output stream to a file.
Example
protected override void Render( HtmlTextWriter writer ) {
using( HtmlTextWriter htmlwriter = new HtmlTextWriter( new StringWriter() ) ) {
base.Render( htmlwriter );
string renderedContent = htmlwriter.InnerWriter.ToString();
// do something here with the string, like save to disk
File.WriteAllText( #"c:\temp\foo.html", renderedContent );
// you could also Response.BinaryWrite() the data to the client
// so that it could be saved on the user's machine.
// and/or write it out to the output stream as well
writer.Write( renderedContent );
}
}
Sequence
User enters data
You store the results somewhere
You re-render the control with the most recent content
Capture the output of the control and write it out to a file
If you are doing it client side you can do something like this using jquery
http://jsfiddle.net/BAVzC/3/
You can then copy paste to a text file.
Just a few pointers.
You can get the whole inner html of a section of your page using jquery functions like html
You can use ajax to send this to your server.
You could write an http handler to receive this at the server. Since you only plan to save this to a fixed format html file, nothing else is required. I would not use a page to so as to avoid the extra overhead of creating all the controls, and a page will not receive html input unless you set ValidateRequest to "false".

Place Image from DLL onto a web page

I'm so stuck on something i thought would be easy.
I have a DLL that returns an Image object.
I just cant figure out how to display that image on a webpage.
I've tried a few ways, and google a million different variations.
Is it not possible to just bind an Image object to an element on the page like an HtmlImage or a simple img?
Or do i need to convert the Image to a Stream? or a Bitmap? I'm really stuck!
Any help appreciated.....
V
With Asp.Net WebForm, the easiest way is to create a custom ashx file.
In Visual Studio, create a new Custom Handler (I'm not sure of the name of the template in Visual Studio). This will create a .ashx file.
In the code of this handler, write something like (does not have VS under the hand to test the syntax) :
public void ProcessRequest(System.Web.HttpContext context)
{
byte[] raw;
using(var ms = new MemoryStream()){
Image myImage = GetFromDll();
myImage.Save(ms, ImageFormat.Png);
raw=ms.ToArray();
}
context.Response.ContentType = "image/png";
context.Response.BinaryWrite(raw);
}
Then, in your browser, navigate to http://yourserver/app/yourhandler.ashx.
You can if you want add url parameter, and get it from the Request.QueryString collection
It's not as simple as binding. On the client side images are retrieved from the web server as a separate GET request, which means you have to have a URL that resolves to an image. The other option, as Asif suggested, is embedding your image in the HTML as a Base64 string, which is bad practice for shared images (see Steve B's comment).
You either have to provide an URL (route that returns the image file in MVC, or a custom page with proper content type and Response.Write in WebForms), or embed in html.
EDIT:
There is also a third option involving custom HTTP handlers. These have the advantage of bypassing the app framework and serving the content almost directly off the web server, see MSDN.
Convert your image to base64 string and then set it in the <img/> tag.
<img/> can show the image in base64 string.
Alternatively you can save the image and use the path in the <img/>.

How not to abort http response c#

I need to run several methods after sending file to a user for a download. What happens is that after I send a file to a user, response is aborted and I can no longer do anything after response.end().
for example, this is my sample code:
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=test.pdf");
Response.ContentType = "application/pdf";
byte[] a = System.Text.Encoding.UTF8.GetBytes("test");
Response.BinaryWrite(a);
Response.End();
StartNextMethod();
Response.Redirect(URL);
So, in this example StartNextMethod and Response.Redirect are not executing.
What I tried is I created a separate handler(ashx) with the following code:
public void ProcessRequest(HttpContext context)
{
context.Response.Clear();
context.Response.AddHeader("content-disposition", "attachment; filename=test.pdf");
context.Response.ContentType = "application/pdf";
byte[] a = System.Text.Encoding.UTF8.GetBytes("test");
context.Response.BinaryWrite(a);
context.Response.End();
}
and call it like this:
Download d = new Download();
d.ProcessRequest(HttpContext.Current);
StartNextMethod();
Response.Redirect(URL);
but the same error happen. I've tryied to replace Response.End with CompleteRequest but it doesn't help.
I guess the problem is that I'm using HttpContext.Current but should use a separate response stream. Is that correct? how do I do that in a separate method generically (Assume that I want my handler to accept byte array of data and content type and be downloadable from a separate response. I really do not want to use a separate page for a response.
UPDATE
I still didn't find a good solution. I'd like to do some actions after user has downloaded a file, but without using a separate page for a response\request thing.
Update
Since you said no second page, do this instead. Add a section to your page that checks for a query string parameter (something like fileid, or path, etc...). If this value is present then it initiates the download process using your existing code. If this value is not present then it runs like normal.
Now when the user clicks the download link you perform a post back (which you are already doing). In this post back create an iFrame on the page and set the URL of the iFrame to your pages URL with the added query string parameter (mypage.aspx?id=12664 or ?download=true, something like that). After creating the iframe perform what ever additional databinds/etc... you wish too.
Example
- http://encosia.com/ajax-file-downloads-and-iframes/
This above linked example uses an iFrame and an update panel, just like you are talking about.
Original Post
Response.Flush will allow you to continue processing after you send the file to the user, or just don't call Response.End (you don't really need too).
However Daniel A. White is correct, you can't actually redirect from your code after you send a file, you will get an error if you try. BUT you can continue to perform other server side operations if you need to.
Other answers agree with the general consensus, you can't redirect after a file starts downloading: https://stackoverflow.com/a/822732/328968 (PHP, but same concepts since it involves HTTP in general). or Directing to a new page after downloading a file.
Response.End() throws a thread abort exception. It is designed to end your response.
No code after that will process in that thread.
The End method causes the Web server to stop processing the script and return the current result. The remaining contents of the file are not processed.
What is it that you are trying to achieve?
If your purpose it to allow the pdf to download and then take the user to some other page, a little javascript can help you out.
Add a script with a timer to set location.href to your redirected paged.
As the previous answers had stated - returning PDF file means to send HTTP headers. You cannot send another headers after that, and Response.Redirect() simply means to send HTTP 302.
If you don't want to have separate page, or if you don't want to use AJAX, why not trying:
<head>
<meta http-equiv="refresh" content="3; url=http://www.site.com/download.aspx?xxxx">
</head>
Actually this will show the desired page you want to show to the user, and will refresh the page after 3 sec with the URL for download of the PDF file.
Download the file in chunks, as illustrated File Download in ASP.NET and Tracking the Status of Success/Failure of Download or in the answer to this question. When the last chunk of the file has been written to the client you can execute the code you need to. (Doesn't have to be at the end, can be anywhere in between depending upon your needs.)
the user clicks on a download button on WebForm1.aspx to start downloading a file. then, after the file download is done (served by WebForm2.aspx), user is automatically redirected.
WebForm1.aspx
<script type="text/javascript">
$(document).ready(function () {
$('#btnDL').click(function () {
$('body').append('<iframe src="WebForm2.aspx" style="display:none;"></iframe>');
return true;
});
});
</script>
<asp:Button runat="server" ID="btnDL" ClientIDMode="Static" Text="Download" OnClick="btnDL_Click" />
WebForm1.aspx.cs
protected void btnDL_Click(object sender, EventArgs e)
{
var sent = Session["sent"];
while (Session["sent"]==null)
{// not sure if this is a bad idea or what but my cpu is NOT going nuts
}
StartNextMethod();
Response.Redirect(URL);
}
WebForm2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=test.pdf");
Response.ContentType = "application/pdf";
byte[] a = System.Text.Encoding.UTF8.GetBytes("test");
Response.BinaryWrite(a);
Session["sent"] = true;
}
Global.asax.cs
protected void Session_Start(object sender, EventArgs e)
{
Session["init"] = 0; // init and allocate session data storage
}
note: make sure don't use ashx (generic handler) to serve your download. for some reason, the session in ashx and aspx don't talk to each other, unless you implement this.
Just remove the context.Response.End(); because you are redirecting anyway...
The problem is flawed logic here.... Why would you end the response?
Get the PDF and display a link to it or use a META refresh to redirect to the location of the PDF or you could also display a link or use a combination of both techniques.
I believe what you are trying won't work.
This is what I would do:
Write content to a file locally and assign it an unique id
send user to the next page that contains a hidden frame that perform a request with the unique id (javascript)
hidden request page loads file and push on the content stream.
This is the same behavior a lot of file download sites is using. Only issue is if the hidden frame fails (javascript turned off) to perform the request, why a lot of the same sites have the link available if the auto request fails.
Disadvantage: file cleanup.
I recommend this solution :
Don't use response.End();
Declare this global var : bool isFileDownLoad;
Just after your (Response.BinaryWrite(a);) set ==> isFileDownLoad = true;
Override your Render like :
///
/// AEG : Very important to handle the thread aborted exception
///
///
override protected void Render(HtmlTextWriter w)
{
if (!isFileDownLoad) base.Render(w);
}

Categories