Wednesday, November 10, 2010

How to solve Unhandled Error in Silverlight Application Code: 2104

How to solve Unhandled Error in Silverlight Application Code: 2104


Tags: IIS, MimeTypes

I’ve found that I get this error every time I upload a Silverlight application to a new webserver. IIS does not have the correct settings by default.

The Problem: You ftp a Silverlight App to an IIS website, go to the website in a browser, and get the following error:

Message: Unhandled Error in Silverlight Application

Code: 2104

Category: InitializeError

Message: Could not download the Silverlight application. Check web server settings



The Cause: The Silverlight Mime types (.xaml, .xap and .xbap) are not listed in that websites registered mime types, therefore IIS will not send those files to the browser.



The Solution: Open IIS on the server, go to HTTP headers, click on Mime Types, click “Add New” and add the following:



Extension – Mime Type

.xaml – application/xaml+xml

.xap – application/x-silverlight-app

.xbap – application/x-ms-xbap

Wednesday, August 11, 2010

ClickOnce: Application does not install when the time of Deployment

After running the publish wizard and running the setup.exe, a message box is shown saying that the "Application cannot be started. Contact the application vendor".
ERROR DETAILS
PLATFORM VERSION INFO 

Windows : 6.1.7600.0 (Win32NT)
Common Language Runtime : 4.0.30319.1

System.Deployment.dll : 4.0.30319.1 (RTMRel.030319-0100)
clr.dll : 4.0.30319.1 (RTMRel.030319-0100)
dfdll.dll : 4.0.30319.1 (RTMRel.030319-0100)
dfshim.dll : 4.0.31106.0 (Main.031106-0000)
SOURCES
Deployment url : file:///G:/OFFICE/R&D/Silverlight/Examples/WPF/BackupDB/Published/BackupDB.application


Application url : file:///G:/OFFICE/R&D/Silverlight/Examples/WPF/BackupDB/Published/Application%20Files/BackupDB_1_0_0_3/BackupDB.exe.manifest
IDENTITIES
Deployment Identity : BackupDB.application, Version=1.0.0.3, Culture=neutral, PublicKeyToken=28500bade1fb75cf, processorArchitecture=msil
Application Identity : BackupDB.exe, Version=1.0.0.3, Culture=neutral, PublicKeyToken=28500bade1fb75cf, processorArchitecture=msil, type=win32
APPLICATION SUMMARY
* Installable application.
ERROR SUMMARY
Below is a summary of the errors, details of these errors are listed later in the log.
* An exception occurred while determining trust. Following failure messages were detected:
+ Value does not fall within the expected range.
* Activation of G:\OFFICE\R&D\Silverlight\Examples\WPF\BackupDB\Published\BackupDB.application resulted in exception. Following failure messages were detected:
+ Value does not fall within the expected range.
COMPONENT STORE TRANSACTION FAILURE SUMMARY
No transaction error was detected.
WARNINGS
There were no warnings during this operation.
COMPONENT STORE TRANSACTION DETAILS
No transaction information is available.
------------------------------------------------------------
Solution:

This is Known Issue Currently and Simple workaround is don't use "&" in File path of Clickonce publish location.

Thursday, August 5, 2010

Silverlight Isolated Storage File/Directory Location

I was just building something in Silverlight that makes use of the Isolated Storage, and I uncovered a bug in Silverlight 2 Beta 2 that cause's it to crash and you are unable to write to the Isolated Storage. So, I found the location on disk where Silverlight stores the files for Isolated Storage.



Here's the file location under Windows Vista / Windows 7 where Silverlight stores the files for Isolated Storage:


C:\Users\{username}\AppData\LocalLow\Microsoft\Silverlight\is


Just replace the text "{username}" with the Windows Username of the user the data is stored for.


The bug that I ran into was also causing the Silverlight Configuration dialog (which pops up when you right click on Silverlight content within the browser) to crash when I selected the Application Storage tab. So, this bug prevented me from clearing the cache, and I wasn't able to get my app working again. I just deleted all the files within the above directory and it fixed my problem.


Monday, April 5, 2010

ASP.NET Page Life Cycle

Introduction


This article describes the life cycle of the page from the moment the URL is hit from the web browser till the HTML code is generated and sent to the web browser. Let us start by looking at some keywords that are involved in the life cycle of the page.

