WCF Access is Denied when opening named pipe channel from IIS application - wcf

We have some legacy web application code which we are updating and porting into a .NET 4.0 runtime.
The code is in a class library and connects to a named pipe endpoint using WCF.
When I initiate the connection from a console application, everything works fine.
When I initiate the connection from a web application, I receive an exception:
Access is denied
Server stack trace:
at System.ServiceModel.Channels.AppContainerInfo.GetCurrentProcessToken()
at System.ServiceModel.Channels.AppContainerInfo.RunningInAppContainer()
at System.ServiceModel.Channels.AppContainerInfo.get_IsRunningInAppContainer()
at System.ServiceModel.Channels.PipeSharedMemory.BuildPipeName(String pipeGuid)
at System.ServiceModel.Channels.PipeSharedMemory.get_PipeName()
at System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri uri, IPipeTransportFact… Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
The error originates at a boundary between the managed code and unmanaged code where there is a call into advapi32.dll:
[SecurityCritical]
private static SafeCloseHandle GetCurrentProcessToken()
{
SafeCloseHandle TokenHandle = (SafeCloseHandle) null;
if (!UnsafeNativeMethods.OpenProcessToken(UnsafeNativeMethods.GetCurrentProcess(), TokenAccessLevels.Query, out TokenHandle))
throw System.ServiceModel.FxTrace.Exception.AsError((Exception) new Win32Exception(Marshal.GetLastWin32Error()));
return TokenHandle;
}
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessLevels DesiredAccess, out SafeCloseHandle TokenHandle);
Various topics on the web suggest removing the element or setting impersonate="false":
<system.web>
<identity impersonate="true"/>
</system.web>
And indeed, this works to fix my issue. However, I'm not certain what side effects this may have on the application (SharePoint 2016) so I'm reluctant to simply remove this attribute.
The SecurityCritical attribute gave me some hints in that perhaps this is related to the change in the CAS model between .NET 2.0 and .NET 4.0. The code is installed into the GAC so it should be running under full trust already but I gave it a shot anyways.
I have also tried adding [SecuritySafeCritical] to the method and the class which invokes the IChannel.Open() to no avail.
I also tried adding [assembly: SecurityRules(SecurityRuleSet.Level1)] on the assembly as this should lock into the .NET Framework 2.0 security rules.
I'm looking for any additional insight and other methods to try to resolve this issue.
There is some similarity to this other Stack post: How to call net.pipe (named pipe) WCF services while impersonating in a Windows Service except that there is no explicit impersonation occurring so I'm not certain that the fix would apply.
An additional note is that when I try to call System.Diagnostics.Process.GetCurrentProcess(), the same error is thrown. The error also originates when trying to get a handle on the current executing process.

