Calling a method in an ASP.NET application from a Windows application - asp.net

Other than using a web service, is there anyway to call a method in a web app from a windows application? Both run on the same machine.
I basically want to schedule a job to run a windows app which updates some file (for a bayesian spam filter), then I want to notify the web app to reload that file.
I know this can be done in other ways but I'm curious to know whether it's possible anyway.

You can make your windows app connect to the web app and do a GET in a page that responds by reloading your file, I don't think it is strictly necessary to use a web service. This way you can also make it happen from a web browser.

A Web Service is the "right" way if you want them to communicate directly. However, I've found it easier in some situations to coordinate via database records. For example, my web app has bulk email capability. To make it work, the web app just leaves a database record behind specifying the email to be sent. The WinApp scans periodically for these records and, when it finds one with an "unprocessed" status, it takes the appropriate action. This works like a charm for me in a very high volume environment.
You cannot quite do this in the other direction only because web apps don't generally sit around in a timing loop (there are ways around this but they aren't worth the effort). Thus, you'll require some type of initiating action to let the web app know when to reload the file. To do this, you could use the following code to do a GET on a page:
WebRequest wrContent = WebRequest.Create("http://www.yourUrl.com/yourpage.aspx");
Stream objStream = wrContent.GetResponse().GetResponseStream();
// I don't think you'll need the stream Reader but I include it for completeness
StreamReader objStreamReader = new StreamReader(objStream);
You'll then reload the file in the PageLoad method whenever this page is opened.

How is the web application loading the file? If you were using a dependency on the Cache object, then simply updating the file will invalidate the Cache entry, causing your code to reload that entry when it is found to be null (or based on the "invalidated" event).
Otherwise, I don't know how you would notify the application to update the file.

An ASP.NET application only exists as an instance to serve a request. This is why web services are an easy way to handle this - the application has been instantiated to serve the service request. If you could be sure the instance existed and got a handle to it, you could use remoting. But without having a concrete handle to an instance of the application, you can't invoke the method directly.
There's plenty of other ways to communicate. You could use a database or some other kind of list which both applications poll and update periodically. There are plenty of asynchronous MQ solutions out there.

So you'll create a page in your webapp specifically for this purpose. Use a Get request and pass in a url parameter. Then in the page_load event check for this paremter. if it exists then do your processing. By passing in the parameter you'll prevent accidental page loads that will cause the file to be uploaded and processed when you don't want it to be.
From the windows app make the url Get request by using the .Net HttpWebRequest. Example here: http://www.codeproject.com/KB/webservices/HttpWebRequest_Response.aspx

Related

How to run code immediately in some other application

I have two Asp.Net web apps, App 1 and App 2. They both use the same database. I am trying to give command from App 1 and immediately run a bit of code in App 2.
The only way I can think of doing this is by inserting a command in the database and have App 2 poll the database every few minutes. But this means there may be a delay in running the code.
Is there a way to run code in App 2 immediately?
You can fire an HttpRequest from one app to another and the code will run almost immediately.
I don't know what language and platform you're using, so it's hard to give you concrete examples, but here are the outlines:
Create a page in App2. In standard ASP.Net, you can use a handler. In ASP Core, you can use an API controller. Both car return a single value or a full object in JSON or XML. Or you can use a standard page if you like to return HTML. The code behind is what you want to run. The rendered page or return value from the handler or controller is what you want App1 to get back in response.
Then from App1, issue an HttpRequest to that page in App2 and check the response to see how to continue (for example, if the code ran successfully or not).
The HttpRequest is in case you want to make the call from the server side of App1. If you want to make the call from the client side, then you use Ajax instead. In the case of Ajax, you have to pay attention to the security side, because you don't want to allow whoever to call that page from App2 unless it unless the code behind doesn't pose any security risk and doesn't return any sensitive data.
One last idea specific to your scenario, since both apps are using the same database, you can add the required values to the database as you were planning to do, and then issue a simple HttpRequest. This way, you don't need to worry about security or passing a any sensitive info. When App2 receives the request, it checks the database to see if the request was actually made from App1 and then processes it, otherwise ignores it.

Interactive HTTP server

For manually testing an HTTP client in my application, I'd like to use a tool which starts an HTTP server my application can connect to and that lets me respond to request from my application manually. I'm basically looking for a tool with a GUI that lists all incoming requests and allows me to select a status code and type a response message. I've already tested the functionality with unit tests but I also want to verify it manually with no mocking etc.
Sounds simple but I didn't find such a tool. I've found some that can be scripted but no interactive one. Do you know one?
This can probably be written relatively easily by creating the Swing GUI dialog popup inside the servlet servicing methods. Have never seen Tomcat running this way but probably it would. Only, mind the server time out. It may be not long enough for you to make an input and require to be configured, also on the client side. Also, parallel calls will make multiple popups that may be difficult to respond but probably this is a single client app.
As a simplest solution, server GUI can be simply disposed after call and newly created as the next call arrives. This will make eveything indepenent on how servlet container is managing the servlets (does it stays, is it destroyed, maybe class is unloaded, who knows). Advanced solution could include the "server servlet" that would interact through its own JSP page but then it may be complex to update it when the new call arrives (unless maybe refresh periodically).

