Classic asp migration to windows 2008 RC - asp-classic

I am very new to asp classic application. The below code snippet is from a asp classic application which we are going to migrate to Windows Server 2008RC.
1.Set objConfig_Constantsinc = Server.CreateObject("Notion.Configuration")
2.Dim account
3.account = objConfig_Constantsinc.GetConfig("SQLAccount")
As per my understanding in line number 1 we are creating an instance of a COM class. Now in line number 3 using this instance we are trying to get some config data "SQLAccount" .
Here is my doubt. In classic ASP application where are we storing these type of configuration strings(For eg: "SQLAccount"). Is there any concept of global configuration file. Kindly guide me.

As stated in the comments & by yourself, the Notion.Configuration item is some kind of com object, if you're porting this to the new server you dont really have a problem (assuming you port the underlying storage mechanism, i.e. the com object could be storing the vars anywhere (Eg: sql, registry, files)
If for some reason you want to do away with the com object for storing configuration data (i.e. your question regarding the existence of a global configuration file) - there is a mechanism for doing this in Classic ASP.
Specifically, the global.asa file, commonly, the common.asa file is placed in the root of your site and exposes application variables that can be read from any asp file within your application.
More Details: http://msdn.microsoft.com/en-us/library/ms525316(v=vs.90).aspx
Declaring application level globals is easy:
Example from a global.asa:
<script language="VBScript" runat="Server">
Sub Application_OnStart
Application("SQLAccount") = "whatver"
End Sub
Example in any other asp page:
response.write Application("SQLAccount")
I would remind you though, that declaring unnecessary global vars is counterproductive & you should carefully choose what to expose at a global level to avoid confusion / duplicate items in memory.

Related

COM visible .NET class cannot get System.Web.HttpContext.Current when used in classic asp