I've concluded that this issues is related to the internals of System.ServiceModel in .NET 4.0.
Initially, I thought that this may be related to Server 2016 UAC or .NET 4.0/IIS 10 web application runtime settings (e.g. .NET 2.0 vs .NET 4.0 CAS models). I created a simple web application in .NET 3.5 and tried to call Process.GetCurrentProcess().Handle. I ran this in the new server and it failed with the same "Access is denied" error.
I took this into the old server (Windows Server 2008 R2, .NET 3.5) and ran it there expecting this to work and lo-and-behold, it also fails. So I browsed the source for System.ServiceModel in 3.5 and found that there is no AppContainerInfo and thus it is likely that the 3.5 code does not make the same Win32 API level calls at all.
My conclusion is that we did not encounter this error before because the old 3.0 libraries did not need to invoke APIs from advapi32.dll or had some other mechanism to create the pipe name.
Indeed, here is the first few lines of the implementation from PipeConnectionInitiator.GetPipeName in 3.0":
internal static string GetPipeName(Uri uri)
{
string[] strArray = new string[3]
{
"+",
uri.Host,
"*"
};
bool[] flagArray = new bool[2]{ true, false };
for (int index1 = 0; index1 < strArray.Length; ++index1)
{
for (int index2 = 0; index2 < flagArray.Length; ++index2)
{
And here is the first few lines in 4.0:
internal static string GetPipeName(Uri uri, IPipeTransportFactorySettings transportFactorySettings)
{
AppContainerInfo appContainerInfo = PipeConnectionInitiator.GetAppContainerInfo(transportFactorySettings);
string[] strArray = new string[3]
{
"+",
uri.Host,
"*"
};
bool[] flagArray = new bool[2]{ true, false };
string str1 = string.Empty;
string str2 = (string) null;
for (int index1 = 0; index1 < strArray.Length; ++index1)
{
for (int index2 = 0; index2 < flagArray.Length; ++index2)
{
if (appContainerInfo == null || !flagArray[index2])
So the 4.0 implementation requires access to execute OpenProcessToken.
One option, if the code is sufficiently isolated, is to use an assembly binding redirect:
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="System.ServiceProcess" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="4.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
And simply force the runtime to bind to the old versions.
Unfortunately, the application has some dependencies on System.ServiceModel 4.0 so it's not so simple for me to switch.

Related

Facing issue while create the events using MS graph API

I have tried this code to generate the token:
public async Task Authenticate() {
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new StringContent(_clientId), "client_id");
content.Add(new StringContent(_clientSecret), "client_secret");
content.Add(new StringContent("client_credentials"), "grant_type");
content.Add(new StringContent(".default"), "scope");
try {
var task = _client.PostAsync(new Uri(string.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", _tenantId)), content);
var res = task.GetAwaiter().GetResult();
if (res.StatusCode == System.Net.HttpStatusCode.OK) {
JsonDocument resJSON = await JsonDocument.ParseAsync(await res.Content.ReadAsStreamAsync());
_accessToken = resJSON.RootElement.GetProperty("access_token").GetString();
lock(this) {
_expiresAt = DateTime.UtcNow.AddSeconds(resJSON.RootElement.GetProperty("expires_in").GetInt16());
}
} else
throw new Exception(res.ReasonPhrase);
} catch (WebException ex) {
// handle web exception
}
}
But I got the error like
error_description=AADSTS1002016: You are using TLS version 1.0, 1.1 and/or 3DES cipher which are deprecated to improve the security posture of Azure AD. Your TenantID is: 334xxxx. Please refer to https://go.microsoft.com/fwlink/?linkid=2161187 and conduct needed actions to remediate the issue. For further questions, please contact your administrator.
Trace ID: c8a502xxxx
Correlation ID: 325a1dxxxxx
Timestamp: 2022-08-04 13:35:23Z
But the same code works in console application.While using this code inside the dll it throws the exception.All the versions are same - .net framework,System.text.json,system.memory etc.
Please help me to sort out this.
According to this page the default TLS version that is used, depends on the targeted .net version and the used operating system.
Targeting .net framework 4.8 should default to TLS1.2 on Windows 10/11
Any change that you are using an older version of either? Or that you are setting the tls version explicitly somewhere in your application?
Also using lock inside an asynchronous method is bad practice and might deadlock your code.
When I use .NET Framework 4.6.1, I encounter the same problem. After I switched the version to 4.7.2, the problem was not solved until I explicitly specified the version in Web.config.
<httpRuntime targetFramework="4.7.2" />

The 'DbProviderFactories' section can only appear once per config file

We are receiving this error when calling a WCF .net 4.0 service using entity framework.
The 'DbProviderFactories' section can only appear once per config file
It is the first app on the server using EF and other .net 4.0 WCF services are not receiving this error.
Is there any way to correct this error with out editing the machine config file on the server?
The installation for IBM DB2 .NET provider, causes an empty DbProviderFactories, see below. Just delete the second empty entry DbProviderFactories
<system.data>
<DbProviderFactories>
<add name="IBM DB2 for i .NET Provider" invariant="IBM.Data.DB2.iSeries" description=".NET Framework Data Provider for IBM i" type="IBM.Data.DB2.iSeries.iDB2Factory, IBM.Data.DB2.iSeries, Version=12.0.0.0, Culture=neutral, PublicKeyToken=9cdb2ebfb1f93a26" />
</DbProviderFactories>
<DbProviderFactories />
</system.data>
Maybe you could create web.config entries which override any machine-wide settings you want changed.
Described here:
Override machine.config by web.config
Putting the <clear /> instruction inside of the DbProviderFactories tags in the web config to clear out and then override the duplicate entries made in the machine config. Thus doing a hack-work around of the error in the machine.config.
You have to update Machine.config file located in the below paths.
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Machine.Config
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Machine.Config
For 64-bit machines, Machine.config will be located in ...\Framework64\...
The block to pay attention to is this:
<system.data>
<DbProviderFactories>
<add name="IBM DB2 for i5/OS .NET Provider" invariant="IBM.Data.DB2.iSeries" description=".NET Framework Data Provider for i5/OS" type="IBM.Data.DB2.iSeries.iDB2Factory, IBM.Data.DB2.iSeries, Version=12.0.0.0, Culture=neutral, PublicKeyToken=9cdb2ebfb1f93a26"/>
<add name="Microsoft SQL Server Compact Data Provider" invariant="System.Data.SqlServerCe.3.5" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
</DbProviderFactories>
<!-- This is the line to remove - empty element --><DbProviderFactories/>
</system.data>
As #yonsk already mentioned why this problem occurs (duplicate entry of ), you can create a console application which can fix the machine.config file and then, invoke that console application from your Application's Installer or from your Application whenever you get the Exception. The following code can be used for the console application that will fix the machine.config file.
class Program
{
static void Main()
{
string machineConfigFilePath = RuntimeEnvironment.SystemConfigurationFile;
XDocument xdoc = XDocument.Load(machineConfigFilePath);
XElement[] elements = xdoc.XPathSelectElements("//configuration/system.data/DbProviderFactories").ToArray();
if (elements.Any())
{
foreach (XElement anElement in elements)
{
if (!anElement.HasElements)
anElement.Remove();
}
}
xdoc.Save(machineConfigFilePath);
}
}
If you want to call the console application, from your Application, you would need to invoke that as Administrator. So, the following snippet may help to invoke that console application as Administrator (The user will be prompted with a dialog to accept..)
try
{
Process process = Process.Start(new ProcessStartInfo
{
Verb = "runas",
FileName = "/Path/to/the/console/application",
UseShellExecute = true,
CreateNoWindow = true,
});
process.WaitForExit();
int exitCode = process.ExitCode;
}
catch (Exception ex)
{
}

Trying to follow WCF delegation example on MSDN but keep getting "impersonation level" exception

Near the bottom of this article (MSDN) in a section entitled "The following code example demonstrates how to use delegation." where MSDN shows an example of how to perform delegation. I have tried to take this example and apply it to my code. In my situation, I have a client app (WCFTestClient), a middle service and a back end service. The goal is is to have the client execute a WCF exposed method on the middle service which in turn calls another method on the back end service. I'm trying to get the identity of the execution on both middle service and back end service to be that of the user executing the client:
Client ----> Middle Service ----> Back End Service.
Here is the exception that occurs on the "channel.PreparePolicy" invocation:
Could not load file or assembly 'System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. Either a required impersonation level was not provided, or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542)
Here is my code, taken most directly from the example. I did add one line that differs from the MSDN example in my attempt to debug channelFactory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;
but to no effect.
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public void PreparePolicy(string requestGuid, string policyName, ulong version)
{
WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a Windows identity.");
}
using (callerWindowsIdentity.Impersonate())
{
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
Uri uri = new Uri(String.Format("net.tcp://{0}:{1}/App", "10.192.12.159", 8080));
EndpointAddress backendServiceAddress = new EndpointAddress(uri);
ChannelFactory<Service> channelFactory = new ChannelFactory<Service>(binding, backendServiceAddress);
channelFactory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;
Service channel = channelFactory.CreateChannel();
channel.PreparePolicy("alkdjf", policyName, version);
}
}
I was using the WCFTestClient as my client in this scenario. Turns out its not enabled to allow delegation. I wrote my own client and enabled it for delegation and everything worked fine.

SQLite NHibernate configuration with .Net 4.0 and vs 2010

I am updating this post with what I think I now know about getting this configuration; HOWEVER, there is more to know as I am still having a problem is one crucial area.
I use SQLite for unit testing, which now works fine, using the configuration steps below. I also use it when I want a test run of the UI with more data than in-memory test data but without the overhead of SQLServer - this configuration fails with the following:
{"Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4."}
Here is updated info on configs that DO work:
1) Which SQLite dll?? There are some bad links out there that look helpful but that have build errors in them. The only good download as of this date is here at Source Forge. v1.066 which was released today, 4-18-2010.
2) Must you use the GAC? No, as answered by Mauricio.
3) x64 builds - as answered by Mauricio.
4) NHib driver - SQLite20Driver, as answered by Mauricio
5) FNH as a potential conflict - no, as answered by Mauricio
Cheers,
Berryl
== ADD'L DEBUG INFO ===
When the exception is hit and I call up the SQLite20Drive assembly, I get the following which suggests to me that the driver should be available. I am wondering though, as the configuration code is in a different assembly.
-- assembly when error ----
?typeof(SQLite20Driver).Assembly
{NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
[System.Reflection.RuntimeAssembly]: {NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
CodeBase: "file:///C:/Users/Lord & Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.WpfPresentation/bin/Debug/NHibernate.DLL"
EntryPoint: null
EscapedCodeBase: "file:///C:/Users/Lord%20%26%20Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.WpfPresentation/bin/Debug/NHibernate.DLL"
Evidence: {System.Security.Policy.Evidence}
FullName: "NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4"
GlobalAssemblyCache: false
HostContext: 0
ImageRuntimeVersion: "v2.0.50727"
IsDynamic: false
IsFullyTrusted: true
Location: "C:\\Users\\Lord & Master\\Documents\\Projects\\Smack\\trunk\\src\\ConstructionAdmin.WpfPresentation\\bin\\Debug\\NHibernate.dll"
ManifestModule: {NHibernate.dll}
PermissionSet: {<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
}
ReflectionOnly: false
SecurityRuleSet: Level1
--- assembly when unit testing (NO ERROR)
{NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
[System.Reflection.RuntimeAssembly]: {NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}
CodeBase: "file:///C:/Users/Lord & Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.Tests/bin/Debug/NHibernate.DLL"
EntryPoint: null
EscapedCodeBase: "file:///C:/Users/Lord%20%26%20Master/Documents/Projects/Smack/trunk/src/ConstructionAdmin.Tests/bin/Debug/NHibernate.DLL"
Evidence: {System.Security.Policy.Evidence}
FullName: "NHibernate, Version=2.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4"
GlobalAssemblyCache: false
HostContext: 0
ImageRuntimeVersion: "v2.0.50727"
IsDynamic: false
IsFullyTrusted: true
Location: "C:\\Users\\Lord & Master\\Documents\\Projects\\Smack\\trunk\\src\\ConstructionAdmin.Tests\\bin\\Debug\\NHibernate.dll"
ManifestModule: {NHibernate.dll}
PermissionSet: {<PermissionSet class="System.Security.PermissionSet"
version="1"
Unrestricted="true"/>
}
ReflectionOnly: false
SecurityRuleSet: Level1
Here is the bootstrapper for this a SQLite session:
/// <summary>SQLite-NHibernate bootstrapper for general use.</summary>
public class SQLiteBoot : IDisposable
{
public readonly ISessionFactory SessionFactory;
private readonly ISession _session;
private static Configuration _config;
private static string _persistenceModelGeneratorName;
public SQLiteBoot(IAutoPersistenceModelGenerator persistenceModelGenerator) {
if (_isSessionFactoryBuildRequired(persistenceModelGenerator)) {
_config = new Configuration()
.SetProperty(ENV.ReleaseConnections, "on_close")
.SetProperty(ENV.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
.SetProperty(ENV.ConnectionString, "data source=:memory:")
.SetProperty(ENV.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName)
.SetProperty(ENV.CurrentSessionContextClass, typeof (ThreadStaticSessionContext).AssemblyQualifiedName);
_persistenceModelGeneratorName = persistenceModelGenerator.Name;
var persistenceModel = persistenceModelGenerator.Generate();
var fluentCfg = Fluently.Configure(_config).Mappings(m => m.AutoMappings.Add(persistenceModel));
SessionFactory = fluentCfg.BuildSessionFactory();
Check.Require(SessionFactory.GetAllClassMetadata().Count > 0, "No mapped classes - check your AutoPersistenceModel!");
}
_session = SessionFactory.OpenSession();
CurrentSessionContext.Bind(_session);
new SchemaExport(_config).Execute(true, true, false, _session.Connection, Console.Out);
}
private bool _isSessionFactoryBuildRequired(IAutoPersistenceModelGenerator persistenceModelGenerator)
{
return
_config == null
|| SessionFactory == null
|| !persistenceModelGenerator.Name.Equals(_persistenceModelGeneratorName);
}
public void Dispose()
{
_session.Dispose();
}
}
}
Sure. You can also use previous versions if you configure mixed mode loading.
No need to be in the GAC. You can use gacutil to remove the assemblies from the GAC.
Use the x64 DLL to target Windows x64 and x86 for Windows x86
Please post the full exception stack trace. Also if you're using a 3.5 assembly use mixed mode loading.
FNH has no reference to SQLite.
I want this to stand out so it will help someone else; the full reason this happens is explained here; so adjust your congig to use BOTH the redirect there in combo with the mixed loading mode referenced here by Mauricio.
I had the same problem, and found little or no help on all the forum and blog posts.
Note that this problem is specific to a case respecting all of the following criteria:
- using SQLite
- with System.Data.SqlLite
- on an x64 machine
- and NHibernate (2.1.2.4 in my case)
That chunk of config in my web.config (or app.config for my unit tests) got it to work. I had to qualify the assembly to be sure he loads correctly.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly
partialName="System.Data.SQLite"
fullName="System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" />
</assemblyBinding>
</runtime>
</configuration>
Somewhere in it's inner plumbing, during the mapping using scanned assemblies, NHibernate creates an Assembly object using it's paritla name, as a string, "System.Data.SQLite". Somehow, the x86 version of the assembly got loaded.
The above configuration made sure that using the partial name to load an assembly would provide the x64 version.
EDIT: I use version 1.0.66.0 and took the DLL under the bin\x64 folder in the file SQLite-1.0.66.0-binaries.zip available on sourceforge here.

Can Silverlight WCF client read exceptions from an ASMX web service?

I've seen no need to upgrade my services to WCF, but I have been using WCF clients for some time to access ASMX services from .NET 3.5 ASP.NET. I figured eventually I'd hit a wall in this mismatch and I just did - but with Silverlight.
When using Silverlight to access ASMX web services I get an error like this in a popup :
An exception occurred during the
operation, making the result invalid.
Check InnerException for exception
details.
If I'm debugging I get this error :
The remote server returned an error: NotFound.
If I look in Fiddler the exception/fault is there just fine :
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body><soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Server was unable to process request. ---> ID does not match</faultstring>
<detail /></soap:Fault></soap:Body></soap:Envelope>
How do I actually get to this exception in the Silverlight client.
I need the error to be accessible at runtime with no fiddler and no debugger.
There is a property includeexceptiondetailinfaults that belongs in <behaviors> in the web.config - but this is for server side only as far as I can tell.
Am I correct in assuming that I will need to convert my asmx to svc to be able to get actual exception details in the silverlight client?
If you're happy to wrap the asmx SOAP request in your own IHttpHandler, you can force-feed a Response.StatusCode = 200 after the System.Web.Script.Services.ScriptHandlerFactory does it's work. Here's a sample;
static void ProcessService(HttpContext context)
{
//
// I'm also using this to fake/hide the path of my asmx so that
// domain.com/xml becomes the service end-point..
//
string asmx = "/Services/Some.Service.asmx";
string method = context.Request.Path.Substring("/xml".Length);
//
// ScriptHandlerFactory and friends are sealed so have to use reflection..
//
IHttpHandlerFactory fact = (IHttpHandlerFactory)Activator.CreateInstance(Type.GetType("System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions"));
Type vpt = Type.GetType("System.Web.VirtualPath, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
System.Reflection.MethodInfo mi = vpt.GetMethod("Create", new Type[] { typeof(string) });
object vp = mi.Invoke(null, new object[] { context.Request.Path });
System.Reflection.FieldInfo fi = context.Request.GetType().GetField("_pathInfo", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
System.Reflection.FieldInfo _virtualPath = vpt.GetField("_virtualPath", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
_virtualPath.SetValue(vp, method);
fi.SetValue(context.Request, vp);
IHttpHandler handler = fact.GetHandler(context, context.Request.RequestType, asmx, context.Server.MapPath(asmx));
try
{
// This will trap your asmx Exception and output 500 status and soap fault
handler.ProcessRequest(context);
// force 200 status for Silverlight to receive fault code
context.Response.StatusCode = 200;
context.ApplicationInstance.CompleteRequest();
}
finally
{
fact.ReleaseHandler(handler);
}
}
No client ever gets exceptions from web services. Web services don't send exceptions - they send faults.
The details of the fault are contained in the <detail/> element of the fault message. some platforms, including WCF, parse this information in order to translate from the fault to a platform-specific exception.
Since there is no information in the <detail/> element, no translation is likely to occur.