Background

IIS: IIS (Internet Information Server) is a complete Web server that makes it possible to quickly and easily deploy powerful Web sites and applications. It is the default web server used with .NET. When a Web server (for ASP.NET applications, typically IIS) receives a request, it examines the file-name extension of the requested file, determines which ISAPI extension should handle the request, and then passes the request to the appropriate ISAPI extension. (By default, ASP.NET handles file name extensions that have been mapped to it, such as .aspx, .ascx, .ashx, and .asmx.)

Note:

If a file name extension has not been mapped to ASP.NET, ASP.NET will not receive the request. It will be handled by the IIS. The requested page/image/file is returned without any processing.

If you create a custom handler to service a particular file name extension, you must map the extension to ASP.NET in IIS and also register the handler in your application's Web.config file.

ASPNET_ISAPI.DLL: This DLL is the ISAPI extension provided with ASP.NET to process the web page requests. IIS loads this DLL and sends the page request to this DLL. This DLL loads the HTTPRuntime for further processing.

ASPNET_WP.EXE: Each worker process (ASPNET_WP.EXE) contains an Application Pool. Each Application Pool can contain any number of Applications. Application Pool is also called as AppDomain. When a web page is requested, IIS looks for the application pool under which the current application is running and forwards the request to the respective worker process.


HTTP Pipeline: HTTP Pipeline is the general-purpose framework for server-side HTTP programming that serves as the foundation for ASP.NET pages as well as Web Services. All the stages involved from creating HTTP Runtime to HTTP Handler is called HTTP Pipeline.


