How to prove the application working on web farm? - asp.net

I have created a application that is the custom session mode and session bridge between asp and asp.net application. Now, I need to prove that is working or not. So, I have created an asp.net page. In this page, I had written this code.
System.Diagnostics.Process.GetCurrentProcess.Id
This produces worker process id. I can prove the application working on web farm due to changing worker process. But I don't know how to produce worker process id from classic asp. Please tell me. How can I get worker process id from classic asp?

Have you considered setting a custom HTTP Response Header on each of the IIS servers in the web farm then displaying the value on the page? Like so:
HttpContext.Current.Response.Headers["X-ServerName"]
Where X-ServerName is the custom HTTP Response Header on each of the IIS Servers.
EDIT:
Sorry, for Classic ASP you can try using javascript in the page to get the header.
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);

Related

Authentication prevents posting to Classic ASP from Web form using WebClient() from Code Behind

I am managing and old web site (site, not application) that is a hybrid of Web Forms and Classic ASP. The Classic ASP is being phased out, but that is probably a year away. Right now, we are dropping the old form of authentication in favor of Windows Authentication in the web.config.
The problem is that I am attempting to post to a Classic page from the code behind of a web form (http://www.blahsiblah.com/index.aspx) and am getting a 401 error.
var webClient = new WebClient();
var urlClassicASP = "http://www.blahsiblah.com/classic.asp";
var responseArray = webClient.UploadValues(urlClassicASP, "POST", nameValueCollection);
This throws "The remote server returned an error: (401) Unauthorized"
My question is, how can I post to the classic page without invoking the authentication of the dotNet side?
There are multiple ways to achieve this
Here is a simple suggestion that I hope helps
.Net
Use 127.0.0.1 (or your internal 192.169 / 10.1* ) IP to post to the page vs the public URL
Add a parameter (call it 'bypassauth' or something unique ) when sending the request to the ASP page
Add a parameter that identifies the user that you have authenticated in the .Net side
ASP
Find the include where the authentication check is happening and in that check, add another condition before returning 401 that checks two things
1) Request is from local/internal IP
2) Has the bypassauth parameter
3) the user id is valid
This way your old ASP code will still continue to work if requested from a browser and expect user to be authenticated however, when sending the request from .net will let you bypass authentication
I'm sure there are other ideas too, but this is just one approach
My solution was to set:
webClient.UseDefaultCredentials = true;

need application url from console application

I have a MVC web application and a console application created as a separate project inside my web application. I want this console application to be run as a windows service at specified intervals. The console application is for sending mail to some persons. I need to include my application URL in the mail content body which redirect to my application login page. Since i am running this service for more than one instance i could't hard code the URL in code. Someone please help. I tried the below code. But it is returning null value.
var site = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.ApplicationPath.TrimEnd('/');
var url = string.Format("<a href='{0}'>Login</a>", site);
I converted this from the comment to the question.
You are trying to obtain information from HttpContext.Current in situation when there is no HttpContext available at all - because your console application is launched directly by the operating system and not on the event of incoming http request (as oposed to request handling in your MVC application) - so there simply is no http context to use (hence HttpContext.Current is null in your console application).
You have to establish your own application logic for your console application that determines which URL to use in your emails. What would that be depends on the answer to the question "what does the url to be used in each email depend on specifically"? In other words - "how should each email know what URL to use"? Once you figure out the answer to that question then you can think of how to pass that dependency to your windows service.
Example (I do not know if it describes your case):
there are several web applications on different URLs
each of these web applications can add email to the queue to be send
windows service (console app) is scheduled to run once in a while and process the queue by sending the emails. Each email has to have an URL of the application from where it was added.
Assuming the example above you can just add the email together with the URL of the application to the queue (insted of just the email) and then retrieve that information from the queue in your console application. So then each of the emails has associated URL. It is irrelevant how would the queue itself be implemented (SQL, file, ...).

ASP.NET MVC with Forms Auth and WebApi with Basic Auth

