Κάνω ένα catch-all ιστοσελίδα όπου οι χρήστες μπορούν να φορτώσουν το δικό τους κώδικα HTML στην ιστοσελίδα τότε η ιστοσελίδα θα δείξει την ιστοσελίδα τους κατά την κλήση τους το συγκεκριμένο υποτομέα.
Ο κώδικας HTML με συνημμένα να έχει φορτωθεί σε ένα υποκατάλογο μέσα στον δικτυακό τόπο:
SITE #1
~/sites/test1/index.html
~/sites/test1/images/logo.png
SITE #2
~/sites/test2/index.html
~/sites/test2/images/logo.png
Έτσι, μπορείτε να καλέσετε αυτά τα αρχεία χρησιμοποιώντας τις ακόλουθες διευθύνσεις URL:
SITE #1
http://test1.mydomain.com/index.html
http://test1.mydomain.com/images/logo.png
SITE #2
http://test2.mydomain.com/index.html
http://test2.mydomain.com/images/logo.png
Έτσι αυτό που έκανα ήταν να κάνει χειρισμού σφαλμάτων μέσα στο Global.asax που ανιχνεύει όταν προσπαθείτε να ζητήσετε ένα αρχείο που δεν υπάρχει, ως εκ τούτου, να ζητήσει από τον δικτυακό τόπο:
protected void Application_Error()
{
// Get the subdomain requested
var subdomain = Request.Url.Authority.Split(new char[] { '.', ':' }).FirstOrDefault();
// Get the directory info about the requested subdomain
DirectoryInfo info = new DirectoryInfo(Server.MapPath(~/ + subdomain));
// Check if subdomain is not empty and exists
if (!string.IsNullOrEmpty(subdomain) && info.Exists)
{
// Get the requested filename
var filename = Request.Url.PathAndQuery.Split(new char[] { '?' }).FirstOrDefault();
// If the root is requested change to index.html
if (filename == /) filename = /index.html;
// Translate requested filename to server path
var fullname = Server.MapPath(~/sites/ + subdomain + filename);
// Respond the file
ResponseFile(fullname);
}
else
{
// Subdomain not found so end the request
Response.End();
}
}
public void ResponseFile(string fullname)
{
Response.Clear();
System.IO.Stream oStream = null;
try
{
// Open the file
oStream =
new System.IO.FileStream
(path: fullname,
mode: System.IO.FileMode.Open,
share: System.IO.FileShare.Read,
access: System.IO.FileAccess.Read);
// **************************************************
Response.Buffer = false;
// Setting the ContentType
Response.ContentType = MimeMapping.GetMimeMapping(fullname);
// Get the length of the file
long lngFileLength = oStream.Length;
// Notify user (client) the total file length
Response.AddHeader(Content-Length, lngFileLength.ToString());
// **************************************************
// Total bytes that should be read
long lngDataToRead = lngFileLength;
// Read the bytes of file
while (lngDataToRead > 0)
{
// The below code is just for testing! So we commented it!
//System.Threading.Thread.Sleep(200);
// Verify that the client is connected or not?
if (Response.IsClientConnected)
{
// 8KB
int intBufferSize = 8 * 1024;
// Create buffer for reading [intBufferSize] bytes from file
byte[] bytBuffers =
new System.Byte[intBufferSize];
// Read the data and put it in the buffer.
int intTheBytesThatReallyHasBeenReadFromTheStream =
oStream.Read(buffer: bytBuffers, offset: 0, count: intBufferSize);
// Write the data from buffer to the current output stream.
Response.OutputStream.Write
(buffer: bytBuffers, offset: 0,
count: intTheBytesThatReallyHasBeenReadFromTheStream);
// Flush (Send) the data to output
// (Don't buffer in server's RAM!)
Response.Flush();
lngDataToRead =
lngDataToRead - intTheBytesThatReallyHasBeenReadFromTheStream;
}
else
{
// Prevent infinite loop if user disconnected!
lngDataToRead = -1;
}
}
}
catch { }
finally
{
if (oStream != null)
{
//Close the file.
oStream.Close();
oStream.Dispose();
oStream = null;
}
Response.Close();
Response.End();
}
}
Ο παραπάνω κώδικας λειτουργεί για το αρχείο «/index.html», αλλά δεν λειτουργεί για το «/images/logo.png», επειδή το 404 δεν θα απολύσει τον χειριστή Application_Error. Μετά από πολλή αναζήτηση και τραβώντας τα μαλλιά μου έξω ανακάλυψα αυτό το «χαρακτηριστικό» που ξεκίνησε από το .net 4.0 και πάνω. Αλλά δεν θέλω να πάω πίσω, θέλω να μάθω πώς να λύσει σωστά αυτό.