XMLSerialization with WCF Enum Attribute ignored - wcf

I am having problem with serializing object before send to the wire.
Basically I am expecting my object to be serialized as
<verb operation="and">Show</verb>
However its ignoring the attribute as
<verb>Show</verb>
Below is the client proxy code
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.starstandards.org/webservices/2005/10/transport")]
public enum OperationEnumeratedType
{
/// <remarks/>
///
and,
/// <remarks/>
///
or,
/// <remarks/>
///
not,
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
public OperationEnumeratedType operation
{
get
{
return this.operationField;
}
set
{
this.operationField = value;
}
}
and Below is How I am Creating this object.
verb = new CriteriaLogicStringType
{
operation = OperationEnumeratedType.and,
Value = "Show"
}
Does anyone knows how can I get the Operation Attribute to appear in serialized xml?
Thanks

You should decorate the members of the OperationEnumeratedType enumeration with the EnumMemberAttribute, like this:
[DataContract]
public enum OperationEnumeratedType
{
[EnumMember]
And,
[EnumMember]
Or,
[EnumMember]
Not
}
Related resources:
Enumeration Types in Data Contracts

Related

WCF web service not working Due to type of Data contract

When i am testing my WCF web service through "WcfTestClient", it is showing
"this operation is not supported in wcf test client because it uses type VINDescription"
Where VINDescriptionis a DataContract, which is consist of datamembers of type :
"int, string, ArrayList"
It seems WCF web service is not supporting ArrayList?
Please suggest how can i fix this?
Here is a code snippet of DataContract :
[DataContract]
public class VINDescription
{
#region Private Members
private int _cylinders = 0;
private string _msrp = string.Empty;
private ArrayList _interior = new ArrayList();
private string[][] _showOptionalEquipment = new string[][] { };
#endregion
#region Public Data Members
/// <summary>
/// Stores the number of cylinders of a decoded vehicle.
/// </summary>
[DataMember]
public int Cylinders
{
get
{
return _cylinders;
}
set
{
_cylinders = value;
}
}
/// <summary>
/// Stores the MSRP cost of a decoded vehicle.
/// </summary>
[DataMember]
public string MSRP
{
get
{
return _msrp;
}
set
{
_msrp = value;
}
}
/// <summary>
/// Stores the interior values of a decoded vehicle.
/// </summary>
[DataMember]
public ArrayList Interior
{
get
{
_interior.Sort();
return _interior;
}
set
{
_interior = value;
}
}
/// <summary>
/// To store the data for show optional equipments.
/// </summary>
[DataMember]
public string[][] ShowOptionalEquipment
{
get
{
return _showOptionalEquipment;
}
set
{
_showOptionalEquipment = value;
}
}
The way I understand it, WCF actually supports your data contract, but the WCF Test Client tool does not support everything that WCF itself supports, hence the error. Not sure if it's because of ArrayList, string[][], or something else, but in any case it seems to be a tool limitation, not a framework limitation.

Problem with DataContract and hierarchy on WCF

i have a problem with an object in my wcf project.
I have lets say this object:
[DataContract(Name="ClassA")]
public class Person{
//---attributes---
}
[DataContract(Name="ClassB")]
public class Men : Person{
//---attributes---
}
Where ClassB is child of ClassA on the other side.
Then i have a method that is post:
[OperationContract]
[WebInvoke(UriTemplate= "Person", ResponseFormat = WebMessageFormat.Json, Method= "POST")]
public string PostPerson(Person person) {
if(person is Men){
//code...
}
}
The thing is that i receive the person (in the other side, they sendme as a ClassB) but the person is Men returns false.. why?
You need to add the [ServiceKnownType(typeof(Men))] attribute to the PostPerson method.
As Ryan Gross mentions, you need Men to be a known type. Here's a similar question/answer here on SO. One option not mentioned in the linked article is the KnownType attribute. Here's an example of code I've used in the past. The prerequisite is that this class is the base class for all of your data contracts and all of your data contracts are in the same assembly:
/// <summary>
/// Base class for all data contracts.
/// </summary>
[DataContract(Name = "Base", Namespace = "your namespace")]
[KnownType("GetKnownTypes")]
public class BaseDC : IExtensibleDataObject
{
#region Constants and Fields
/// <summary>
/// Instance used to control access to the known types list.
/// </summary>
private static readonly object _knownTypesLock = new object();
/// <summary>
/// Classes derived from this class. Needed to ensure proper functioning of the WCF data
/// constract serializer.
/// </summary>
private static List<Type> _knownTypes;
#endregion
#region Properties
/// <summary>
/// Gets or sets an <c>ExtensionDataObject</c> that contains data that is not recognized as belonging to the
/// data contract.
/// </summary>
public ExtensionDataObject ExtensionData { get; set; }
#endregion
#region Public Methods
/// <summary>
/// Enumerates the types in the assembly containing <c>BaseDC</c> that derive from <c>BaseDC</c>.
/// </summary>
/// <returns>List of <c>BaseDC</c>-derived types.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
Justification = "Not appropriate for a property.")]
public static IEnumerable<Type> GetKnownTypes()
{
lock (_knownTypesLock)
{
if (_knownTypes == null)
{
_knownTypes = new List<Type>();
Assembly contractsAssembly = Assembly.GetAssembly(typeof(BaseDC));
Type[] assemblyTypes = contractsAssembly.GetTypes();
foreach (Type assemblyType in assemblyTypes)
{
if (assemblyType.IsClass && !assemblyType.IsGenericType)
{
if (assemblyType.IsSubclassOf(typeof(BaseDC)))
{
_knownTypes.Add(assemblyType);
}
}
}
_knownTypes.Add(typeof(BaseDC));
}
return _knownTypes;
}
}
#endregion
}