HTTP Runtime: Each AppDomain has its own instance of the HttpRuntime class—the entry point in the pipeline. The HttpRuntime object initializes a number of internal objects that will help carry the request out. The HttpRuntime creates the context for the request and fills it up with any HTTP information specific to the request. The context is represented by an instance of the HttpContext class. Another helper object that gets created at such an early stage of the HTTP runtime setup is the text writer—to contain the response text for the browser. The text writer is an instance of the HttpWriter class and is the object that actually buffers any text programmatically sent out by the code in the page. Once the HTTP runtime is initialized, it finds an application object to fulfill the request. The HttpRuntime object examines the request and figures out which application it was sent to (from the pipeline's perspective, a virtual directory is an application).


HTTP Context: This is created by HTTP Runtime. The HttpContext class contains objects that are specific to the current page request, such as the HttpRequest and HttpResponse objects. You can use this class to share information between pages. It can be accessed with Page.Context property in the code.


HTTP Request: Provides access to the current page request, including the request headers, cookies, client certificate, query string, and so on. You can use this class to read what the browser has sent. It can be accessed with Page.Request property in the code.


HTTP Response: Provides access to the output stream for the current page. You can use this class to inject text into the page, to write cookies, and more. It can be accessed with Page.Response property in the code.



HTTP Application: An application object is an instance of the HttpApplication class—the class behind the global.asax file. HTTPRuntime uses HttpApplicationFactory to create the HTTPApplication object. The main task accomplished by the HTTP application manager is finding out the class that will actually handle the request. When the request is for an .aspx resource, the handler is a page handler—namely, an instance of a class that inherits from Page. The association between types of resources and types of handlers is stored in the configuration file of the application. More exactly, the default set of mappings is defined in the section of the machine.config file. However, the application can customize the list of its own HTTP handlers in the local web.config file. The line below illustrates the code that defines the HTTP handler for .aspx resources.

HttpApplicationFactory: Its main task consists of using the URL information to find a match between the virtual directory of the URL and a pooled HttpApplication object.

HTTP Module: An HTTP module is an assembly that is called on every request that is made to your application. HTTP modules are called as part of the ASP.NET request pipeline and have access to life-cycle events throughout the request. HTTP modules let you examine incoming and outgoing requests and take action based on the request. They also let you examine the outgoing response and modify it. ASP.NET uses modules to implement various application features, which include forms authentication, caching, session state, and client script services. In each case, when those services are enabled, the module is called as part of a request and performs tasks that are outside the scope of any single page request. Modules can consume application events and can raise events that can be handled in the Global.asax file.

HTTP Handler: An ASP.NET HTTP handler is the process that runs in response to a request that is made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request a .aspx file, the request is processed by the page handler. We can write our own handler and handler factory if we want to handle the page request in a different manner.

Note: HTTP modules differ from HTTP handlers. An HTTP handler returns a response to a request that is identified by a file name extension or family of file name extensions. In contrast, an HTTP module is invoked for all requests and responses. It subscribes to event notifications in the request pipeline and lets you run code in registered event handlers. The tasks that a module is used for are general to an application and to all requests for resources in the application.

Life Cycle of Page

Web page request comes from browser.

IIS maps the ASP.NET file extensions to ASPNET_ISAPI.DLL, an ISAPI extension provided with ASP.NET.

ASPNET_ISAPI.DLL forwards the request to the ASP.NET worker process (ASPNET_WP.EXE or W3P.EXE).

ISAPI loads HTTPRuntime and passes the request to it. Thus, HTTP Pipelining has begun.

HTTPRuntime uses HttpApplicationFactory to either create or reuse the HTTPApplication object.

HTTPRuntime creates HTTPContext for the current request. HTTPContext internally maintains HTTPRequest and HTTPResponse.

HTTPRuntime also maps the HTTPContext to the HTTPApplication which handles the application level events.

HTTPApplication runs the HTTPModules for the page requests.

HTTPApplication creates HTTPHandler for the page request. This is the last stage of HTTPipelining.

HTTPHandlers are responsible to process request and generate corresponding response messages.

Once the request leaves the HTTPPipeline, page level events begin.

Page Events are as follows: PreInit, Init, InitComplete, PreLoad, Load, Control events (Postback events), Load Complete, PreRender, SaveStateComplete, Render and Unload.

HTTPHandler generates the response with the above events and sends back to the IIS which in turn sends the response to the client browser.



Events in the Life Cycle of Page


PreInit: All the Pre and Post events are introduced as part of .NET Framework 2.0. As the name suggests, this event is fired before the Init method is fired. Most common functionalities implemented in this method include:

Check the IsPostBack property

Set the master page dynamically

Set the theme property of the page dynamically

Read or Set the profile property values

Re-create the dynamic controls

Init: This event is raised after all controls in the page are initialized and any skin settings have been applied. This event is used to read or initialize control properties. It can be used to register events for some controls for which the events are not specified in the aspx page.

Ex: OnClick event of the Button can be registered in the Init rather than specifying in the OnClick property of the Button in the aspx page.

InitComplete: Use this event for processing tasks that require all initialization to be complete.

PreLoad: Use this event if you need to perform processing on your page or control before the Load event. After the Page raises this event, it loads view state for itself and all controls, and then processes any postback data included with the Request instance.

Load: The Page calls the OnLoad event method on the Page, then recursively does the same for each child control, which does the same for each of its child controls until the page and all controls are loaded. Use the OnLoad event method to set properties in controls and establish database connections.

Control events: Use these events to handle specific control events, such as a Button control's Click event or a TextBox control's TextChanged event.

LoadComplete: Use this event for tasks that require that all other controls on the page be loaded.

PreRender: This is the last event raised before the HTML code is generated for the page. The PreRender event also occurs for each control on the page. Use the event to make final changes to the contents of the page or its controls.

SaveStateComplete: Before this event occurs, ViewState has been saved for the page and for all controls. Any changes to the page or controls at this point will be ignored.

Use this event to perform tasks that require view state to be saved, but that do not make any changes to controls.

Render: This is the stage where the HTML code for the page is rendered. The Page object calls the Render method of each control at this stage. All ASP.NET Web server controls have a Render method that writes out the control's markup that is sent to the browser.

UnLoad: This event occurs for each control and then for the page. In controls, use this event to do final cleanup for specific controls, such as closing control-specific database connections.

For the page itself, use this event to do final cleanup work, such as closing open files and database connections, or finishing up logging or other request-specific tasks.

Thursday, February 25, 2010

Solving Reportviewer Rendering issue on iis7

Solving Reportviewer Rendering issue on iis7

Applies to:
Internet Information Services 7.o (IIS7)
Microsoft Report Viewer Redistributable 2005

Symptoms:

Unable to render ReportViewer on ASP.NET Web pages while running on IIS7.

You have no problem viewing your reports when running on debug mode with your Visual Studio 2005.

You are able to view your reports on Report Manager but not able to view them on IIS7.

You encounter JavaScript error when loading your report page with ReportViewer. Image buttons such as calendar appear as red 'X'.

Cause:

When the ReportViewer control is added to Web Form (.aspx), the

Reserved.ReportViewerWebControl.axd httpHandler is added to System.Web section of the Web.Config file. In IIS7, it should be added under System.Webserver section.

IIS7 Handler Mappings does not contain Reserved.ReportViewerWebControl.axd httpHandler, and therefore unable to render the ReportViewer elements needed by the JavaSript.

Resolution:

Open Internet Information Services (IIS) Manager and select your Web application.

Under IIS area, double-click on Handler Mappings icon.

At the Action pane on your right, click on Add Managed Handler.

At the Add Managed Handler dialog, enter the following:

Request path: Reserved.ReportViewerWebControl.axd

Type: Microsoft.Reporting.WebForms.HttpHandler

Name: Reserved-ReportViewerWebControl-axd

Click OK.

Reserved-ReportViewerWebControl-axd handler is now added to your Handler Mappings list. Notice that the following line has also been added to your Web.config file under the system.webserver's handler section:

add name="Reserved-ReportViewerWebControl-axd" path="Reserved.ReportViewerWebControl.axd"
verb="*" type="Microsoft.Reporting.WebForms.HttpHandler" resourceType="Unspecified"

Run your report again.

Thursday, February 4, 2010

ASP.Net Menu

foreach (DataRow drItems in dsRoles.Tables[0].Rows)

{
      MenuItem smsParentItem = new MenuItem((string)drItems["menuName"]);
      if (drItems["parentID"].ToString().Equals("0"))
      {
         SMSMenu.Items.Add(smsParentItem);
         smsParentItem.Value = drItems["menuUID"].ToString();
      }
}


for (int i = 0; i < SMSMenu.Items.Count; i++)
{
     foreach (DataRow drItems in dsRoles.Tables[0].Rows)
    {
        if (SMSMenu.Items[i].Value == drItems["parentID"].ToString())
         {
             MenuItem smsChildItem = new MenuItem((string)drItems["menuName"]);
             SMSMenu.Items[i].ChildItems.Add(smsChildItem);
             smsChildItem.NavigateUrl = drItems["menuURL"].ToString();
             smsChildItem.ImageUrl = ""
        }
    }
}
SMSMenu.Orientation = Orientation.Vertical;
SMSMenu.DataBind();

Wednesday, January 27, 2010

Working with Crossdomain Client Access Policy

Working with Crossdomain Client Access Policy


We have seen that all accesses from Silverlight application out of the domain are forbidden by default. However it is necessary to allow accesses from other domains in some situations.



Actually at the access to a resource from other domain, Silverlight Runtime checks if "clientaccesspolicy.xml" file which should be in a root of the given domain exists. If this file is found, parameters of the access to this domain are set in it.



If the file is not found, attempt of search of "crossdomain.xml" file, which is necessary for Adobe Flash applications work, will be made. If both files are not found, the access to the domain is blocked outside.



To understand how it works, let us make some experiments. For this purpose we need to create some websites that work in different domains. For our experiment, such sites can be defined in a "hosts" file which is located in a "%windir %\System32\drivers\etc" folder. For example, it is possible to define this file as follows.



Listing 4 - The "host" file sample



127.0.0.1 site1.com

127.0.0.1 api.site1.com

127.0.0.1 subdomain.api.site1.com

127.0.0.1 site2.com

127.0.0.1 site3.comFrom this listing we can see that we define some domains which refer to local IP-address. It is now necessary to create in some sites in IIS for each of the domains.



Let us place a file "data.xml" on a web-site "api.site1.com" and we will create small Silverlight application which will access this file. There will be some lines of a code which load a XML-file in an asynchronous mode to this application.



Listing 5 - Sample of Silverlight application



private void GetDataButton_Click(object sender, RoutedEventArgs e)

{

var client = new WebClient();

client.DownloadStringCompleted += client_DownloadStringCompleted;

client.DownloadStringAsync(new Uri(ServerURI.Text));



Data.Text = "Loading..";

}



void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

if (e.Error == null)

{

Data.Text = e.Result;

}

else

{

Data.Text = "Error: " + e.Error.ToString();

}

}Let us place this application in each domain and try to access to service. Now applications in all domains, except api.site1.com, will throw a SecurityException.



