Let say I have following classes:
public class Entity { ... }
public class MyEntity : Entity
{
}
MyEntity can be complex object, which has list of Entity as its property.
I'd like to serialize MyEntity to xml, but only properties of base class, i.e Entity object.
I tried to use DataContractSerializer with DataMemberAttribute, but it seems, starting
with .NET 3.5 it serializes all public properties even if DataMemberAttribute is not applied.
What are my options?
Okay, answer to my own question. My current solution is to implement IXmlSerializable in the base class (Entity class), and not implement this interface for derived classes (MyEntity). Then XmlSerializer serializes public properties of only the base class. Tricky part is implementing IXmlSerializable; especially ReadXml() method. An answer by Paul Alexander (not selected answer!) in the following post was helpful to me:
Reading Xml with XmlReader in C#
Related
I am new to WCF; I have an abstract class that in my WCF service.
I am referencing that WCF service from another application that invokes it: I have it added as a Service Reference in my Visual Studio project.
I managed to serialize the derived classes using the ServiceKnownType attribute, but I cannot manage to make the base class automatically abstract in the service reference code.
Any ideas?
I'm not sure whether this is something that will work in your case, but you can't (with the normal Add Service Reference tool) directly generate abstract classes.
However, all generated classes are partial, so if you know the namespace, all that's required to make it abstract is a new file with;
namespace whatever.the.service.reference.namespace.is {
abstract partial class MyClass { }
}
...and the class will be marked abstract.
could some one please confirm whether I should always have a DataContract and datamember attribute for Operation Parameter and return types?
e.g.
ResponseMessage getOrderDetails(RequestMessage msg)
{
....
}
public class ResponseMessage
{
...
}
public class RequestMessage
{
...
}
It was required only in very first version of WCF (.NET 3.0). After that default data contract serialization was introduced so you don't have to place DataContract attribute on your classes and all public properties with getter and setter will be serialized. Once you want better control over serialization you will use DataContract and DataMember attributes or you will switch to Xml serialization.
The parameter types and return types need to be either serializable or treated in a special way by WCF.
For the first case, [DataContract] and [DataMember] is only one way to make a type serializable - the post at http://blogs.msdn.com/b/sowmy/archive/2006/02/22/536747.aspx describes the serialization programming model in WCF. As Ladislav mentioned, starting with .NET 3.5 SP1 WCF introduced a default (POCO) serialization so you don't need any annotation at all.
For the second case, there are some types which are treated as special cases by WCF, such as System.IO.Stream or System.ServiceModel.Channels.Message - and you can even add more such types if you use a custom message formatter (although this is an advanced scenario and not very common).
I am using WCF to retrieve a collection of objects. The objects are all of type ProcedureText but may be of child classes SuspensionText or ResumptionText, both of which inherit from ProcedureText.
public class ProcedureText { }
public class SuspensionText : ProcedureText { }
public class ResumptionText : ProcedureText { }
My OperationContract specifies a method returning an array of ProcedureText objects:
[OperationContract]
[WebGet(UriTemplate = "procedureTexts")]
ProcedureText[] GetProcedureTexts();
This works if I cast all my objects to ProcedureText but I want to keep the distinction of using the sub-types. I had hoped to use the KnownType attribute to do this and had expected to be able to do it by adding it to my ProcedureText class:
[System.Runtime.Serialization.KnownType(typeof(SuspensionTextDto))]
[System.Runtime.Serialization.KnownType(typeof(ResumptionTextDto))]
public class ProcedureText { }
This doesn't work because the compiler cannot resolve System.Runtime.Serialization.KnownType. I know from the document that the attribute is part of .NET Framework 4, but I am using .NET Framework 4 and that is the Target Frameweork for my project.
Why do I need to set to be able to use the attribute?
The relevant DLL containing that type is not added by default. You need to add a reference to:
System.Runtime.Serialization
The usage is described in the documentation:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.knowntypeattribute.aspx
Basically it is so that the serializer recognises the type. Your service contract returns an array of the base class, however the types in that array could be more derived. If the serializer is not told this, the serialization will fail I think.
Without explicitly adding the reference to the project, I was able to use " I was able to use "using System.Runtime.Serialization" in my code but when I used attributes like "KnownType" or "DataMember" the compiler gave an error.
I was able to overcome this issue by explicitly adding the reference. Go to "Add References" in your project and search for "System.Runtime.Serialization" under Assemblies and add the dll to the project.
Works in .net 4.5 and 4.5.1 so I assume this will work in 4.0 as well.
I’m using NHibernate for data access, but accessing it through a façade layer. This layer consists of interfaces for the repositories, plus an IUnitOfWork interface which corresponds to the ISession object.
In order that retrieved entities are managed correctly, repositories are passed an IUnitOfWork in their constructor and the IUnitOfWork is used for the loading.
The IUnitOfWork contains a property called All, which retrieves all entities of the class as an IQueryable (for later filtering). Thus, a repository method to retrieve all entities created this year might look like the following:
NB: this is not the complete code for these interfaces and classes! Only the code relevant to my question.
IUnitOfWork interface:
IQueryable<T> GetList<T>();
UnitOfWork concrete class:
public IQueryable<T> GetList<T>()
{
return _session.Linq<T>();
}
IFooRepository interface
IQueryable<Foo> All { get; }
IEnumerable<Foo> ThisYearsFoos{ get; }
FooRepository concrete class
public IQueryable<Foo> All
{
get { return _unitOfWork.GetList<Foo>(); }
}
public IEnumerable<Foo> ThisYearsFoos
{
get { return All.Where(x => x.DateCreated > new DateTime(2010,1,1);}
}
I would like to add functionality to specify fetch strategies so that related entities can be eagerly loaded. So let’s say Foo has a property corresponding to another entity, Bar:
public class Foo
{
public Bar {get;set;}
}
The mapping file specifies that Bar is lazy-loaded, but in my ThisYearsFoos repository property I would like to specify that Bar should be eagerly loaded to avoid N+1 selects.
In Linq to NHibernate we can specify eager fetching using the Expand() extension method. However, this extension method belongs to the NHibernateQueryable type, whereas the IUnitOfWork interface’s GetList method only knows about IQueryable.
Clearly I don’t want the IUnitOfWork interface to know about INHibernateQueryable since it is supposed to not know about NHibernate.
Using the design I have specified above, is there a way to do this that I haven’t been able to think of? Or is my design in need of a rethink?
Thanks
David
Upgrade to NHibernate 3.x. The new method that corresponds to Expand (Fetch) operates on IQueryable.
You are saying some conflicting things:
- You don't want to expose interface
- You want to use the use that interface
That is impossible. You have to rethink your design.
You use the term unit of work for a different thing than most people do.
Most people would expect a unit of work interface to have the methods Commit and RollBack, but not some IQueryable.
I have an interface that describes an specialized list in my application...
Public Interface IAlphabeticListItem
Property StartingLetter() As String
Property DetailsList() As Generic.List(Of DetailsData)
End Interface
Multiple objects implement this interface, but I want to return them in a webservice not as the underlying object, but as the interface.
<WebMethod()> _
Public Function GetCategoryList(...) As Generic.List(Of IAlphabeticListItem)
...
End Function
Sadly, this causes an exception
Cannot serialize interface IAlphabeticListItem.
Exception Details: System.NotSupportedException: Cannot serialize interface IAlphabeticListItem.
Is there a way to make an interface serializable, or am I going to have to convert each of my objects into a concrete class implementing the interface, and then return that class?
Yes and no. You cannot directly expose the generic class for XML serialization because it's not supported. You can however expose a non-generic interface on the same collection and serialize that. This blog goes into great detail on how to make this work
http://srtsolutions.com/blogs/billwagner/archive/2006/11/20/xml-serialization-and-generic-interfaces.aspx
I don't have time to test it right now, but in C# you can extend interfaces, so I suppose you can do that in VB.NET.
Just make IAlphabeticListItem extend ISerializable