Using NInject to bind a generic interface, with a default if a binding for the generic type is not set

Imagine I have the following classes and interfaces:
public interface IService<T> { }
public class DefaultService<T> : IService<T> { }
public class FooService : IService<Foo> { }
public class BarService : IService<Bar> { }
I would then like to be able to get instances from the Kernel like this:
Kernel.Get<IService<Foo>>(); // Should return FooService
Kernel.Get<IService<Bar>>(); // Should return BarService
Kernel.Get<IService<Dog>>(); // Should return DefaultService
Kernel.Get<IService<Cat>>(); // Should return DefaultService
Kernel.Get<IService<Giraffe>>(); // Should return DefaultService
Is it possible to setup bindings using NInject (possibly using the Conventions extension), so that I don't have to manually bind every single possible implementation of IService?
I've been working on something similar recently and came up with somewhat simpler solution of your problem (although a bit weaker).
What should suffice is to bind a generic implementation (DefaultService) to the generic interface, and concrete implementations (FooService, BarService) to the concrete interfaces. When you ask for a concrete instance of the interface, Ninject resolves whether you defined the concrete binding. If you did, it gives you the appropriate instance, otherwise it falls through to the generic binding. The following code should do the trick.
var kernel = new StandardKernel();
kernel.Bind(typeof(IService<>)).To(typeof(DefaultService<>));
kernel.Bind<IService<Foo>>().To<FooService>();
kernel.Bind<IService<Bar>>().To<BarService>();
EDIT:
The concept works throughout the whole Ninject, so you can use it along with Extensions.Conventions as well.
e.g. define the following:
public class Foo{}
public class Bar{}
public class Dog{}
public interface IService<T>{}
public class DefaultService<T> : IService<T>{}
public class FooService : IService<Foo>{}
public class BarService : IService<Bar>{}
use conventions to bind the services:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IService<>))
.BindSingleInterface());
and create and check the appropriate services:
Assert.IsInstanceOf<BarService>(kernel.Get<IService<Bar>>());
Assert.IsInstanceOf<FooService>(kernel.Get<IService<Foo>>());
Assert.IsInstanceOf<DefaultService<Dog>>(kernel.Get<IService<Dog>>());
I took the liberty of refactoring the answer from #cbp, so that it works for the new IBindingGenerator signature in Ninject v3 conventions. It's pretty much replacing the Process() method signature with the CreateBindings() method signature, but I didn't test this, so there's a chance you'll have to tweak it a bit if you use it.
/// <summary>
/// Creates bindings on open generic types.
/// This is similar to the out-of-the-box
/// <see cref="GenericBindingGenerator" />,
/// but allows a default class to be
/// specified if no other bindings can be found.
/// See the test case for usages.
/// </summary>
public class GenericBindingGeneratorWithDefault : IBindingGenerator
{
private static readonly Type TypeOfObject = typeof(object);
private readonly Type _contractType;
private readonly Dictionary<Type, Type> _cachedBindings;
private readonly Type _defaultType;
public GenericBindingGeneratorWithDefault(Type contractType, Type defaultType)
{
if (!(contractType.IsGenericType || contractType.ContainsGenericParameters))
throw new ArgumentException("The contract must be an open generic type.",
"contractType");
_cachedBindings = new Dictionary<Type, Type>();
_contractType = contractType;
_defaultType = defaultType;
}
/// <summary>
/// Creates the bindings for a type.
/// </summary>
/// <param name="type">The type for which the bindings are created.</param>
/// <param name="bindingRoot">The binding root that is used to create the bindings.</param>
/// <returns>
/// The syntaxes for the created bindings to configure more options.
/// </returns>
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
if (type == null) throw new ArgumentNullException("type");
if (bindingRoot == null) throw new ArgumentNullException("bindingRoot");
if (type.IsInterface || type.IsAbstract) yield break;
if (type == _defaultType)
{
yield return bindingRoot.Bind(_contractType).ToMethod(
ctx =>
{
Type requestedType = ctx.Request.Service;
Type resolution = _cachedBindings.ContainsKey(requestedType)
? _cachedBindings[requestedType]
: _defaultType.MakeGenericType(ctx.GenericArguments);
return ctx.Kernel.Get(resolution);
});
}
else
{
Type interfaceType = ResolveClosingInterface(type);
if (interfaceType != null)
{
yield return bindingRoot.Bind(type).To(_cachedBindings[interfaceType]);
}
}
}
/// <summary>
/// Resolves the closing interface.
/// </summary>
/// <param name="targetType">Type of the target.</param>
/// <returns></returns>
private Type ResolveClosingInterface(Type targetType)
{
if (targetType.IsInterface || targetType.IsAbstract) return null;
do
{
Type[] interfaces = targetType.GetInterfaces();
foreach (Type #interface in interfaces)
{
if (!#interface.IsGenericType) continue;
if (#interface.GetGenericTypeDefinition() == _contractType)
{
return #interface;
}
}
targetType = targetType.BaseType;
} while (targetType != TypeOfObject);
return null;
}
}
I figured out how to do this after a couple of hours messing around with NInject Convention's GenericBindingGenerator.
If anyone is interested I can post it.
Update:
/// <summary>
/// Creates bindings on open generic types.
/// This is similar to the out-of-the-box <see cref="GenericBindingGenerator" />, but allows a default class to be
/// specified if no other bindings can be found. See the test case for usages.
/// </summary>
public class GenericBindingGeneratorWithDefault : IBindingGenerator
{
private static readonly Type TYPE_OF_OBJECT = typeof (object);
private readonly Type _contractType;
private Dictionary<Type, Type> _cachedBindings = new Dictionary<Type, Type>();
private readonly Type _defaultType;
public GenericBindingGeneratorWithDefault(Type contractType, Type defaultType)
{
if ( !( contractType.IsGenericType || contractType.ContainsGenericParameters ) )
{
throw new ArgumentException( "The contract must be an open generic type.", "contractType" );
}
_contractType = contractType;
_defaultType = defaultType;
}
/// <summary>
/// Processes the specified type creating kernel bindings.
/// </summary>
/// <param name="type">The type to process.</param>
/// <param name="scopeCallback">the scope callback.</param>
/// <param name="kernel">The kernel to configure.</param>
public void Process( Type type, Func<IContext, object> scopeCallback, IKernel kernel )
{
if (type == _defaultType)
{
kernel.Bind(_contractType).ToMethod(
ctx =>
{
var requestedType = ctx.Request.Service;
var resolution = _cachedBindings.ContainsKey(requestedType)
? _cachedBindings[requestedType]
: _defaultType.MakeGenericType(ctx.GenericArguments);
return ctx.Kernel.Get(resolution);
});
}
else
{
Type interfaceType = ResolveClosingInterface(type);
if (interfaceType != null)
{
_cachedBindings[interfaceType] = type;
}
}
}
/// <summary>
/// Resolves the closing interface.
/// </summary>
/// <param name="targetType">Type of the target.</param>
/// <returns></returns>
public Type ResolveClosingInterface( Type targetType )
{
if ( targetType.IsInterface || targetType.IsAbstract )
{
return null;
}
do
{
Type[] interfaces = targetType.GetInterfaces();
foreach ( Type #interface in interfaces )
{
if ( !#interface.IsGenericType )
{
continue;
}
if ( #interface.GetGenericTypeDefinition() == _contractType )
{
return #interface;
}
}
targetType = targetType.BaseType;
} while ( targetType != TYPE_OF_OBJECT );
return null;
}
}

WCF Message Contract namespace issue

I have following MessageContract
[MessageContract(IsWrapped = true, WrapperName = AuthorizationXmlElementNames.ElementNames.GetUserRightsResponse,
WrapperNamespace = AuthorizationXmlElementNames.Namespace)]
public class GetUserRightsResponseMessage
{
#region Properties
/// <summary>
/// Gets or sets GetUserRightsResponse.
/// </summary>
[MessageBodyMember(Namespace = AuthorizationXmlElementNames.Namespace)]
public GetUserRightsResponse GetUserRightsResponse { get; set; }
/// <summary>
/// Gets or sets ResponseHeader.
/// </summary>
[MessageHeader(
Name = XmlCoreElementNames.ElementNames.ResponseHeader,
Namespace = XmlCoreElementNames.Namespace,
ProtectionLevel = ProtectionLevel.None)]
public ResponseHeader ResponseHeader { get; set; }
#endregion
}
GetUserRightsResponse class looks like this
[XmlRoot(ElementName = AuthorizationXmlElementNames.ElementNames.GetUserRightsResponse,
Namespace = AuthorizationXmlElementNames.Namespace, IsNullable = false)]
[Serializable]
//[MessageContract(WrapperName = AuthorizationXmlElementNames.ElementNames.GetUserRightsResponse, WrapperNamespace = AuthorizationXmlElementNames.Namespace)]
public class GetUserRightsResponse
{
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="GetUserRightsResponse"/> class.
/// Initialize a new instance of the <see cref="GetUserRightsResponse"/> class.
/// </summary>
public GetUserRightsResponse()
{
this.UserServiceAccesses = new UserServiceAccesses();
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the user rights for the current user.
/// </summary>
//[MessageBodyMember(Namespace = AuthorizationXmlElementNames.Namespace)]
public UserServiceAccesses UserServiceAccesses { get; set; }
#endregion
}
XmlCoreElementNames.Namespace is the constant string for namespace and it's value is urn:MyNamespace:Authorization
I return an instance of the GetUserRightsResponseMessage from my operation contract. But I always get wrong namespace for the GetUserRightsResponse instance contained in the returned object. The returned XML part looks like the following.
<s:Body u:Id="_0">
<GetUserRightsResponse xmlns="urn:MyNamespace:Authorization">
<GetUserRightsResponse i:nil="true"
xmlns:a="http://schemas.datacontract.org/2004/07/MyMessageContract.MessageContracts"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
</GetUserRightsResponse>
</s:Body>
Why do i always get the namespace xmlns:a="http://schemas.datacontract.org/2004/07 for the property in the returned object? What does xmlns:a mean?
Both GetUserRightsResponse elements are in namespace "urn:MyNamespace:Authorization", because the default namespace declaration on the outer one is inherited by the inner one.
xmlns:a="http://schemas.datacontract.org/2004/07/MyMessageContract.MessageContracts" is a namespace declaration which defines a namespace prefix ("a") which isn't actually used in your message. So it has no effect at all on the meaning of the XML message and could be omitted. Its presence is a quirk of the Microsoft implementation, perhaps triggered by the naming collision between your message wrapper element name and the data contract name (but I'm just guessing about this).
If your clients are fully XML compliant, this shouldn't be a problem for you at all. However, there are some non-compliant SOAP client toolsets around which are fussy about the treatment of namespace declarations. If you are very unlucky you might find you have one which is confused by an unused namespace prefix declaration.
You are not getting wrong namespace, as far as I can see.
All elements are set to "urn:MyNamespace:Authorization" which I imagine is the AuthorizationXmlElementNames.Namespace.
xmlns:a="http://schemas.datacontract.org/2004/07/MyMessageContract.MessageContracts" points to Microsoft's schema for message contracts. Now this does not seem to have been used in the snippet you published, so I am surprised it is there at all but this is an innocent namespace since you do not have any element or attribute in that namespace.

WCF Data Service Partial class property on the client causes SaveContext exceptions

I have a WCF Data Service running that is exposing an EDM. There are several properties I needed on the client side, that the database doesn't need to know about. After setting all that up I got to testing the SaveContext method and get this error on the server "Error processing request stream. The property name 'CanDelete' specified for type 'DataModels.Customer' is not valid."
Is there a way to tell WCF Data Services on the client side to ignore this property? Or should I move to RIA Serivces? I've read that setting the property to internal will do this, but I need the property for binding and I have the client UI code in a different project (de-coupling my SL applications from my data service).
on the client I have:
public partial class Customer
{
private bool canDelete;
/// <summary>
/// Gets or sets a value indicating whether this instance can be deleted.
/// </summary>
/// <value>
/// <c>true</c> if this instance can delete; otherwise, <c>false</c>.
private bool canDelete;
/// <summary>
/// Gets or sets a value indicating whether this instance can be deleted.
/// </summary>
/// <value>
/// <c>true</c> if this instance can delete; otherwise, <c>false</c>.
/// </value>
public bool CanDelete
{
get
{
return this.canDelete;
}
set
{
if (this.canDelete != value)
{
this.canDelete = value;
this.OnPropertyChanged("CanDelete");
}
}
}
}
I had the exact same problem and adapted some code below from
extending partial designer classes
It simply involves hooking the WritingEntity Event inside a partial class of the Context.
I added my own attribute (IgnorePropertyAttribute) so I could attach it to other properties.
Would of course be nice if the attribute wasnt inserted in the first place but this worked for me
public sealed class IgnorePropertyAttribute : Attribute
{
}
...
partial void OnContextCreated()
{
this.WritingEntity += MyDataContext_WritingEntity;
}
private void MyDataContext_WritingEntity(object sender, System.Data.Services.Client.ReadingWritingEntityEventArgs e)
{
//
foreach (XElement node in e.Data.Elements())
{
if (node != null && node.Name.LocalName == "content")
{
foreach (XElement el in node.Elements())
{
if (el.Name.LocalName == "properties")
{
foreach (XElement prop in el.Elements())
{
if(e.Entity.GetType().GetProperty(prop.Name.LocalName).GetCustomAttributes(typeof(IgnorePropertyAttribute), true).Length > 0)
{
prop.Remove();
}
}
}
}
}
}
}