To resolve cross-domain access to "api.site1.com" the domain we will place "clientaccesspolicy.xml" within a web-site "api.site1.com". Thus this file should have the address "http://api.site1.com/clientaccesspolicy.xml". This file has the following format.



Listing 6 - Sample of "clientaccesspolicy.xml" file



























When we place this file within the specified domain all cross-domain access becomes possible and all applications from various domains can access it. We can be sure that our Silverlight application has been correctly set up if we can access our test application from the different domains that we have previously deployed.



Besides, it is possible to adjust the policy so that access is possible from only some domains. For example, the "clientaccesspolicy.xml" file can look as follows.



Listing 7 - Sample of "clientaccesspolicy.xml" file





























In this case we allow access only from domains site1.com and site2.com.



In other case we can define not only certain domains, but also subdomains.



Listing 8 - Sample of "clientaccesspolicy.xml" file



























In this case access is possible from all subdomains *.site1.com.



Also it is possible to limit which port and protocol will be used. For example, we will allow access only via HTTPS for all sites.



Listing 9 - Sample of "clientaccesspolicy.xml" file



























Besides, it is possible to limit a set of resources which are accessible from outside of current domain. For example, it is possible to specify that only the "data.xml" file can be accessible out of the domain.



Listing 10 - Sample of "clientaccesspolicy.xml" file



