I have a WebApi using Basic Auth nicely. And I have an MVC site using Forms Auth nicely. But here's the catch:
Client X has a dedicated database with any number of Contacts and Products. The MVC site is a dedicated site for them (via {clientId} routing), which allows their Contacts to log in (via Forms Auth) and place orders for their products. The Contact must be Form-ly logged in to place an order.
The product orders (need to) hit the WebApi to be recorded in the Client's database.
But since the WebApi uses Basic Auth to validate the Client, not the Contacts who placed the orders, every request comes back is 401 - Unauthorized.
I've checked out ThinkTecture as suggested by a number of posts here on SO, however it doesn't get me what I need because I'm not looking to allow Forms Auth in the WebApi. I don't want to authenticate the Contact from the Client's database in the WebApi, I want to authenticate the Client in the WebApi.
Has anyone come across a similar scenario and am I missing something glaringly obvious? Perhaps I need to implement both Forms and Basic on the site?
The very standard Api call I'm making from the site (where the UserName and Password are the Client's, not the Contact's):
var clientId = new Guid(RouteData.Values["clientId"].ToString());
var baseUrl = ConfigurationManager.AppSettings["ApiBaseAddress"];
var authHeader = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", _shoppingCartSettings.UserName, _shoppingCartSettings.Password)));
var requestUrl = String.Format("api/{0}/inventory", clientId.ToString());
var httpWebRequest = WebRequest.Create(baseUrl + requestUrl);
httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, "Basic " + authHeader);
httpWebRequest.Method = "GET";
httpWebRequest.Accept = "application/json";
httpWebRequest.ContentType = "application/json";
try
{
using (var httpWebResponse = httpWebRequest.GetResponse())
{
// we never get here because of a 401
}
}
catch (WebException ex)
{
using (var httpWebResponse = ex.Response)
{
// we always get here
}
}
If I set up a separate test client and make the same call, it works great :/
Is your Web API under the same virtual directory and configuration as the MVC site? It looks like the Forms Auth HTTP module kicks in for your API, which you don't want. As long as you don't plan to call the API directly from the browser, move it to a separate virtual directory that is set up exclusively for basic auth, no forms auth module in the web.config for the API.
Why not have one login for your MVC site that has the ability to submit orders for every Client? It makes sense for your WebAPI to only allow Clients to submit orders for themselves. But I don't think it makes sense to have your MVC site authenticate as different Clients based on the Contact. Your MVC site would have to store the passwords for each Client.
Instead, create one login for the MVC site and give it the ability to submit an order for any Client.
After much banging of head against the not-so-proverbial wall, and a much needed shove by #0leg, I've discovered the cause.
In the Properties of my WebApi project file under Web > Servers, the Visual Studio Development Server was being used with a Virtual Path of "/", whereas my MVC project file was set up to use the Local IIS Web Server. The MVC project also had the Apply server settings to all users (store in project file) option checked.
Setting both to use the local IIS server resolved it.
Upon further contemplation, this now seems logical since they were essentially running on different servers.
Posting this for posterity's sake.

Client side trouble when calling

Please use my previous question as reference. I have marked an answer already.
Question
I'm a .NET developer doing some work for a company that uses Classic ASP. My experience with server side development is VB.NET or C# with some sort of MVC pattern. Consider the following code snippet, I wrote it in an ASP page the company would like to keep and "include" in other pages where this web call would be needed. Kind of like a reusable piece of code. I've left some out for sanity reasons.
//Create ActiveXObject, subscribe to event, and send request
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
xmlDoc.loadXML(xmlHttp.responseText);
debugger;
var JSON = $.xml2json(xmlDoc);
parseResponse(JSON);
}
}
urlToSend = encodeURI(REQUEST);
urlRest += urlToSend
xmlHttp.open("GET", urlRest, false);
xmlHttp.send(null);
After struggling with a variety of security problems, I was glad when this finally worked. I changed a setting in Internet Options to allow scripts to access data from other domains. I presented my solution, but the Company would have to change this setting on every machine for my script to work. Not an ideal solution. What can I do to make this run on the server instead of the client's browsers?
I have a little bit of knowledge of the <% %> syntax, but not much.
This SO Question should help you call the service server side:
Calling REST web services from a classic asp page
To Summarise, use MSXML2.ServerXMLHTTP
Set HttpReq = Server.CreateObject("MSXML2.ServerXMLHTTP")
HttpReq.open "GET", "Rest_URI", False
HttpReq.send
And check out these articles:
Integrating ASP.NET XML Web Services with 'Classic' ASP Applications
Consuming XML Web Services in Classic ASP
Consuming a WSDL Webservice from ASP
You will also need a way to parse JSON

How do I get the host domain name in ASP .NET without using HttpContext.Current.Request?

I've got an ASP .Net application running on IIS7. I'm using the current url that the site is running under to set some static properties on a class in my application. To do this, I'm getting the domain name using this (insde the class's static constructor):
var host = HttpContext.Current.Request.Url.Host;
And it works fine on my dev machine (windows XP / Cassini). However, when I deploy to IIS7, I get an exception: "Request is not available in this context".
I'm guessing this is because I'm using this code in the static constructor of an object, which is getting executed in IIS before any requests come in; and Cassini doesn't trigger the static constructor until a request happens. Now, I didn't originally like the idea of pulling the domain name from the Request for this very reason, but it was the only place I found it =)
So, does anyone know of another place that I can get the host domain name? I'm assuming that ASP .Net has got to be aware of it at some level independent of HttpRequests, I just don't know how to access it.
The reason that the domain is in the request is...that's what's being asked for. For example these are a few stackexchange sites from http://www.stackexchangesites.com/:
http://community.ecoanswers.com
http://www.appqanda.com
http://www.irosetta.com/
If you ping them, you'll see they all point to the same IP/Web Server and be served by the same app (or multiple apps in this case, but the example holds if it was one big one)...but the application doesn't know which one until a host header comes in with the request asking the server for that site. Each request may be to a different domain...so the application doesn't know it.
If however it doesn't change, you could store it as an appSetting in the web.config.
Use global.asax or write a HttpModule and subscribe to start request events. You will have the request passed into your event handler.
Use this instead:
HttpRuntime.AppDomainAppVirtualPath
Or if you want the physical path:
HttpRuntime.AppDomainAppPath
For further reading:
http://weblogs.asp.net/reganschroder/archive/2008/07/25/iis7-integrated-mode-request-is-not-available-in-this-context-exception-in-application-start.aspx

Resources