Serialization Exception in compiled dll - c#

I've inherited an ecommerce ASP.NET (c# code behind) web application. We've recently moved servers and it's proving somewhat troublesome. I have very little experience with IIS server configuration and dealing with large projects like this. Most of the problems have now been fixed, but we're experiencing problems with a crucial part, as a customer attempts to make a payment.
As the customer confirms payment, the application encounters the following error:
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET
will serialize the session state objects, and as a result non-serializable objects or
MarshalByRef objects are not permitted. The same restriction applies if similar
serialization is done by the custom session state store in 'Custom' mode.
Stack Trace:
[SerializationException: Type 'PayerAuthentication.PayerAuthenticationServicePost' in Assembly 'PayerAuthentication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +7733643
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +258
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +111
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +161
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) +51
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +410
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +134
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1577
Google search results indicate I should add [Serializable] to the class declaration affected, but this is in a compiled dll to which I do not have the csproj.
The code was working fine on the previous server and I do not believe any changes have been made to the code, only to web.config - what can I do?
The sessionstate section of web.config reads <sessionState mode="StateServer" />
UPDATE1: Using Reflector, I exported the class above, made it serializable, recompiled and replaced the dll. The order process went one step further, wherepon I encountered the same error for another dll-compiled class. Once again I was able to use Reflector to see the code, and then export it, edit and recompile.
Now I have the same error occurring in:
SerializationException: Type 'System.Runtime.Remoting.Messaging.AsyncResult' in Assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.]
I'm not sure I can do anything about this, as this must be part of the .net system files! Any further ideas?
UPDATE2: Ha, well I've subsequently discovered it's processing the payments correctly, but then throwing the above Unable to serialize the session state error on System.Runtime.Remoting.Messaging.AsyncResult before the user gets receipt of the transaction. Not good. Unsure how to move forward now...
UPDATE3: I tried creating a copy of the System.Runtime.Remoting.Messaging.AsyncResult class, and making it serializable but this is then leading to inconsistent accessibility problems.
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Security.Permissions;
using System.Runtime.Remoting.Messaging;
[Serializable, ComVisible(true)]
public class myAsyncResult : IAsyncResult, IMessageSink
{
// Fields
private AsyncCallback _acbd;
private Delegate _asyncDelegate;
private object _asyncState;
private ManualResetEvent _AsyncWaitHandle;
private bool _endInvokeCalled;
private bool _isCompleted;
private IMessageCtrl _mc;
private IMessage _replyMsg;
// Methods
internal myAsyncResult(Message m);
//[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink);
private void FaultInWaitHandle();
public virtual IMessage GetReplyMessage();
public virtual void SetMessageCtrl(IMessageCtrl mc);
//[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
public virtual IMessage SyncProcessMessage(IMessage msg);
// Properties
public virtual object AsyncDelegate { get; }
public virtual object AsyncState { get; }
public virtual WaitHandle AsyncWaitHandle { get; }
public virtual bool CompletedSynchronously { get; }
public bool EndInvokeCalled { get; set; }
public virtual bool IsCompleted { get; }
public IMessageSink NextSink { [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] get; }
}
Specifically, that error CS0122: 'System.Runtime.Remoting.Messaging.Message' is inaccessible due to its protection level. I can see this is because Message is an internal class. But surely I can't change the accessibility level of it as it is part of the System.Runtime namespace. And making a copy and renaming it is going to cuase the same problem again, surely?
Can anyone help me now?
FINAL UPDATE
Looks like, after all this, that it was the SSL certificate (see my answer below)

If you really wanted the code, you could try using Reflector's Class View. At the very least, it could help you verify whether or not [Serializable] was part of the problem class definition or not.

You'll need to find out if the new server is a later version than the old, or an older one. If it's an older version, then upgrade it to the newer version, and things should work.
If it's newer, then is it your code (that you have source to) that puts these non-serializable objects into session state? If so, then you can maybe create your own class to mirror the properties of the old class. Make your class serializable and put an instance of your class into session state. Make an instance of the old class when you take yours out of session state.

I now believe that this problem arose when we installed a new SSL certificate.
The new certificate had Postcode extensions which our payment merchant HSBC doesn't accept over it's CPI payment gateway.
Getting the correct SSL certificate installed seems to have finally solved this problem.

If the code was previously using just the in-memory state provider, then this could be... tricky. It is a pain point that the serialization process (via BinaryFormatter, which the database state provider uses) requires the [Serializable] attribute when the default provider doesn't.
How much of the code can you edit? Any of it? For example, can you change the code that puts things into/out-of state? You could perhaps use a separate (serializable) DTO with the necessary properties and translate between them with your own code.
Other options:
go back to the in-memory provider (and wave goodbye to a cluster)
write a provider that doesn't use BinaryFormatter
I have some thoughts on the latter, but I doubt it would be trivial

