is it possible to issue dynamic include in asp-classic? - asp-classic

I mean, like php'h include...
something like
my_file_to_be_included = "include_me.asp"
-- >
for what I've seen so far, there are a couple of alternatives, but every one of them has some sort of shortcoming...
what I'm trying to figure out is how to make a flexible template system... without having to statically include the whole thing in a single file with a loooooong case statement...
here there are a couple of links
a solution using FileSysmemObject, just lets you include static pages
idem
yet another one
same thing from adobe
this approach uses Server.Execute
but it has some shortcomings I'd like to avoid... seems like (haven't tried yet) Server.Execute code runs in another context, so you can't use it to load a functions your are planning to use in the caller code... nasty...
same thing
I think this one is the same
this looks promising!!!
I'm not sure about it (couldn't test it yet) but it seems like this one dinamycally handles the page to a SSDI component...
any idea???

No you can't do a dyanmic include, period.
Your best shot at this is a server.execute and passing whatever state it needs via a Session variable:-
Session("callParams") = BuildMyParams() 'Creates some sort of string
Server.Execute(my_file_to_be_included)
Session.Contents.Remove("callParams")

Improved version (v2.0):
<%
' **** Dynamic ASP include v.2.0
function fixInclude(content)
out=""
if instr(content,"#include ")>0 then
response.write "Error: include directive not permitted!"
response.end
end if
content=replace(content,"<"&"%=","<"&"%response.write ")
pos1=instr(content,"<%")
pos2=instr(content,"%"& ">")
if pos1>0 then
before= mid(content,1,pos1-1)
before=replace(before,"""","""""")
before=replace(before,vbcrlf,""""&vbcrlf&"response.write vbcrlf&""")
before=vbcrlf & "response.write """ & before & """" &vbcrlf
middle= mid(content,pos1+2,(pos2-pos1-2))
after=mid(content,pos2+2,len(content))
out=before & middle & fixInclude(after)
else
content=replace(content,"""","""""")
content=replace(content,vbcrlf,""""&vbcrlf&"response.write vbcrlf&""")
out=vbcrlf & "response.write """ & content &""""
end if
fixInclude=out
end function
Function getMappedFileAsString(byVal strFilename)
Dim fso,td
Set fso = Server.CreateObject("Scripting.FilesystemObject")
Set ts = fso.OpenTextFile(Server.MapPath(strFilename), 1)
getMappedFileAsString = ts.ReadAll
ts.close
Set ts = nothing
Set fso = Nothing
End Function
execute (fixInclude(getMappedFileAsString("included.asp")))
%>

Sure you can do REAL classic asp dynamic includes. I wrote this a while back and it has opened up Classic ASP for me in a whole new way. It will do exactly what you are after, even though people seem to think it isn't possible!
Any problems just let me know.

I'm a bit rusty on classic ASP, but I'm pretty sure you can use the Server.Execute method to read in another asp page, and then carry on executing the calling page. 15Seconds had some basic stuff about it - it takes me back ...

I am building a web site where it would have been convenient to be able to use dynamic includes. The site is all ajax (no page reloads at all) and while the pure-data JSON-returning calls didn't need it, all the different html content for each different application sub-part (window/pane/area/form etc) seems best to me to be in different files.
My initial idea was to have the ajax call be back to the "central hub" main file (that kicks the application off in the first place), which would then know which sub-file to include. Simply including all the files was not workable after I realized that each call for some possibly tiny piece would have to parse all the ASP code for the entire site! And using the Execute method was not good, both in terms of speed and maintenance.
I solved the problem by making the supposed "child" pages the main pages, and including the "central hub" file in each one. Basically, it's a javascript round-trip include.
This is less costly than it seems since the whole idea of a web page is that the server responds to client requests for "the next page" all the time. The content that is being requested is defined in scope by the page being called.
The only drawback to this is that the "web pieces" of the application have to live partly split apart: most of their content in a real named .asp file, but enough of their structure and relationship defined in the main .asp file (so that, for example, a menu item in one web piece knows the name to use to call or load another web piece and how that loading should be done). In a way, though, this is still an advantage over a traditional site where each page has to know how to load every other page. Now, I can do stuff like "load this part (whether it's a whole page or otherwise) the way it wants to be loaded".
I also set it up so each part can have its own javascript and css (if only that part needs those things). Then, those files are included dynamically through javascript only the first time that part is loaded. Then if the part is loaded repeatedly it won't incur an extra overhead.

Just as an additional note. I was getting weird ASCII characters at the top of the pages that were using dynamic includes so I found that using an ADODB.Stream object to read the include file eliminated this issue.
So my updated code for the getMappedFileAsString function is as follows
Function getMappedFileAsString(byVal strFilename)
Dim fso
Set fso = CreateObject("ADODB.Stream")
fso.CharSet = "utf-8"
fso.Open
fso.LoadFromFile(Server.MapPath(strFilename))
getMappedFileAsString = fso.ReadText()
'Response.write(getMappedFileAsString)
'Response.End
Set fso = Nothing
End Function

Related

Execute VB Script on page_load

I am having VB Script in ASPX page.I need to use that Script in codeBehind in Page _load with in a For loop,for each iteration.
My Code is :-
(.ASPX Page with VB Script. )
<script type="text/vbscript" language="vbscript" >
sub wordit()
'Opens Word application and does some process
end sub
</script>
VB Code Behind Part:-
For i As Integer = 1 To colSelRowIndex
CheckboxTemplateId = colSelRowKeys(i).ToString 'I get the ID from here
ViewState("TemplateID") = CheckboxTemplateId 'I need to send the value to the sub routines
hen()'sub
den()'sub
cs.RegisterStartupScript(cstype, csname1 & i, "wordit();", True)
Next
I need to open a word doc for an ID and another document for another ID from the loop.
Try this:
For i As Integer = 1 To 10
cs.RegisterStartupScript(cstype, csname1 & i, "wordit();", True)
Next
That second argument in that function call is looking for a unique key. This is a feature, to prevent accidentally programmatically adding the same script more than once. If you want to do it on purpose, you need a unique key each time.
But that you want to do this at all indicates a possible fundamental misunderstanding about what's going on. While your server code (including Page_Load) is running, your client page in the web browser doesn't exist. The purpose of the server code is always to generate an html response to web request. The server code can never directly manipulate a page DOM.
Obviously this is true for a first request to a page in session: the server must first generate the initial page to send the client. But even on subsequent postbacks, the browser will destroy the prior instance of a page. The server must rebuild the entire page from scratch. Every. Time. While this happens, the page you're looking at in your browser window is only a sort of after-image. The browser has already destroyed any prior DOM, and is waiting for the server to supply a whole new set of HTML.
I also wonder at your use of vbscript, rather than javascript. Using vbscript pretty much guarantees you're page will only work with Internet Explorer.

Pass value WinForm =>(page.html?query123)=> HTML =>(page.aspx?query123)=> asp.net //esle?

The problem here is the middle of the line (HTML).
The chain:
I have WinForm program that uses awesomium (alternative to native webBrowser) to view Html page that has a part of asp.net page in it's iframe.
The problem:
The problem is that I need to pass value to asp.net page, it is easily achieved without middle of the chain (Html iframe) by sending hashed and crypted querystring.
How it works:
WinForm do some thing, then use few-step-crypt to code all the needed values into 1 string.
Then it should send this string to asp.net page through the iframe (and that's the problem, it is easy to receive query string in asp.net page, but firstly I need to receive it in Html and send to asp.net).
Acceptable answers:
1) Probably the most easily one - using JavaScript. I have heard it is possible to be done in that way.
How I imagine this - I send query string from WinForm to Html page as http:\\HtmlPage.html?AspNet.aspx?CryptedString
Then Html receive it with JavaScript and put querystring "AspNet.aspx?CryptedString" into iframe's "src=http:\\" resulting in "src=http:\\AspNet.aspx?CryptedString"
And then I easily get it in asp.net page.
2) Somehow create >>>VIRTUAL<<<(NOTE: Virtual, I don't want querystring to be saved on the HDD, even don't suggest) asp.net or html page with iframe source taken directly from WinForm string.
Probably that is possible with awesomium, but I'm new to it and don't know how to (if it is possible ofc).
3) Some web service with which I can communicate between asp.net and WinForm through the existing HTML iframe.
4) Another way that replace one of 3 previous, that doesn't save "values" in querystring/else on HDD nor is visible for the user, doesn't use asp.net page's server to create iframe-page on it. On HTML page's server HTML is only allowed, PhP isn't.
5) If you don't know any of 4 above - suggest free PhP hosting without ads (if such exists, what I highly doubt).
Priority:
The best one would be #3, then #2, then #1, then #5 (#4 is excluded as it is unknown).
And in the end:
Thanks in advance for your help.
P.S.Currently at work, so I'll check/try all answers later on and will report tomorrow if any suits my needs. Thanks again.
Answering my own question. I have found 2 ways that can do what I did want.
The first one:
Creating a RAM file System.IO.MemoryStream or another method (google c# create a file in ram).
The second one:
Creating a hidden+encrypted+system+custom-readable-only-by-program-crypt file somewhere in the far away folder via File.SetAttributes Method and System.IO.StreamWriter/Reader or System.IO.FileStream or System.IO.TextWriter, etc. depending on what it should be.
Once this file was used for needs delete it + delete on exit + delete on start using
if (File.Exists(path)
{
File.Delete(path);
}
(Need more reputation to post few links -_-, and I don't want to post only part of them, either all or no at all, so use google if you'll need anything from here).
If you'll need to store "Small temp file" and not for a long time use first one, if "Heavy" use second one, unless you badly need to use RAM for it.

Conditional includes in Classic ASP - where the file may not exist on the server

I am currently in a situation where I have to make some additions to an application written in classic ASP using server-side JScript on IIS.
The additions that I need to make involve adding a series of includes to the server-side code to extend the application's capabilities. However, the inc files may not exist on the server in all cases, so I need the application to fall back to the existing behavior (ignore the includes) if the files do not exist, rather than generating an error.
I know that this can't be accomplished using if statements in the JScript code because of the way that SSI works, and have not come across any ways of dynamically including the code on the server side, where the files may not exist.
Does anyone know of a way to accomplish this in classic ASP? Any help would be much appreciated.
Here's a script to dynamically include asp files:
<%
' **** Dynamic ASP include v.2
function fixInclude(content)
out=""
if instr(content,"#include ")>0 then
response.write "Error: include directive not permitted!"
response.end
end if
content=replace(content,"<"&"%=","<"&"%response.write ")
pos1=instr(content,"<%")
pos2=instr(content,"%"& ">")
if pos1>0 then
before= mid(content,1,pos1-1)
before=replace(before,"""","""""")
before=replace(before,vbcrlf,""""&vbcrlf&"response.write vbcrlf&""")
before=vbcrlf & "response.write """ & before & """" &vbcrlf
middle= mid(content,pos1+2,(pos2-pos1-2))
after=mid(content,pos2+2,len(content))
out=before & middle & fixInclude(after)
else
content=replace(content,"""","""""")
content=replace(content,vbcrlf,""""&vbcrlf&"response.write vbcrlf&""")
out=vbcrlf & "response.write """ & content &""""
end if
fixInclude=out
end function
Function getMappedFileAsString(byVal strFilename)
Dim fso,td
Set fso = Server.CreateObject("Scripting.FilesystemObject")
Set ts = fso.OpenTextFile(Server.MapPath(strFilename), 1)
getMappedFileAsString = ts.ReadAll
ts.close
Set ts = nothing
Set fso = Nothing
End Function
execute (fixInclude(getMappedFileAsString("included.asp")))
%>
The last line (the one starting with "execute") is equivalent to an "include" directive, with the difference that it can be included inside an "if" statement (dynamic include).
Bye
If you are really brave, you can read the contents of the file and then Eval() it.
But you will have not real indication of line numbers if anything goes wrong in the included code.
As a potentially better alternative: Can you not create some sanity check code in global.asa to create the include files as blanks if they do not exist?
Put simply, no. Why would the files not exist? Can you not at least have empty files present?
What you could do is something like this:
Use Scripting.FileSystemObject to detect the presence of the files
Use Server.Exeecute to "include" the files, or at least execute the code.
The only problem is that the files cannot share normal program scope variables.
The solution to this turned out to be to use thomask's suggestion to include the files and to set a session variable with a reference to "me" as per http://www.aspmessageboard.com/showthread.php?t=229532 to allow me to have access to the regular program scope variables.
(I've registered because of this, but can't seem to associate my registered account with my unregistered account)

stupid caching in asp.net

i use such code
string.Format("<img src='{0}'><br>", u.Avatar);
u.Avatar-it's like '/img/path/pic.jpg'
but in this site i can upload new image instead old pic.jpg. so picture new, but name is old. and browser show OLD picture (cache). if i put random number like /img/path/pic.jpg?123 then works fine, but i need it only ufter upload, not always. how can i solve this?
string imgUrl = _
string.Format("<img src='{0}?{1}'><br>", _
u.Avatar, _
FunctionThatLookupFileSystemForItsLastModified(u.Avatar).Ticks.ToString());
Instead of linking to the images directly, consider setting up a generic HTTP handler to serve the images.
MSDN: HTTP Handlers and HTTP Modules Overview
Stack Overflow: How to use output caching on .ashx handler
Append DateTime.Now.Ticks to the image url:
string imgUrl =
string.Format("<img src='{0}?{1}'><br>", u.Avatar,DateTime.Now.Ticks);
EDIT: I don' think this best practice are even a practice I would use. This is just a suggestion given the limited information given in case the Random implementation isn't truly Random.
Read your post again,,, sorry for general answer.
To workaround it do following
On Application_Start create a Dictionary with uploaded images save it on Application object, set it to null. Once you upload an image add it to this Dictionary. Wrap every place avatars appear on your website with function that evaluates image in Dictionary if found return imagename.jpg?randomnumber and then delete it from a Dictionary else return just an imagename.jpg.
This is going to be heavy because you will need to check each image in Dictionary but this will do exactly what you need.
You can set cache dependancy using the System.Web.Caching.CacheDependency namespace.
This can set the dependancy on the file uploaded, and will release the cache for that file automatically when the file changes.
There are lots of articles and stuff on MSDN and other places so I will not go into details on all that level of detail.
You can do inserts, deletes and other management of cache using the tools available.
(and this does not require you to change the file names or tack on stuff - it knows by the file system that the file changed)

How to select between include files

I am working on adding a mulit-language feature to an asp classic site. I was trying to do this by using if else statements to select the include I want to load. After a bit of research I found out that includes files are loaded up before any code is handled.
How can I get around this issue and load up the proper include files? Is there a better way of doing this?
Thanks!
You can't, as you've discovered, dynamically choose includes. Includes are handled statically before any script is executed.
The next best thing is Server.Execute. You can use logic to choose what additional files to execute, however whether this fits with your solution is another matter. What do your includes currently contain?
Another approach would be place your "multi-language" choices in some data format such a set of CSV files or XML files. Your code would then load the appropriate "language file".
After countless hours I think I finally came up with a solution. I create xml files for each language (en.xml, fr.xml) with a super simple structure (just a label element with an id and value).
By using an attribute that has a similar name to the label I want to replace I can figure out where everything needs to go, and just pull the value.
I'm not sure if this idea helps, but you could dim the language string variables in one ASP file and then set the variables in separate ASP functions. Then your if statements can call the proper function to set the ASP language string variables. You would not be breaking out the language string into separate files, but it might accomplish what you are trying to achieve.
For example:
dim str1, str2
sub SetLangX
str1 = "String val 1 for lang X"
str2 = "String val 2 for lang X"
end sub
sub SetLangY
str1 = "String val 1 for lang Y"
str2 = "String val 2 for lang Y"
end sub
It can be done - just use include virtual instead of file
edit
I stand corrected - obviously i tried too hard to forget those dark ages.
Years ago i worked on a project where we would create a "container page" for every language version an then include the respective portion of constants.
A working spinoff is still running and if you check the page source of this site you can get an idea how we plugged the pages together.
Some of the included scripts identified by their SVN id tags even included more scripts and maintaining this slowly turned into a nightmare.
I'm sorry i was wrong about the conditional include and there should be a better solution than the one mentioned above.

Resources