detecting undisposed web service calls (ASP.NET)

I'm inheriting a legacy project, and there's a page that calls a method that makes a web service call. Load and performance testing has detected that this page sometimes takes a really long time to close, but usually it's fine, and if there is one hanging, all other requests for that page hang until the first one resolves, and then they all resolve.
I think this might have something to do with the web service being instantiated and not disposed, but I don't know how I can be more sure. I tried to add a delegate to the Dispose method but that doesn't seem to ever fire. (I'm not sure it would without Dispose being called explicitly, but that doesn't really matter.)
So what can I look for on the production server or any deployed environment to watch those requests pile up and go out (or get handled in an orderly manner, if they aren't the problem)?
You might consider using a tool like .NET Memory Profiler. You can use it to attach to your running application, and it can find and report all undisposed objects.
I think they have a free two week trial.
In your web app code, you could write to a log (event log, text file) right before you send a request, and again right after you get the response. Include some identifying information about the request. Add timestamps.
If you only want to use this while debugging, wrap it in #debug.
Or if you want to test in release mode, you could put a boolean in appSettings in web.config so you could turn the logging off and on.

ASP.NET concurrency

I have an ASP.NET application that starts a long running operation during the Event Handler phase in the ASP.NET Page life cycle. This occurs when the end user pushes a button a bunch of queries are made to a database, a bunch of maps are generated, and then a movie is made from jpeg images of the maps. This process can take over a minute to complete.
Here's a link to the application
http://maxim.ucsd.edu/mapmaker/cbeo.aspx
I've tried using a thread from the threadpool, creating and launching my own thread and using AsyncCallback framework. The problem is that the new thread is run under a different userid. I assume the main thread is run under ASPNET, the new thread is run under AD\MAXIM$ where MAXIM is the hostname. I know this because there is an error when it tries to connect to the database.
Why is the new thread under a different userid?
If I can figure out the userid issue, what I'd like to do is check if the movie making process has finished by examining a Session variable in a Page_Load method, then add a link to the page to access the movie.
Does anyone have any good examples of using concurrency in a ASP.NET application that uses or creates threads in an EventHandler callback?
Thanks,
Matt
Did you read this?: http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
Quoting one relevant portion from that link (you should read the whole thing):
A final point to keep in mind as you build asynchronous pages is that you should not launch asynchronous operations that borrow from the same thread pool that ASP.NET uses.
Not addressing the specific problem you asked about, but this is likely to come up soon:
At what point is this video used?
If it's displayed in the page or downloaded by the user, what does the generated html that the browser uses to get the video look like? The browser has to call that video somewhere using a separate http request, and you might do better by creating a separate http handler (*.ashx file) to handle that request, and just writing the url for that handler in your page.
If it's for storage or view elsewhere you should consider just saving the information needed to create the video at this point and deferring the actual work until the video is finally requested.
The problem is that the new thread is run under a different userid. I assume the main thread is run under ASPNET, the new thread is run under AD\MAXIM$ where MAXIM is the hostname.
ASPNET is a local account, when the request travels over a network it will use the computer's credentials (AD\MAXIM$).
What may be happening, is that you're running under impersonation in the request - and without in the ThreadPool. If that's the case, you might be able to store the current WindowsIdentity for the request, and then impersonate that identity in the ThreadPool.
Or, just let the ThreadPool hit the DB with Sql Authentication (username and password).

IIS Integrated Request Processing Pipeline -- Modify Request

I want to implement an ISAPI filter like feature using HttpModule in IIS7 running under IIS Integrated Request Processing Pipeline mode.
The goal is to look at the incoming request at the Web Server level, and inject some custom HttpHeaders into the request. (for ex: HTTP\_EAUTH\_ID)
And later in the page lifecycle of an ASPX page, i should be able to use that variable as
string eauthId = Request.ServerVariables["HTTP\_EAUTH\_ID"].ToString();
So implementing this module at the Web Server level, is it possible to alter the ServerVariables collection ??
HttpRequest.ServerVariables Property is a read-only collection. So, you cannot directly modify that. I would suggest storing your custom data in httpcontext (or global application object or your database) from your httpmodule and then reading that shared value in the aspx page.
If you still want to modify server variables, there is a hack technique mentioned in this thread using Reflection.
I believe the server variables list only contains the headers sent from the browser to the server.
You won't be able to modify either the HttpRequest.Headers or the HttpRequest.ServerVariables collection. You will however be able to tack on your information to any of:
HttpContext.Current.Items
HttpContext.Current.Response.Headers
Unfortunately, Request.Params, Request.QueryString, Request.Cookies, Request.Form (and almost any other place you'd think of stuffing it is read only.
I'd strongly advise against using reflection if this is a HttpModule you're planning on installing into IIS 7. Given that this code will be called for (potentially) every request that goes through the web server it'll need to be really fast and reflection just isn't going to cut it (unless you have very few users).
Good luck!

Resources