how to return value from server.execute call

J

Jim Rodgers

I am trying to replace a huge chunck of code that currently I incorporate
with an #Include directive. The program rarely has to flow through that
code, so I thought it would be better if I used Server.Execute.

I found I can pass data TO the called asp file by creating an HTML <input>
and erading it after I get there.

However, I also need to read back ONE variable that the called file must
set. I cannot figuer out how to do that. My backup positions are (1) I can
keep on using the #Include technique, and (2) I can use a database to bridge
the gap.

BUT... Isn't there a way to carry data BACK TO the calling asp file FROM
THE CALLED asp file?

I certainly do appreciate the help!

Thanks,

Jim
 
E

Evertjan.

=?Utf-8?B?SmltIFJvZGdlcnM=?= wrote on 05 aug 2007 in
microsoft.public.inetserver.asp.general:
I am trying to replace a huge chunck of code that currently I
incorporate with an #Include directive. The program rarely has to
flow through that code, so I thought it would be better if I used
Server.Execute.

I found I can pass data TO the called asp file by creating an HTML
<input> and erading it after I get there.

However, I also need to read back ONE variable that the called file
must set. I cannot figuer out how to do that. My backup positions
are (1) I can keep on using the #Include technique, and (2) I can use
a database to bridge the gap.

BUT... Isn't there a way to carry data BACK TO the calling asp file
FROM THE CALLED asp file?

try session variables:

============== test.asp ==================
<%
response.write "running test.asp<br>"
session("a") = "from test"
response.write "1-A: "&session("a")&"<br>==========<br>"

server.execute "testtest.asp"

response.write "running test.asp<br>"
response.write "2-A: "&session("a")&"<br>"
response.write "3-B: "&session("b")&"<br>"
%>
==========================================

============ testtest.asp ================
<%
response.write "running testtest.asp<br>"
session("b") = "from testtest"
response.write "A: "&session("a")&"<br>"
response.write "B: "&session("b")&"<br>==========<br>"
%>
==========================================

===== result from running test.asp ======
running test.asp
1-A: from test
==========
running testtest.asp
A: from test
B: from testtest
==========
running test.asp
2-A: from test
3-B: from testtest
==========================================
 
J

Jim Rodgers

Evertjan. said:
=?Utf-8?B?SmltIFJvZGdlcnM=?= wrote on 05 aug 2007 in
microsoft.public.inetserver.asp.general:



try session variables:

Thanks, Evertjan. We made a design decision early on in the project not to
use the Session object -- for various reasons, mostly related to scalability
in some way. But you're right, of course; that would be perfect.

This is why I described one of my fallback positions to be using a database,
which is the way many developers implement Session functionality without the
Session object. I believe MS eCommerce Server (correct name?) does it that
way.

It seems, except for the Session object, any "variables" that can be passed
TO the CALLED asp file are essentially read-only in the sense they cannot be
changed and passed back to the CALLING asp file.

For example, I can create Request.Form(1) in the CALLING file using an
<input> element, and I can read it in the CALLED file. However, this
expression is not permitted on the left side of an equation, so it seems I
cannot change that value.

Moreover, if I create yet another Form name / value pair in the CALLED file,
that one will NOT be visible to the CALLING file upon return.

Can you think of any way a script can modify a passed value in the CALLED
file so a script in the CALLING file can see it?
 
J

Jim Rodgers

Jon Paal said:
Server.execute is a dynamic include, so any variables defined in the parent file will also be availabel in the "include" file, since
they execute within the same page scope.

http://support.microsoft.com/kb/224363

Thank you, Jon Paal. The variables that are available to the script in the
CALLED file are the ASP object variables like Server, Request, Response,
Application, etc., and most importantly, variables in the Session object.
The VBScript variables do not scope beyond the CALLING file as they do with
the #Include directive. It's very frustrating.

BTW, the article you mentioned has some problems; I think they should pull
it. For example, the data stream to the client includes...

<html>
<body>
<html>
<body>
....
</body>
</html>
</body>
</html>

....which works, but, well they need to do more than just test their examples.

An excellent (albeit somewhat verbose) alternative article is this one:

http://msdn.microsoft.com/msdnmag/issues/0400/redir/