If the question is just how to make the application run without this error, the fast solution is to set the mode attribute of the sessionState element to "InProc".

Related

How can I fake a DbSet<T> using FakeItEasy when the classes are internal?

I'm using Entity Framework 6 and want to unit test some of my business logic code. Following Microsoft's example on how to do this, they provide the following example using MOQ:
var mockSet = new Mock<DbSet<Blog>>();
var mockContext = new Mock<BloggingContext>();
mockContext.Setup(m => m.Blogs).Returns(mockSet.Object);
var service = new BlogService(mockContext.Object);
I'm using FakeItEasy instead of MOQ, and I'd hoped it would be just as simple, however FakeItEasy complains that it can't create a fake of my DbSet using the following:
var fakeDbSet = A.Fake<DbSet<InstalledProduct>>();
I get an exception as follows:
FakeItEasy.Core.FakeCreationException: Failed to create fake of
type "TN.Prs.Persistence.LicenseContext".
Below is a list of reasons for failure per attempted constructor:
No constructor arguments failed:
No usable default constructor was found on the type TN.Prs.Persistence.LicenseContext.
An exception was caught during this call. Its message was:
Access is denied: 'TN.Prs.Persistence.LicenseContext'.
at
FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithResolvedConstructors(Type
typeOfFake, String reasonForFailureOfUnspecifiedConstructor,
IEnumerable1 resolvedConstructors) at
FakeItEasy.Creation.FakeObjectCreator.TryCreateFakeWithDummyArgumentsForConstructor(Type
typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession
session, String failReasonForDefaultConstructor, Boolean
throwOnFailure) at
FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake,
FakeOptions fakeOptions, IDummyValueCreationSession session, Boolean
throwOnFailure) at
FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type
typeOfFake, FakeOptions options) at
FakeItEasy.Creation.DefaultFakeCreatorFacade.CreateFake[T](Action1
options) at FakeItEasy.A.FakeT at
TN.Prs.RegistrationServices.Specifications.when_activating_a_product_from_a_valid_digitally_signed_activation_key.<.ctor>b__0()
in
My POCO classes are internal rather than public, but I've added the InternalsVisibleTo attributes as appropriate, for DynamicProxyGenAssembly2. When I make the classes public, everything works, but I really don't want to expose these classes publicly. I would appreciate any suggestions.
Here is my context class:
internal class LicenseContext : DbContext
{
public LicenseContext()
{
}
public virtual DbSet<InstalledProduct> ManagedProducts { get; set; }
}
Problem solved!
Before I added the InternalsVisibleTo attributes, FakeItEasy complained and told me to add those attributes and I was delighted to see that it gave me the exact code I needed right in the error message. I even remarked to one of my colleagues, "now THAT is what I call an error message!". The attribute it suggested was:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
Unfortunately that doesn't work and I get an 'Access Denied' error. It might be that the public key isn't correct, but since my assemblies are not strong-named, I simply removed the public key from the attributes and everything works.
Eventually I will have to strong-name my assemblies so I will have to solve this public key problem eventually, but I know what to do so it shouldn't be an obstacle.

ResolutionFailedException with Unity