Besides, it is possible to demand HTTP-heading presence in request.



In this case cross-domain access is allowed only in case of this header presence.



Listing 11 - Sample of "clientaccesspolicy.xml" file



























Undoubtedly such permission of access to the domain can have the consequence of reducing security of a resource. It is possible to give access to the inattentive application. That is why all web-services which should be accessible to other domains are frequently taken in a separate domain. For example, our application can work within "site1.com" domain, and web-services within "api.site1.com" domain. Thus we can save us from the attack that uses cookie of the user.

Debugging Web Service Usage in Silverlight 2

Debugging Web Service Usage in Silverlight 2


(Cross-posted from http://eugeneos.blogspot.com/2008/04/debugging-web-service-usage-in.html)



Silverlight 2 Beta1 makes it easy to use Web Services based on either the WCF technology (Windows Communication Foundation), the “.asmx” technology (ASP.NET Web Services), or practically any other SOAP platform.



Unfortunately, when something goes wrong with service consumption, you often run into cryptic and incomprehensible error messages that don’t help you much. We are looking into various ways to make this better by the time we fully ship Silverlight 2, but for now I hope that this post will be useful in helping you debug common problems. Here are the things you can try:



Does your proxy compile?



After you use the “Add Service Reference” dialog to add a reference to a service, try building your project. If you get compilation issues in the generated proxy code, you are probably using a service that uses some feature that is not supported in Beta1. We are trying to fix all or most of these by the time we ship, but for now the easiest thing to do is to find the offending code in the generated proxy and just remove it – naturally this workaround does not work in all cases :) Some common things that will cause non-compilable proxies in Beta1:



- Using custom SOAP headers in your service

- Using custom SOAP faults

- Using “wildcard” schema in your service like xsd:any or xsd:anyattribute



And specifically if your service is a WCF (or in some cases .ASMX) service:



- Using XML types like XmlElement/XElement/XmlNode[]/XmlAttribute/etc. in your service

- Using Datasets in your service

- Using types that implement ISerializable in your service (except for collections)

- Using WCF Transactions features

- Using the Stream type in your service

- Using MessageHeaderAttribute in Message Contracts



Check the Configuration



The next step is to check whether the service is configured correctly. You should have a file called ServiceReferences.ClientConfig generated by Add Service Reference. It actually doesn’t do anything at all in Beta1! This (understandably) confuses a lot of people. Starting with Beta2, we will actually start using this file, but for now any changes that you’ll make in it won’t actually affect anything.



However, the file is still useful for debugging. Look in the file – it should look something like this:



















Notice that it has exactly one endpoint element for the service you just added a reference to, and the binding is basicHttpBinding.



