Testing for interface implementation in WCF/SOA - wcf

I have a reporting service that implements a number of reports. Each report requires certain parameters. Groups of logically related parameters are placed in an interface, which the report then implements:
[ServiceContract]
[ServiceKnownType(typeof(ExampleReport))]
public interface IService1
{
[OperationContract]
void Process(IReport report);
}
public interface IReport
{
string PrintedBy { get; set; }
}
public interface IApplicableDateRangeParameter
{
DateTime StartDate { get; set; }
DateTime EndDate { get; set; }
}
[DataContract]
public abstract class Report : IReport
{
[DataMember]
public string PrintedBy { get; set; }
}
[DataContract]
public class ExampleReport : Report, IApplicableDateRangeParameter
{
[DataMember]
public DateTime StartDate { get; set; }
[DataMember]
public DateTime EndDate { get; set; }
}
The problem is that the WCF DataContractSerializer does not expose these interfaces in my client library, thus I can't write the generic report generating front-end that I plan to. Can WCF expose these interfaces, or is this a limitation of the serializer? If the latter case, then what is the canonical approach to this OO pattern?
I've looked into NetDataContractSerializer but it doesn't seem to be an officially supported implementation (which means it's not an option in my project). Currently I've resigned myself to including the interfaces in a library that is common between the service and the client application, but this seems like an unnecessary extra dependency to me. Surely there is a more straightforward way to do this? I was under the impression that WCF was supposed to replace .NET remoting; checking if an object implements an interface seems to be one of the most basic features required of a remoting interface?

I believe you just need to put the ServiceContract attribute on the interface defintions, too, as in
[ServiceContract]
public interface IReport
{
[OperationContract]
string PrintedBy { get; set; }
}
etc...

Related

FaultContract<T> - what does it means?

I should create wcf service that returns data about users, the interface and DataContract is below:
[ServiceContract]
public interface IUserInfoProvider{
[FaultContract<UserNotFound>]
public UserInfo GetUserInfo(Guid userId)}
[DataContract]
public class UserInfo
{
[DataMember] public Guid UserId { get; set; }
[DataMember] public bool? AdvertisingOptIn { get; set; }
[DataMember] public string CountryIsoCode { get; set; }
[DataMember] public DateTime DateModified { get; set; }
[DataMember] public string Locale { get; set; }
}
I have no special client for service - requests (get, post) runs from fiddler or rest plugin for browser.
Please, describe how to implement [FaultContract<>] in my case, i saw examples with [FaultContract(typeof(UserNotFound))] but never seen [FaultContract<>]
Sorry about the late answer, but I faced something similar and I would like to share what I've found:
FaultContract is possible: https://msdn.microsoft.com/en-us/library/ff650547.aspx
From MSDN:
To support the use of custom faults, WCF services use the
FaultContractAttribute to formally specify faults that can be returned
from a service operation. Types specified in a FaultContractAttribute
must be serializable as DataContract,SerializableAttribute, or
ISerializable. When a FaultException is thrown using a custom fault
defined in FaultContract, client applications can also catch these
specific faults using the FaultException generic type.
Example:
throw new FaultException<InvalidNameFault>(fault, "Invalid Name!");

How to ignore a DataMember from the superclass in a subclass

The title is pretty self-explanatory.
I have a base WCF DataContract, let's call it the PersonContract, which covers all fields of the Person entity in my database.
I have a number of client applications that call the same service through endpoints of different interfaces implemented by that service. This is because (amongst other differences) I want every of those applications to be able to access and edit only a specific subset of the Person entity.
Now if I want to define a contract with all the properties of PersonContract except one, can I subclass PersonContract and ignore a single property in the subclass?
Or is my only option building contracts from the smallest subset (but I doubt I can fully avoid repeating code then)?
Out of curiosity I did a couple tests and it doesn't look like it'll work.
Here are the data contracts I used:
[DataContract]
public class Person
{
[DataMember]
public virtual string FirstName { get; set; }
[DataMember]
public virtual string MidName { get; set; }
[DataMember]
public virtual string LastName { get; set; }
}
[DataContract]
public class Person2 : Person
{
[IgnoreDataMember]
public override string MidName { get; set; }
}
And my service contract:
public interface IService1
{
[OperationContract]
Person GetPerson();
[OperationContract]
Person2 GetPerson2();
}
Both operations return the same result.
Another way that you might be able to produce the results you're looking for could be to define your minimal contract (the one with missing the excluded properties) and inherit from it adding the field needed by the other operation.
The equivalent data contracts would look something like:
[DataContract]
public class Person2 : Person
{
[DataMember]
public virtual string MidName { get; set; }
}
[DataContract]
public class Person
{
[DataMember]
public virtual string FirstName { get; set; }
[DataMember]
public virtual string LastName { get; set; }
}
And I've verified that the results are as I would expect.

.NET WebAPI Serialization k_BackingField Nastiness

When i serialize the following:
[Serializable]
public class Error
{
public string Status { get; set; }
public string Message { get; set; }
public string ErrorReferenceCode { get; set; }
public List<FriendlyError> Errors { get; set; }
}
I get this disgusting mess:
<ErrorRootOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Printmee.Api">
<_x003C_Errors_x003E_k__BackingField>
An exception has occurred. Please contact printmee support
</_x003C_Errors_x003E_k__BackingField>
<_x003C_LookupCode_x003E_k__BackingField>988232ec-6bc9-48f3-8116-7ff7c71302dd</_x003C_LookupCode_x003E_k__BackingField>
</ErrorRootOfstring>
What gives? How can i make this pretty? JSON responses also contain the k_BackingField
By default you don't need to use neither [Serializable] nor [DataContract] to work with Web API.
Just leave your model as is, and Web API would serialize all the public properties for you.
Only if you want to have more control about what's included, you then decorate your class with [DataContract] and the properties to be included with [DataMember] (because both DCS and JSON.NET respsect these attributes).
If for some reason, you need the [Serializable] on your class (i.e. you are serializing it into a memory stream for some reason, doing deep copies etc), then you have to use both attributes in conjunction to prevent the backing field names:
[Serializable]
[DataContract]
public class Error
{
[DataMember]
public string Status { get; set; }
[DataMember]
public string Message { get; set; }
[DataMember]
public string ErrorReferenceCode { get; set; }
[DataMember]
public List<FriendlyError> Errors { get; set; }
}
There is a more general solution: you can configure the Json Serializer to ignore the [Serializable] attribute, so that you don't have to change the attributes in your classes.
You should make this configuration change in the application start, i.e. in Global.asax Application_Start event:
var serializerSettings =
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
var contractResolver =
(DefaultContractResolver)serializerSettings.ContractResolver;
contractResolver.IgnoreSerializableAttribute = true;
You can also make other changes to the Json serialization, like specifying formats for serializing dates, and many other things.
This will only apply to the Web API JSON serialization. The other serializations in the app (Web API XML serialization, MVC JsonResult...) won't be affected by this setting.
Try using DataContract instead of Serializable for marking your class. For more detail on why, look at this good blog post on serializing automatic properties.
The [DataContract] attributes dosn't worked for me, so it was not an option.
XmlSerializer ignores [XmlAttribute] in WebApi
The above resolution solved it for me.
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

Send a list with appointments through WCF

I would like to send a list of Appointments through WCF. My Interface looks like this:
[ServiceContract]
public interface IServices
{
[OperationContract]
string addAppointments(List<Appointment> appointmentList);
}
If I call my WCF Service I'm always getting the following error:
Type 'Microsoft.Exchange.WebServices.Data.Appointment' cannot be
serialized. Consider marking it with the DataContractAttribute
attribute, and marking all of its members you want serialized with the
DataMemberAttribute attribute. See the Microsoft .NET Framework
documentation for other supported types.
My Service currently looks like this:
class Service : IServices
{
public string addAppointments(List<Appointment> appointmentList)
{
foreach (Appointment app in appointmentList)
{
Console.WriteLine(app.Organizer.Name);
}
return "true";
}
}
It's not your service that's at fault, it's the class your passing, Appointment.
Start by adding [DataContract] to your class. then [DataMember] to each of the properties you'd like to pass.
For example, if you started with:
public class Appointment{
public DateTime Date { get; set; }
public string Name { get; set; }
}
You can make it serializable by WCF's DataContractSerializer by adding those attributes:
[DataContract]
public class Appointment{
[DataMember]
public DateTime Date { get; set; }
[DataMember]
public string Name { get; set; }
}

RIA DomainService not generating client code using DataContracts

I'm working on a Silverlight 4.0 application and am using RIA services. I have created a class on the server-side which has DataContract and DataMember attributes applied to it.
A DomainService exposes this class as a query result and as such, generates code for it on the client. But somehow it doesn't generate code for all properties of the class. Primitive properties of type guid, string, int, bool etc are generated just fine, but if I have a property of my own complex type, that property isn't created on the client.
Here's the class in question:
[DataContract]
[KnownType(typeof(SummaryGroup))]
public class SummaryDataSet
{
public SummaryDataSet()
{
}
[KeyAttribute]
[DataMember]
public Guid Guid { get; set; }
[DataMember]
public SummaryGroup SummaryGroup { get; set; }
}
The Guid property is created on the client just fine. The SummaryGroup property isn't created on the client. Here's the code for the SummaryGroup:
[DataContract]
public class SummaryGroup
{
public SummaryGroup()
{
}
[KeyAttribute]
[DataMember]
public Guid Guid { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int Sequence { get; set; }
}
Both classes are in the same namespace.
Question: why isn't the SummaryGroup property of SummaryDataSet created on the client and what should I do to fix this?
WCF RIA cannot handle complex types, but you could try this:
[DataContract]
[KnownType(typeof(SummaryDataSet))]
public class SummaryDataSet
{
public SummaryDataSet()
{ }
[KeyAttribute]
[DataMember]
public Guid Guid { get; set; }
[DataMember]
[Association("SummarySet_SummaryGrp_FK", "Guid", "Guid")]
public SummaryGroup SummaryGroup { get; set; }
}
This gives RIA the information to connect from the SummaryDataSet to the SummaryGroup.
This assumes that you can request both the SummaryDataSet and SummaryGroup from the serverside service.