I'm using Patterns and Practices' Unity to inject dependencies into my objects and have hit a weird (to me, anyway) issue. Here's my class definitions:
public class ImageManager : IImageManager
{
IImageFileManager fileManager;
public ImageManager(IImageFileManager fileMgr)
{
this.fileManager = fileMgr;
}
}
public class ImageFileManager : IImageFileManager
{
public ImageFileManager(string folder)
{
FileFolder = folder;
}
}
And here's the code to register my classes
container.RegisterInstance<MainWindowViewModel>(new MainWindowViewModel())
.RegisterType<IPieceImageManager, PieceImageManager>(
new InjectionConstructor(typeof(string)))
.RegisterType<IImageFileManager, ImageFileManager>()
.RegisterType<IImageManager, ImageManager>(
new InjectionConstructor(typeof(IImageFileManager)));
I originally resolved this in the code behind (I know, it defeats the purpose. Bear with me.) of the XAML file like this
IImageManager imageManager = MvvmViewModelLocator.Container.Resolve<IImageManager>(
new ParameterOverride("folder", "/images"));
And it worked. But I created a view model for my main view and when I copied the same line into it, I get an exception. Here are the two most inner exceptions:
InnerException: Microsoft.Practices.Unity.ResolutionFailedException
HResult=-2146233088
Message=Resolution of the dependency failed, type = "SwapPuzzleApp.Model.IImageManager", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type IImageManager does not have an accessible constructor.
At the time of the exception, the container was:
Resolving SwapPuzzleApp.Model.IImageManager,(none)
Source=Microsoft.Practices.Unity
TypeRequested=IImageManager
StackTrace:
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable`1 resolverOverrides)
at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides)
at Microsoft.Practices.Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, ResolverOverride[] overrides)
at SwapPuzzleApp.ViewModel.MainWindowViewModel..ctor() in c:\Users\Carole\Documents\Visual Studio 2012\Projects\SwapPuzzle\SwapPuzzle\ViewModel\MainWindowViewModel.cs:line 17
at SwapPuzzleApp.ViewModel.MvvmViewModelLocator..cctor() in c:\Users\Carole\Documents\Visual Studio 2012\Projects\SwapPuzzle\SwapPuzzle\ViewModel\MvvmViewModelLocator.cs:line 51
InnerException: System.InvalidOperationException
HResult=-2146233079
Message=The type IImageManager does not have an accessible constructor.
Source=Microsoft.Practices.Unity
StackTrace:
StackTrace:
at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForNullExistingObject(IBuilderContext context)
at lambda_method(Closure , IBuilderContext )
at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context)
at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
InnerException:
I'm not sure what the problem is, as ImageManager clearly has a public constructor. I thought it might be due to an invalid path, but if I concretely instantiate the object, everything works.
// this line has no problems
IImageManager imageManager = new ImageManager(new ImageFileManager("/images"));
I also wondered if I needed to pass in new InjectionConstructor(typeof(string)) when I register IImageManager, but it doesn't seem to help and why would it be needed now and not before? So I'm stumped. This is my first attempt at using Dependency Injection, so it's probably something basic. I'm just not seeing what, though.
Look very closely at the error message. Notice this part:
Message=The type IImageManager does not have an accessible constructor.
Notice the type name is IImageManager, not ImageManager. Somewhere along the line you lost your type mapping.
Your registration of FileImageManager has a problem as well, since you don't specify the folder parameter in the registration, so Unity has no idea what string to pass.
I was using the examples in this article as my guide. Either the examples in there are way too advanced for an introduction, or there's misinformation in that topic.
After consulting other sources (mainly PluarlSight), I came up with a much simpler and more logical solution.
container.RegisterInstance<TimerViewModel>(new TimerViewModel());
container.RegisterType<IPieceImageManager, PieceImageManager>();
container.RegisterType<IImageFileManager, ImageFileManager>
(new InjectionConstructor("/images"));
container.RegisterType<IImageManager, ImageManager>();
I ran into a similar issue with this error tied directly to a Mock (using automoq) that I was doing for an operation. In this case it turned out that because there were a number of member methods that get called with the object being mocked, that I had to define all of those in the automoq chain to get it to resolve properly
I realize this is an example in instance code, but it could occur in Moqs also. So if you read this and are wondering about an example related to Moqs, look into that first.

How do I implement Exception.GetObjectData in .NET 4 in a library assembly that has the AllowPartiallyTrustedCallersAttribute?

I have an assembly marked with the AllowPartiallyTrustedCallersAttribute which contains a custom exception class. I want to make it serializable by overriding GetObjectData.
With .NET 4, GetObjectDatahas become a SecurityCritical method. This means that overrides also need to be SecurityCritical. Since my assembly is marked with the AllowPartiallyTrustedCallersAttribute, all code within is automatically SecurityTransparent unless specified otherwise. Therefore, I apply the SecurityCriticalAttribute to the GetObjectData override:
using System;
using System.Runtime.Serialization;
using System.Security;
[assembly:AllowPartiallyTrustedCallers]
namespace Library
{
[Serializable]
public class MyException : Exception
{
public string String;
public MyException ()
{
}
protected MyException (SerializationInfo info, StreamingContext context)
: base(info, context)
{
String = info.GetString ("String");
}
[SecurityCritical]
public override void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
info.AddValue ("String", String);
base.GetObjectData (info, context);
}
}
}
This works fine in full trust scenarios, e.g., when I run code linking this assembly from my desktop.
However, when I use this class from a security sandbox (see below), I'm getting a TypeLoadException:
Inheritance security rules violated while overriding member:
'Library.MyException.GetObjectData(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)'. Security
accessibility of the overriding method must match the security
accessibility of the method being overriden.
My questions:
Why am I getting this exception? I did mark the override to be SecurityCritical, so where's the problem?
Since the SecurityCriticalAttribute is ignored in my sandbox, how will this class behave in other partial trust hosts, such as IIS/ASP.NET or SQL Server?
How do I implement a serializable exception class in .NET 4?
Sandboxing Code:
var evidence = new Evidence();
evidence.AddHostEvidence (new Zone (SecurityZone.Internet));
var setupInfo = AppDomain.CurrentDomain.SetupInformation;
var permissionSet = SecurityManager.GetStandardSandbox (evidence);
permissionSet.AddPermission (new ReflectionPermission (ReflectionPermissionFlag.MemberAccess));
permissionSet.AddPermission (new SecurityPermission (SecurityPermissionFlag.ControlEvidence));
var sandbox = AppDomain.CreateDomain ("Sandbox", evidence, setupInfo, permissionSet);
You've already answered the first part of your question yourself. Your assembly is being loaded as security transparent because it is not being loaded with full trust, so the SecurityCritical attribute is ignored. And so you get the exception.
Instead of overriding GetObjectData, you should handle the SerializeObjectState event and create a type that implements ISafeSerializationData to store the exception state for serialization. These exist for this exact scenario.
You can't call code marked with the securitycriticalattribute from anything but fully trusted code:
The SecurityCriticalAttribute is equivalent to a link demand for full
trust. A type or member marked with the SecurityCriticalAttribute can
be called only by fully trusted code; it does not have to demand
specific permissions. It cannot be called by partially trusted code.
There's a related question here discussing the use of securitysafecriticalattribute.
Well, I know this post is rather aged, but from my observation recently, if you do not give an assembly FullTrust in the sandboxed AppDomain, all the code in the loaded assembly will be SeurityTransparent. This means the SecurityCriticalAttribute applied to MyException.GetObjectData will just do nothing. It will be SeurityTransparent, and will surely not compatible with its base method, which is SecurityCritical.
Hope this tip will be of some help.
See https://learn.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox for how to mark certain assemblies in the sandboxed AppDomain as FullyTrusted.

Inmutable values mutating in IIS?

So, I've been trying to figure out the following problem for the past few weeks, and at this point I'm almost exhausting my options because how contradictory the situation seems.
I have an application which is developed to work under SharePoint but it's basically ASP.NET code. I have an encrypted connection string which I decrypt it in memory and store it in a configuration object to access the database. My configuration object is static (accesible through a Service Locator pattern), which I later use to seed a LINQ-to-SQL data context.
My internal key for decryption is stored, privately in a class as private static readonly string myPassword = "MyPassword"; (just an example, the actual password is more complex and valid). There's no single statement, anywhere, referencing that field, except one on a static method using it as a parameter for another decryption method (instance method), which instantiates a new DESCryptoServiceProvider with it.
And still, I get the following exception from time to time in my production server logs:
Exception type: CryptographicException
Exception message: Specified key is a known weak key for 'DES' and cannot be used.
As such, the connection string decryption fails and, of course, the database is not accessed anymore. Poof, application down.
How is this even possible?
Disclaimer: This is an old application I am maintaining. The description I provide here is to help troubleshoot, but I cannot change the way it works internally. Some will agree that this is not the best approach but the application has been running without a problem for more than 2 years and suddenly these exceptions are taking it down.
Update: I've been requested to clarify with a stack trace of the exception, but I cannot provide one full stack trace for NDA reasons. What I can tell is the following:
The object throwing the exception is the System.Security.DESCryptoServiceProvider.CreateDecryptor(Byte[] rgbKey, Byte[] rgbIV) method
The original key (the one we actually use) does validate and does not generate an exception. Still, we get this exception from time to time (not always), without knowing which is the current value which does not validate
The instance of the DESCryptoServiceProvider is stored statically, privately, in a helper class
This is all triggered by System.Web.HttpApplication.InitModulesCommon(), to initialize the application internal parts
Also, here is an obscured stack trace:
at System.Security.Cryptography.DESCryptoServiceProvider.CreateDecryptor(Byte[] rgbKey, Byte[] rgbIV)
at SymmetricEncryption.Decrypt(String contents, String key)
// our helper, just a wrapper, based from this class: http://www.codeproject.com/Articles/1967/Encryption-Decryption-with-NET
at EncryptedConnectionStringHelper.DecryptUserAndPass(String connectionString)\
// our container for parsing the connection string and decrypting the user and password, not the full connstring is encrypted
at OurModule.Init(OurConfigurationSection config)
at OurModule.Boot(OurConfigurationSection config)
at OurModule.Boot()
at OurModule.Init(HttpApplication context)
at System.Web.HttpApplication.InitModulesCommon()
at System.Web.HttpApplication.InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers)
at System.Web.HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context)
at System.Web.HttpApplicationFactory.GetApplicationInstance(HttpContext context)
at System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
Our application registers this module in the following way:
public class OurModule : IHttpModule
{
public static bool initialized = false;
public void Init(HttpApplication context)
{
if (!initialized) {
subscribe(context);
OurModule.Boot();
initialized = true;
}
}
Have a look at your wrapper SymmetricEncryption.Decrypt. My guess would be that the issue is in there. How it creates the Key from your password. Does it use PasswordDeriveBytes or some other half baked solution?
Failing that maybe you could try get a better key than "MyPassword".
Failing that maybe you could use web.config encryption. Scott Gu wrote about it here.
It doesn't sound like anything's mutating the object. It sounds like "something" (if you'd posted the stack trace it would be clearer) is validating the DES key... and complaining that it's a known weak key.
Ideally, you should change your password to be more secure, of course - but if you can't, you should look at exactly where that exception's coming from, and see if there are settings somewhere controlling how and when it's validated.
If you're not already logging the full stack trace (instead of just the exception message) that's the first thing you should do.

WCF AddServiceReference causing custom tool error, not producing proxy

A problem with "Add Service Reference", and actually with SvcUtil over all its features.
In order to reproduce you just need to add an OperationContract with argument or returning the following class :
[XmlSchemaProvider("MySchema")]
public class MyStructure : IXmlSerializable
{
private XmlElement e;
private static void Func(object o, ValidationEventArgs args)
{
}
public static XmlQualifiedName MySchema(XmlSchemaSet xs)
{
//xs.XmlResolver = new XmlUrlResolver();
XmlSchema s = XmlSchema.Read(new XmlTextReader(new StringReader("<?xml version=\"1.0\"?><xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"><xs:complexType name=\"MyStructure\"><xs:sequence><xs:any /></xs:sequence></xs:complexType></xs:schema>")), null);
xs.Add(s);
return new XmlQualifiedName("MyStructure");
}
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
throw new NotImplementedException();
}
public void ReadXml(XmlReader reader)
{
XmlDocument doc = new XmlDocument();
e = (XmlElement)doc.ReadNode(reader);
}
public void WriteXml(XmlWriter writer)
{
e.WriteTo(writer);
}
#endregion
}
The result is that when you use AddWebReference or AddSerivceReference without a reference to the class library containing the MyStructure type, everything will be fine ad you will get an xmlElement representation at the auto created proxy.
However, when you have a reference you will get the following warning :
================
Warning 1 Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Referenced type 'ServiceLibrary.MyStructure, ServiceLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' with data contract name 'MyStructure' in namespace '' cannot be used since it does not match imported DataContract. Need to exclude this type from referenced types.
XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:portType[#name='IService1'] \Projects\WCFSample\WCFExample\TestAddReference\Service References\ServiceReference1\Reference.svcmap 1 1 TestAddReference
======================
And no proxy will be generated for you.
Now, the internet is full with descriptions of this when you have a generic DataContract, and/or using IsReference attribute.
This is a much serious problem, since any non-typed data will do this problem.
Could not find any way to solve the problem. What if I want to know the type at the client side, by sharing the class library of the contracts ?
This type of exception generally means there is at least one difference in the type contracts generated by the service as compared to the referenced types (as the message indicates!). But it may not be obvious at first glance, as I found out. Make sure all nested and referenced types are up to date with the server. In my case, nested types were updated on the server. I thought I had updated by locally referenced assembly (and the shared reference types) but I missed some. It took close examination to find the culprit.
See additional information in this question
I have a suggestion:
I had similar errors, including:
the .svcmap file cannot be found. It may have been moved or deleted. To generate a new .svcmap file, delete the service reference and add it again.
And at that point, no way to delete the service reference unless I close VS2010 and open it again.
The situation is: my WCF service is running, I programmatically added a Description.ServiceMetadataBehavior at an HTTP address that I define.
In VS2010, I try to add a service reference at the HTTP address, I see my service, I add the reference, and voila, errors and warning.
The problem: my HTTP address is containing some key words that WCF doesn't like. Specifically the word COM (it breaks with LPT too).
So my solution: modify my HTTP address not to have the word COM. It worked for me.
If the service is hosted over HTTPS, go into the server's IIS Manager. Under "SSL Settings" for the site, make sure "Require SSL" is checked, and check the Client Certificates radio button for "Accept".

Categories