Yet even that one fails to mention (I think) the subject of returning (or
not...) values back to the CALLING script.

Can you think of any other ways?

Thanks,

Jim
 
A

Anthony Jones

Jim Rodgers said:
I am trying to replace a huge chunck of code that currently I incorporate
with an #Include directive. The program rarely has to flow through that
code, so I thought it would be better if I used Server.Execute.

I found I can pass data TO the called asp file by creating an HTML <input>
and erading it after I get there.

However, I also need to read back ONE variable that the called file must
set. I cannot figuer out how to do that. My backup positions are (1) I can
keep on using the #Include technique, and (2) I can use a database to bridge
the gap.

BUT... Isn't there a way to carry data BACK TO the calling asp file FROM
THE CALLED asp file?

I certainly do appreciate the help!

For this scenario the next step from an include file is a VB6 dll. Of
course for various reasons that may not be an option.

For an include file that contains a large set of functions enclosing them in
a class helps to keep the global namespace free.

Server.Execute is not an appropriate solution.

How have you determined that having a large include file is a problem?
 
J

Jim Rodgers

Anthony Jones said:
For this scenario the next step from an include file is a VB6 dll. Of
course for various reasons that may not be an option.

For an include file that contains a large set of functions enclosing them in
a class helps to keep the global namespace free.

Server.Execute is not an appropriate solution.

How have you determined that having a large include file is a problem?

Thanks, Anthony!

I have not yet determined that having a large include file is a problem. I
may keep what I have until it is a problem. However, I am not only creating
a specific web application, but I am trying to keep my options open for code
reuse since the project is turning into a decent platform for more work.

Your idea about a VB6 DLL is excellent. I am planning to replace a lot of
my #Includes (containing my VBScript Subs and Functions "library") with a DLL
soon. But it will make more sense to you and everyone if I mention one more
aspect of the problem I have in the current case.

