views:

1705

answers:

3

I have a .NET 3.5 based web service running at http://localhost/serivce.svc/. Then I have an ASP.NET application running at http://localhost/myApp. In Application_Load my application reads some XML configuration from the web service. That works fine on my machine, but:

  • On Windows Vista with IIS 7 the request to the web services fails.
  • The web service can be accessed via the browser without any problem.
  • I configured the app pool of my application to run as admin. I added the admin to the IIS_USRS group, but it still cannot access the web service. impersonate=true/false seems not to make a difference.
A: 

Try to give access to the IIS_USRS group on the folder that contains the web service, and check again :).

Wael Dalloul
That's not the problem. Every part of the system works in isolation, if I change configuration to access data from a different machine. The problem only comes up if both instances are running on vista.
Achim
A: 

When you get the 503 errors, have you considered looking at the event viewer on the machine to see if IIS logged the exception.

When started from Visual Studio, is it running in the Visual Studio web server or IIS? (This is a critical point. Visual Studio, since 2005, has used its own web server by default for web projects. And this web server is executed under your user account -- also critical for what's coming next.)

You're attempting to read some XML goodness out of a file. In .NET, in order to read a file, for some reason the user executing the code (in IIS7 I believe it is IIS_USERS and NETWORK SERVICE; in older versions of IIS, IUSR_MachineName and ASPNET) have to have both read and write access permissions. So the very first thing I'd check is the ACL on that XML file. Make sure the appropriate users have read/write access. This would be the NTFS permissions, by the way -- right-click the file in Explorer, choose Security, and add the appropriate perms.

What gave it away is that it works when you run the solution from Visual Studio, but not when it's executed from IIS. I don't believe you're getting 503 back from the web service -- you're most likely getting 503 from myApp itself.

The reason for this 503 is because you're attempting to read this file on Application_Load. That means that before any page can even attempt to be served, your XML file must be read and parsed. Upon reflection, and re-reading the question one more time, I'm now 99.99% certain that the inability to read this file (due to the lack of write permissions on it) is the issue.

My advice: Take out all of the admin stuff you'd done, take your user/ACL configuration back to normal, how it was -- including the AppPool. Then, follow the advice above to grant the appropriate IIS users read/write access to the XML file. I'm 99.99% sure your app will now work in IIS.

John Rudy
Your explanation sounds logical to me, but I think there is one misunderstanding: The XML configuration is not read from the file system. It's read via HTTP from a URL with is located on the same server (http://localhost/serivce.svc/). My process might not be allowed to access that URL, but how to check that?
Achim
I'm not certain why that would be off the top of my head; however I'm still fairly convinced your 503s are due to `Application_Load`. At this point, I'd probably have to see more of the app ... At this point, if you're using WCF, it's time to start using blowdart's advice.
John Rudy
A: 

First off, take admin out of the IIS_WPG group before you forget, and configure your app pool back to normal.

Now, turn on WCF logging on the service by putting the following in your web.config file -

<system.diagnostics>
    <sources>
        <source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
            <listeners>
                <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                    <filter type="" />
                </add>
                <add name="ServiceModelMessageLoggingListener">
                    <filter type="" />
                </add>
            </listeners>
        </source>
    </sources>
    <sharedListeners>
        <add initializeData="c:\logs\web_messages.svclog"*
            type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
            <filter type="" />
        </add>
    </sharedListeners>
</system.diagnostics>


<system.serviceModel>
...
   <diagnostics>
     <messageLogging logMalformedMessages="true" *logMessagesAtServiceLevel="true"*
       logMessagesAtTransportLevel="true" />
   </diagnostics>
...
</system.ServiceModel>

Create the c:\logs directory and make sure the application pool identity user has full control on that directory. Now test your app.

If no log files are being created then there's a problem reaching the WCF service. If log files are being created view them in the Service Trace viewer which comes as part of the Windows SDK. You'll see a red message which is the log entry containing the exception thrown inside the service - this should give you a pointer to where your service code is going wrong.

If the problem is inside your app, rather than the service then you should be logging exceptions inside your Application_Load event (you should be logging exceptions anyway) - however if you try with a global exception handler, well, your app is failing on startup and so the global exception handler will never start to run - instead of putting potential failable scenarios in Application_Load I'd move that out to a utility class which provides an access point to the information you need (say myGlobalThingumy.GetStuff()). Make this class a singleton, and then check if you have the stuff already - if you don't, then you make your web service call. It would act much the same as putting it in Application_Load but will enable global error handling to work, and make your debugging easier.

blowdart