My company would like to update legacy visual basic 6/classic asp code. We do not have access to a visual basic 6 compiler, so it seemed like a good idea to use Visual Studio 10 and recompile the visual basic 6 code as a VB.NET class. With some minor modifications everything compiled and we registered it as a com object to be called from classic asp.
Now we are trying to access global variables from the asp server. After an extensive search on Google, the only way mentioned was to use System.Web.HttpContext.Current or System.Web.HttpContext.Current.Application . However, this doesn't appear to work.
Here is the code leading up to error. We have imported System and System.Web.
Public Function DoSomethingUseful() As String
Dim objCurrent As System.Web.HttpContext
DoSomethingUseful = Nothing
objCurrent = System.Web.HttpContext.Current
If objCurrent Is Nothing Then
Throw New Exception("No Context.") '<--- THIS EXCEPTION IS THROWN
End If
The problem is we can't get a current instance of the http context and the exception is thrown. Every example I've seem shows that the line objCurrent = System.Web.HttpContext.Current should work but it doesn't. Perhaps it's because we are not using ASP.NET? If not then why isn't it working?
Yes, it is because you're not using ASP.NET.
Despite the similar sounding names, and to a certain degree similar design choices, there is no relationship whatsoever between ASP.NET anything and "Classic" ASP anything. They are completely independent environments.
To access directly the ASP context objects (not the similarly-named ASP.NET context objects which in your application don't even exist), your object must be a registered COM+ object, so:
Your class must inherit from System.EnterpriseServices.ServicedComponent *
On Windows 7/2008 and up, you must enable the "Allow IIS Intrinsic properties" from Component Services, just like you would have to in VB6 (open \Component Services\My Computer\COM+ Applications\YourComPlusApp\Components; select all the objects that need the ASP objects; right-click; click on Properties; go to the Advanced tab).
You can then retrieve the ASP objects (Application, Server, Request, Response, Session) from the COM+ ObjectContext.
Your code would look something like this:
objCurrent = System.EnterpriseServices.ContextUtil.GetNamedProperty("Application")
There are also attributes that you can add to your class to simplify the deployment of the code, but that's a bit outside the scope of this question.
For your reference:
ASP Built-in Objects
ContextUtil.GetNamedProperty Method
* I don't remember 100% if this is a hard requirement. It might actually depend on what the object is actually doing with COM+.

ASP .NET WebService that accept large file input from a different server

I need to build a Web Service in ASP .NET 3.5 (C#) that accepts a large file (documents like DOC/PDF/XLS and similar of about 10-20 MB) as input parameter.
This Web Service is called by many 3rd party applications, many of which are developed in PHP. Once the WS has the file, it has to put it inside another .NET application documents archive.
I already tested the entire round and it works. The file wasn't passed inside the call url, it was taken by a server local path.
Now, my problem is: how can I pass a big file to the WS, when the calls come from an application that is hosted on a different server?
EDIT: added an example.
The case:
Server A is a PHP application that calls the .NET Web Service on Server B and passes it a file. Then, the WS on Server B will post the file somewhere else on Server C.
In other words my problem is the communication between Server A and Server B. I need something like a "query string" which I can use to pass a file as byte array or anything else. Something like:
http://www.myserver.com/InsertFile.ashx?file=A3Fdf3Gjy5... <-- byte array of the file
Obviously, the query string doesn't suit very well to my purpose...
I want to know if what I want to do is possible and which technic I should use to make it works.
You could use a POST instead of a GET to allow larger files (and be semantically correct). A similar question is asked here. Leading to this link
If the web service is yours you can achieve it by changing web.config file. Please refer :
How do I upload large (> 25MB) files to a web service?

ASP.NET unit testing Windows7/IIS7

Spent several hours today trying to write some unit tests against an ASP.NET project. It's Visual Studio 2010.
Using Windows 7 Enterprise with IIS7.
Steps I took were:
Added a new test project to the solution
Opened a class file as part of the web site (Member.vb)
Right clicked within the class file and "Generate unit tests"
Select the methods I wish to generate stubs for, choose to add to my test project, click OK
Open up the generated MemberTest.vb file in the test project, click within one of the generated tests, click "Run tests in curent context"
When following these precise steps on my Windows XP Professional with IIS6 machine it works fine.
However on the Windows 7 Enterprise machine on IIS7 I get:
The URL specified ('http://localhost/MyProject') does not
correspond to a valid directory. Tests configured to run in ASP.NET in
IIS require a valid directory to exist for the URL. The URL may be
invalid or may not point to a valid Web application.
So what's going on, I can confirm I can browse to http://localhost/MyProject and it displays perfectly.
I feel sure I'm missing some sort of config in Windows/IIS but I'm really at a loss.
Generated test method:
<TestMethod(), _
HostType("ASP.NET"), _
UrlToTest("http://localhost/MyProject")> _
Public Sub MyMethodTest()
Dim target As Member_Accessor = New Member_Accessor() ' TODO: Initialize to an appropriate value
Dim CurrentVal As Short = 0 ' TODO: Initialize to an appropriate value
Dim expected As Short = 0 ' TODO: Initialize to an appropriate value
Dim actual As Short
actual = target.MyMethod(CurrentVal)
Assert.AreEqual(expected, actual)
Assert.Inconclusive("Verify the correctness of this test method.")
End Sub
(Cross-posted at ASP.NET Forums)
This could be a permissions issue.
If you're using the default directory (C:\users\\Documents\Visual Studio 2010\Projects), the app identity pool does not have permissions there. You'd have to create a project in something like C:\webs and make sure app pool identity has permission to the folder.
Refer to Rick Anderson's blog post at http://blogs.msdn.com/b/rickandy/archive/2011/04/22/test-you-asp-net-mvc-or-webforms-application-on-iis-7-in-30-seconds.aspx and see if that helps.
If you have not done unit testing before, I would really recommend that you start by just testing the functionality of your classes as cleanly as possible. Try to break you you functionality into small pieces that can be tested individually without and dependencies to the web context.
Have a look at this question for an idea about What is unit testing
Here is an MSDN Magazine article about testing
You can also have a look at this Blog. The examples are using NUnit but the principal is the same if you are using MSTest.
I can also recommend Roy Osheroves Book Art of unit testing
In you case if the Member class does not have dependencies to web context you don't need the IIS and could instead just do something like this:
<TestMethod()> _
Public Sub MyMethodTest()
Dim target = New Member()
Dim CurrentVal As Short = 0 ' TODO: Initialize to an appropriate value
Dim expected As Short = 0 ' TODO: Initialize to an appropriate value
Dim actual As Short
actual = member.MyMethod(CurrentVal)
Assert.AreEqual(expected, actual)
End Sub
I ran into the same problem today. After some research, I found this thread which suggested I check my event log. Upon doing that, I discovered numerous errors similar to the following:
(QTAgent32.exe, PID 12348, Thread 61) WebSites.GetWebServer: failed to
create AspNetHelper:
Microsoft.VisualStudio.Enterprise.Common.AspNetHelperException: The
website metabase contains unexpected information or you do not have
permission to access the metabase. You must be a member of the
Administrators group on the local computer to access the IIS metabase.
Therefore, you cannot create or open a local IIS Web site. If you
have Read, Write, and Modify Permissions for the folder where the
files are located, you can create a file system web site that points
to the folder in order to proceed. --->
System.Runtime.InteropServices.COMException: Unknown error
(0x80005000)
That lead me to this blog post which seems to have resolved the issue.
I just needed to go to "Turn Windows features on or off" and add IIS 6 Management Compatibility and all four subcomponents. I'm running Windows 7 Home Premium which doesn't have the Windows Authentication option, but that didn't seem to be an issue. Give it a shot and see if that resolves the issue for you.
You may need to enable "Use IIS" in the project properties, then click "Create Virtual Directory". Do you have IIS Express installed?

how to use common variables in asp.net?

I am new to .net and I usually had a common file which was having information of username,server,password,IPS and fixed integers in php and asp classic which i used to include in all files so that i could use them in any page. Since I have come to know that .net has no include function. how i can do it in asp.net?
Thank You
You wouldn't necessarily use an include file for sharing variables across a site. In .Net you would normally store values like this in the AppSettings section of the web.config file.
You can then access the values using code like:
string username = WebConfigurationManager.Appsettings["Username"];
Strictly speaking if working with application configuration (such as DB connection strings) these are placed in web.config for web applications and app.config for others.
There's also settings files.
Check out ConfigurationManager.
Other than that you must remember that "global variables are bad mmmkay" and aside from the various configuration files the nearest that you get to them would be public classes and properties.
In addition to AppSettings mentioned by Digbyswift, & webconfig (which I would also recommend), you could use a module:
Module Module2
Public MyGlobalInteger As Integer = 0
End Module
Then it can be called from anywhere like:
Dim someOtherNumber As Integer = MyGlobalInteger + 5
Though, you may want to make it readonly, depending on your usage.

Problems with Web.config and App.config

Intro:
Normally we store ConnectionStrings and some other settings (<appSettings> <add key...) in the Web.config or App.config.
My scenery:
Web application using factory pattern
with direct injection to read data
providers.
In the web.config I have the key
that tells me which DLL (provider)
will I use to retrieve my data.
I can have more than one provider
(each DLL will be a provider for MS
SQL, MySQL, or get the data from
some SOA service).
Each DLL has his own name (ID and namespaces) and will need to have is own
configurations (dataconnections,
service urls, etc...) , the first
idea is to write then in the
app.config.
Problems:
#1 - The website is running (runtime) I need to change the Data Provider, how can I do this? Somehow the default value written in the Web.config will be changed.
My objective is to be able to have multiple providers (and during runtime: add/delete providers and change configurations) - this leads me to my second problem:
.
#2 - Each Data Provider has custom configurations and App.Config files do not work with dll assemblies, only executables. This means that I need to write then on my Web.Config (I do not like this option, because once again I am updating my web.config in runtime). how can I solve this?
I am trying to avoid to write a custom settings XML file. My ideal solution is to deploy somehow the DLL and DLL.config per each provider. And once again during runtime I may need to change this configuration values.
.
Ok guys, while I was waiting for some help I put my hands to work and I was able to find a good solution (in my opinion of course :P).
Let me share it with you:
So, I have one web application, or one console application, or some other kind of application, and lots of class library, and I need to store informations (different per Visual Studio project) that will change during runtime.
Storing this information inside the Web.config or App.config is not a good idea for the many problems it takes.
The other way I see it is to have one XML config file per project.
Each application will read his own XML and add it to the Cache with CacheDependency (will expire when the XML config file is updated). This way we will not need to read the configuration all the times, and we also know when the configuration is changed.
IMO THIS IS THE FASTEST AND EASIEST WAY TO SOLVE THE PROBLEM, no need to use 3rd party frameworks (neither the time it takes to learn/program it).
.
Example code:
protected void Page_Load(object sender, EventArgs e)
{
DBConfiguration cachConf;
cachConf = Cache["cachConf"] as DBConfiguration;
if (cachConf == null)
{
cachConf = new DBConfiguration();
XmlDocument doc = new XmlDocument();
doc.Load(HttpContext.Current.Request.PhysicalApplicationPath + "bin/MyConf.xml");
XmlNodeList xnl = doc.GetElementsByTagName("username");
XmlElement xe = (XmlElement)xnl[0];
cachConf.Username = xe.InnerText.ToString();
xnl = doc.GetElementsByTagName("password");
xe = (XmlElement)xnl[0];
cachConf.Password = xe.InnerText.ToString();
Cache.Insert("cachConf", cachConf,
new System.Web.Caching.CacheDependency(
HttpContext.Current.Request.PhysicalApplicationPath + "MyConf.xml"),
DateTime.Now.AddMinutes(60), TimeSpan.Zero,
System.Web.Caching.CacheItemPriority.Default,
new System.Web.Caching.CacheItemRemovedCallback(
CacheItemRemovedCallBack));
}
LabelUsername.Text = cachConf.Username;
LabelPassword.Text = cachConf.Password;
}
private void CacheItemRemovedCallBack(string key, object value, CacheItemRemovedReason reason)
{
//Response.Write("Hello world");
}
You could store the credentials in a secondary config file referenced from web.config as follows:
<appSettings file="AppSettings.config"/>
You would still need to be careful to avoid editing conflicts on the external file.
Problem 1 - Runtime changes:
The solution that Microsoft hopes you apply to this type of problem is to simply keep the web server stateless. When an ASP.NET application recycles, it lets existing requests complete new requests start on a new process. For background, read about IIS Process Recycling. A change to web.config recycle the worker process, but users will not notice this (unless you keep state in the web server process). That's the MS design.
If you want to monitor for changes without recycling a process, you'll want something other than default web.config behavior. An example that comes to mind are cruise controls project files. They have a component that maps objects to and from xml, using that, you can use the FileSystemWatcher class to monitor for changes.
Problem 2 - Custom configurations:
It sounds like you have components from different libraries that have different dependencies. Your main assembly needs a means to instantiate a service, with a given set of dependencies. The MS data provider model is cool, but not this cool.
To be this cool, use an inversion of control container, because this is exactly what they do. I like autofac (because I like the Philip K Dick reference), but castle windsor is great.
Now, if you are talking about changes databases or data providers on the fly, it may be that configuration is not the right place. If your are reporting against x databases of y types, you need a central repository of that database information, and a configuration file is not the right place, nor is an IOC container the right solution.
As Precipitous suggested, try Castle Windsor:
http://www.castleproject.org/container/
You're doing Inversion of Control manually. Windsor will take the burden off of you.

Resources