If you don’t see an endpoint element for your service, chances are your service wasn’t actually configured correctly for Silverlight consumption. Silverlight can only talk to simple SOAP services at this point – only SOAP 1.1, without any advanced WS-* protocols like WS-Addressing or WS-Security. If you are using “.ASMX” web services, they should just default to this simple configuration. If you are using WCF services, you need to check the configuration on the service side. Open web.config in your service-side project and find a place that looks like the following (usually towards the end):





...









...









Find the endpoint whose “contract” attribute refers to your service. Make sure that the “binding” attribute is set to “basicHttpBinding”. Unfortunately the default for WCF is “wsHttpBinding”, but it doesn’t work with Silverlight. We are hoping to ship a Visual Studio item template in the future (“Add New Item… Silverlight-enabled WCF Service”) that will have a number of Silverlight-friendly defaults, including the correct binding.



It is ok to have other endpoint elements for other contracts with other bindings - for example, do not change the "mexHttpBinding" in the second endpoint element above.



You should check your service-side configuration even if the client-side ServiceReferences.ClientConfig appears to be correct.



If ServiceReferences.ClientConfig contains more than one endpoint for your service, you may need to use a more complicated constructor to new up your service proxy – the one that takes a Binding and an EndpointAddress. Not to worry – just pass a new BasicHttpBinding() and a new EndpointAddress built from the URL of your service.



By the way, our long-term (post-Beta1) plans for the config file are described here: http://blogs.msdn.com/suwatch/archive/2008/04/07/tutorial-using-silverlight-web-service-client-configuration.aspx



Check if the Service is Running



Before looking for problems on the Silverlight side, it is useful to first check whether the service itself is working. A quick-and-dirty way to check is to just type the service address into a web browser (not the address you typed into the “Add Service Reference” dialog, but the address you can find in ServiceReferences.ClientConfig). In many cases, the “service help page” feature will be turned on and you will see either a page indicating that the service is running, or an error page which you can use as a starting point for debugging.



A more reliable way to test whether the service is working is to use a test tool such as the WCF Test Client (http://msdn2.microsoft.com/en-us/library/bb552364.aspx) to try and talk to the service.



Finally, an almost sure-fire but sometimes lengthy way of finding out whether the problem is with the Silverlight code or with the service code is to try using the service without Silverlight :) Just create a new project of type “Console Application”, do an Add Service Reference to that project just like in Silverlight, and write service consumption code inside Main() – again, just like in Silverlight. Use Console.WriteLine to show the results.



Check for Cross-Domain Issues



