Dělám catch-all webové stránky, kde uživatelé mohou nahrát své vlastní html kód na webové stránky, pak webové stránky se objeví na jejich webové stránky, když jejich hovor konkrétní subdoménu.
Html kód s přílohami si to nahrát do podadresáře uvnitř webové stránky:
SITE #1
~/sites/test1/index.html
~/sites/test1/images/logo.png
SITE #2
~/sites/test2/index.html
~/sites/test2/images/logo.png
Takže můžete volat tyto soubory pomocí následujících adresách:
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
Takže to, co jsem udělal, bylo, aby popisovač chyb uvnitř Global.asax, který zjistí při pokusu požádat o soubor, který neexistuje, proto požádat na internetových stránkách:
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();
}
}
Výše uvedený kód funguje pro soubor „index.html“, ale nefunguje to pro „/images/logo.png“, protože 404 se nespustí psovoda Application_Error. Po dlouhém hledání a tahem moje vlasy, že jsem zjistil, začal tento „feature“ od NET 4.0 a výše. Ale nechci se vrátit, chci vědět, jak správně vyřešit.