The subject asp file (which currently is #Included and which I would prefer
to be Server.Execute'd) processes a huge number of Request.Form(i) variables
for all kinds of input validation requirements. It is because of the
Request.Form(i) variables that I felt Server.Execute would be a good choice.
I hate having to pass all these TO the CALLED file.

Since no one could tell me about [an obscure] technique for getting one or
two answers back to the CALLING script, I have decided to write the
validation results to a database. Thus, I need only to check the database
when I return to the first file. Previously, I acted on the validation
results (with Response.Write's) in the CALLED file. Now I will simply do
that after I return. Even though the second file now does no output to the
client side, it still makes sense to use Server.Execute because of the sheer
volume of Request.Form(i) variables.

Would you agree?

Thanks again for your remarks.

Jim
 
J

Jim Rodgers

Jon Paal said:
You don't have to "return" them as they are available as part of the parent page scope. Just use the variable.


Jon,

When I reference (in the VBScript in the "executed" file) any variable from
the VBScript in the "parent" file, I get a variable not declared error.

When I reference (in the VBScript in the "parent" file) any variable
declared only in the VBScript in the "executed" file, I get a variable not
declared error.

And even though I can "see" variables in the Request.Form collection from
the parent to the executed file, I cannot see any Request.Form items declared
in the executed file. (Although this is perhaps not what you were referring
to.)

I am using "Dim" to declare these variables (and Option Explicit). I
haven't tried "Public" yet, do you think that would work? I can see how it
might. Frankly, I don't think the documentation is very good on this point.

(I am referring to variables declared at what I guess you might call the
"module" level -- that is, I am not referring to any variables declared only
in a VBScript subprogram or function.)

The reason I assumed (as you are also telling me) ...that the scope carried
forward to the executed file, is the statement made in the documentation
(somewhere!) that subs and functions declared in file #Includes in the parent
file are not visible in the executed file. The documentation went on to say
that one must also #Include these same files in the executed file for that
"child" VBScript to see it.

Later, I concluded this is just another example of the bizarre confusion
caused by the ever-deteriorating MSDN documentation (especially, but not
limited to ASP Classic). I further concluded, what they really meant was NO
MATTER HOW these elements (variables, subs, and functions) are declared in
the parent, the executed file simply will not see them. Of course, by
putting copies (re-declaring) of the subs and function in the executed file,
you are back in business. However, this does not imply a remedy for the
scope of VBScript variables.

Or does "Public" work? Jon, do you have any links to clear specs or
examples. I would love to see this settled for sure one way or the other.

Thanks for helping. I appreciate the time you spend help me clear this up.

Cheers,

Jim Rodgers
 
E

Evertjan.

=?Utf-8?B?SmltIFJvZGdlcnM=?= wrote on 05 aug 2007 in
microsoft.public.inetserver.asp.general:
Thanks, Evertjan. We made a design decision early on in the project
not to use the Session object -- for various reasons, mostly related
to scalability in some way. But you're right, of course; that would
be perfect.

This is why I described one of my fallback positions to be using a
database, which is the way many developers implement Session
functionality without the Session object. I believe MS eCommerce
Server (correct name?) does it that way.

That is duplicating the session object, and if that is done well, the
solution should work the same.
It seems, except for the Session object, any "variables" that can be
passed TO the CALLED asp file are essentially read-only in the sense
they cannot be changed and passed back to the CALLING asp file.

I don't see why not. A "variable" stored in a database should have the
same workings as using the session database structure.
For example, I can create Request.Form(1) in the CALLING file using an
<input> element, and I can read it in the CALLED file.

But that is not using a serverside daabase.
However, this
expression is not permitted on the left side of an equation, so it
seems I cannot change that value.

And rightly so.
Moreover, if I create yet another Form name / value pair in the CALLED
file, that one will NOT be visible to the CALLING file upon return.

Can you think of any way a script can modify a passed value in the
CALLED file so a script in the CALLING file can see it?

I personally think you should keep to includes
or change your design decision.

It is never to late to improve on design decisions,
they are only to be kept static at your peril.

In the end:

What is wrong with an include,
where the whole code is contained in:

If Not myBoolean Then
' whole code
End If

as opposed to a statement line

If Not myBoolean Then Server.execute "...."

?
 
E

Evertjan.

Jon Paal [MSMD] wrote on 06 aug 2007 in
microsoft.public.inetserver.asp.general:
my bad, all page scope variables are not handled, see Dave's comment
below.

Jon, what are you refering to?
 
D

Dave Anderson

Evertjan. said:
Jon, what are you refering to?

Evertjan, you really ought to give it a rest. I may be your only defender in
here, and even I tire of the constant policing.
 
E

Evertjan.

Dave Anderson wrote on 06 aug 2007 in
microsoft.public.inetserver.asp.general:
Evertjan, you really ought to give it a rest. I may be your only
defender in here, and even I tire of the constant policing.

Dave, I think this is nonsense. Why even you?
I am just asking. If you think that is policing, so be it.
 
A

Anthony Jones

Jim Rodgers said:
Thanks, Anthony!

I have not yet determined that having a large include file is a problem. I
may keep what I have until it is a problem. However, I am not only creating
a specific web application, but I am trying to keep my options open for code
reuse since the project is turning into a decent platform for more work.

Your idea about a VB6 DLL is excellent. I am planning to replace a lot of
my #Includes (containing my VBScript Subs and Functions "library") with a DLL
soon. But it will make more sense to you and everyone if I mention one more
aspect of the problem I have in the current case.

The subject asp file (which currently is #Included and which I would prefer
to be Server.Execute'd) processes a huge number of Request.Form(i) variables
for all kinds of input validation requirements. It is because of the
Request.Form(i) variables that I felt Server.Execute would be a good choice.
I hate having to pass all these TO the CALLED file.

What can't the function you call get the form values from the Request
object?
Since no one could tell me about [an obscure] technique for getting one or
two answers back to the CALLING script, I have decided to write the
validation results to a database. Thus, I need only to check the database
when I return to the first file. Previously, I acted on the validation
results (with Response.Write's) in the CALLED file. Now I will simply do
that after I return. Even though the second file now does no output to the
client side, it still makes sense to use Server.Execute because of the sheer
volume of Request.Form(i) variables.

Would you agree?

No. The volume of values is not a problem there are numerous solutions to
this.

The appropriate approach is a function call and/or the use of Classes.

The fact that you need to jump through ugly hoops to attempt to force a
server.execute into a function call semantic (ie you want it to return a
value) indicates that it's not the right tool for the job.
 
J

Jim Rodgers

What can't the function you call get the form values from the
Request oject?

I was referring to the issue of passing the many Request.Form(i)
variables to a DLL. I did not want to stop and write a DLL right
now. Of course, with both the #Include and the Server.Execute,
I do not have a problem with this since Request is valid in those
cases. I would prefer not to write unplanned VB6 DLLs during
the main stretch of an ASP Classic project. In "Phase 2," if you
will, I can marshall together the opportunities for improvements
and assign VB6 DLL development in the context of the big picture.
Since no one could tell me about [an obscure] technique for
getting one or two answers back to the CALLING script, I have
decided to write the validation results to a database. Thus, I
need only to check the database when I return to the first file.
Previously, I acted on the validation results (with
Response.Write's) in the CALLED file. Now I will simply do that
after I return. Even though the second file now does no output
to the client side, it still makes sense to use Server.Execute
because of the sheer volume of Request.Form(i) variables.

Would you agree?
No. The volume of values is not a problem there are
numerous solutions to this.

The appropriate approach is a function call and/or the use
of Classes.

The fact that you need to jump through ugly hoops to attempt
to force a server.execute into a function call semantic (ie you
want it to return a value) indicates that it's not the right tool
for the job.

For me, writing the result to a database is not an inherently ugly
hoop. It's akin to using Session, but without the scalability issues.
Of course, potential problems could sometimes arise if the data
model did not accommodate the subject information, but that did
not happen here. If it had been a problem, then one might be
concerned that the data model was effective, or that the project
management issues (e.g., deadlines) would kick in. The point is
the code was already done in-line, then became an #Include.

All this time, there was one little boolean that was being carried
forward to the rest of the program. I never embarked on using
Server.Execute when I knew I needed something to come back
from it. There was just this one little thing versus hundreds of
lines of code, and it was not in the existing data model at the time.

As it turns out, I now have re-written the whole thing. The large
number of variables to be validated was creating a large volume
of code. However, I had the variables formatting and limits specs
in a database, so I took the additional time to write better code
rather than to brute force it with a lot of easy code. The result
was so tight, I no longer feel the need to extract it into either an
#Include or a Server.Execute. (When we started, validation was
somewhat generic. It became much more complex, however, as
other parts of the project emerged into testing.)

This code section is now back in-line with the "main" program.
There no longer is an issue with Server.Execute.

My original reason for putting it into an #Include was the code
(i.e., the "main" program) was just getting too big. We did not
anticipate how much the client needed this validation. Testing
later revealed the core function, a complex financial simulation,
required much more extensive input validation (including limits
based on previous user inputs) to maintain simulation stability.

Anyway, as the validation section gradually became horrendous,
it first was #Included. Later, I wanted not to load all these lines
of code unless I needed them, hence the Server.Execute idea,
since the program logic could jump around it. About 1/3 of the
time I was processing a tabbed dialog containing a sequence of
input pages. The other 2/3 of the time, this validation section
was non-value-added overhead.

The reason for wanting the SINGLE piece of information back
from the Server.Executed file was simply to know if Validation
had in fact detected an error. If there were an error, the code
would not process the State Transition Matrix; it would simply
render the same tab page again (with error messages added)
rather than navigate to the next state (i.e., user page). It is
not easy to fully explain this here because there are many
aspects both to the technical objectives of the code and to the
history of the project and client relationship.

It's always a judgement call when either scope creep or the
revelation of unknown requirements causes more code to be
developed. Do you write as "ingeniously" as you would like,
or do you blast it out in a manner more consistent with what
the customer is willing to pay? Sometimes you have to make
what is essentially a business decision to write more without
getting paid more in order to protect the client relationship for
future business. Quality is a high level requirement, and that
includes reliability and maintainability of the product. Hence,
there is a need to go back and tighten-up code if it starts
getting too loose or too big. Clients don't always understand
this. I always endeavor to maintain the right (in the contract
with the client) to "keep" code snippets for re-use – just as I
draw on our code library to keep their price under control. I
can justify the extra-and-sometimes-unpaid work this way.

So, I believe the problem at hand is solved, and there are new
problems already.

Watch as I start new threads with deceptively naive questions.

I really appreciate all the participation in this thread. Thank
you for your time.

Cheers,

Jim Rodgers
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top