Start your Silverlight application. Note the URL that appears in the browser (e.g. http://localhost:1111/something/MyGraphicalApp.aspx) – this is your “Application URL”. (Actually, what matters here is the URL of the XAP file, e.g. http://localhost:1111/somethingelse/MyGraphicalApp.xap, but in most simple cases this URL would be in the same domain as the hosting web page, so I’m ignoring the difference for now). Then, look at the URL in the ServiceReferences.ClientConfig file – e.g. http://localhost:5678/foo/TestService.svc or local.live.com/SearchService/LocalSearch.asmx - this is your “Service URL”.



In Beta1, both the “Application URL” and the “Service URL” must be HTTP URLs (not HTTPS) for service consumption to work. This is the first thing to check.



Also, a common mistake is to run your Silverlight application from a file:// Application URL, resulting in cross-domain issues. Sometimes, you run into this if you just hit F5 to run your Silverlight app – instead, right-click on the .aspx page in your project and choose “View in Browser”.



Now you need to figure out the domains for these URLs. The domain is just the basically everything between http:// and the first slash / after that, including the port number (assumed to be 80 if not present). If the domain of the Application URL is different in any way from the domain of the Service URL in any way (even if it’s just a port number difference, or just one part of the domain name is different), you have a cross-domain situation. For example, if your app is at http://localhost:1111/something/MyGraphicalApp.aspx and it is trying to call into http://localhost:5678/foo/TestService.svc, you have a cross-domain situation because localhost:1111 is different from localhost:5678.



Silverlight documentation tells you that if you are in a cross-domain situation, you need to have a “cross-domain policy file” (clientaccesspolicy.xml or crossdomain.xml) present if you want services to work. There is an easy way to check if you have everything set up correctly: Just open a browser and browse to http://service_domain/clientaccesspolicy.xml and http://service_domain/crossdomain.xml. If at least one of these is present, valid and allows cross-domain access – you’re fine. If not, you need to make sure at least one of these files is present.



A common mistake is to put the cross-domain policy file not directly at the root of the domain – for example, at http://localhost:5678/foo/clientaccesspolicy.xml instead of at http://localhost:5678/clientaccesspolicy.xml. It is easy to run into this situation when working with older (.NET 2.0) projects – see http://timheuer.com/blog/archive/2008/04/09/silverlight-cannot-access-web-service.aspx.



Also, make sure to check the syntax of these files – an error in parsing will be treated essentially the same way as if the file was not there. Also note that clientaccesspolicy.xml and crossdomain.xml have different syntax – make sure you use the appropriate content for the file you choose.



A neat trick for adding cross-domain policy files to WCF services that are not hosted in IIS is described here: http://blogs.msdn.com/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx



Enable Exceptions



Normally, Silverlight does not give you much information in exception messages. This decision was made to make the Silverlight download size smaller (exceptions take up a lot of space, especially once they’re translated into all of the languages Silverlight supports). You can read more about this, and find out how to turn on full exceptions for debugging, here: http://blogs.msdn.com/silverlightws/archive/2008/04/06/getting-full-exceptions-in-silverlight-2-beta-1.aspx



Also, if you are using a WCF service, WCF does not normally return much information about server-side exceptions. This is a security measure: you normally don’t want to expose internal information about your service to the outside world. However, during debugging, you can change this by following the steps here: http://blogs.devdeo.com/carlos.medina/PermaLink,guid,b3bff742-0ec9-4f5c-a178-625220a46652.aspx. Make sure to turn it off once you’re done debugging!



Finally, this seems obvious but a lot of people forget about it for some reason - when you get an exception, don’t just look at the exception itself - look at its innerException, and the innerException inside it, etc. Especially in web service scenarios, the truly useful exceptions are often “wrapped” in several layers.



Unfortunately, even with all of the steps above, you often still won’t see much useful information when a web service call fails. This is due to a pretty fundamental limitation of Silverlight Beta1 (that unfortunately may stay around even after the Beta) – the lack of support for SOAP Faults. So, to truly debug, you need to see what is actually going on – this is what the next section is about.



Getting Down to the Wire



The ultimate way to debug Silverlight service consumption issues is by using an “HTTP spying” tool such as http://www.fiddlertool.com/fiddler/ or http://projects.nikhilk.net/webdevhelper/ that shows you the actual HTTP traffic as it happens. Before using it, make sure to enable server-side exceptions (see above). Start your Silverlight app and your tool side-by-side, and make your app do a web service call. Here are some common patterns you will see:



1.Nothing

- Your HTTP spying tool may be misconfigured (try running another, non-Silverlight app, like a regular web browser, to make sure it works)

- Your app may be broken – put a breakpoint where you invoke the service, make sure it’s hit

- You may have a configuration issue – see Configuration section above

- You may be trying to host your application from a file:// or https:// URL, or trying to call an https:// service



2. Just a service request

- Congratulations – you’ve avoided a cross-domain situation if you see the actual request to the service on the wire.

- Is the address what you expected it to be?

- Look at what’s coming back. Is it timing out or are you getting a 404? Your service or even WCF itself may not be set up correctly.

- Are you getting a SOAP fault back? If so, read carefully what’s in the fault – it will usually have enough information to debug the issue.

- In general, look very carefully at both the request and the reply (including the body and HTTP headers)

- Did you remove anything to get the proxy to compile? The service may actually require some items that you removed (e.g. may require certain SOAP headers)



3. A request to clientaccesspolicy.xml (and possibly crossdomain.xml afterwards), followed by a request to the service

- Congratulations – you have a cross-domain situation but you have successfully set up your cross-domain policy files

- This is now equivalent to situation #2 above



4. Just a request to clientaccesspolicy.xml and nothing else

- Most likely a malformed clientaccesspolicy.xml, or one that contains a policy that forbids cross-domain access



5. A request to clientaccesspolicy.xml, then crossdomain.xml, then nothing else

- Basically, something went wrong with cross-domain policy files.

- Are you getting 404s back? Check if you’re hosting the files correctly and at the correct locations

- Are you getting the actual files back? They may be malformed or may forbid cross-domain access