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!");
Related
I am developing a Wcf Restful Service which contains data contract "User" shown below
[DataContract]
public class User
{
public User()
{
}
[DataMember(Name = "Name")]
public string Name { get; set; }
[DataMember(Name = "Mobile")]
public string Mobile { get; set; }
[DataMember(Name = "Email")]
public string Email { get; set; }
[DataMember(Name = "IsImageUpdated")]
public bool IsImageUpdated { get; set; }
}
Now i would like to add one mode data member of type Image,When i try to add Image with type Stream it showing exception
[DataMember(Name = "Iamge")]
public Stream Image { get; set; }
"The InnerException message was 'Type 'System.IO.FileStream' with data contract name 'FileStream:http://schemas.datacontract.org/2004/07/System.IO' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details."
The service i am developing having many Data contract's,I read some posts which saying the issue can be resolved by changing the Datacontract to message contract,Does a service supports different contract types(like Data,Message).
i need a solution.
This is not possible when using a WebHttpBinding.
Combining streamed and buffered Content is only possible when the binding has a SOAP message Format and you use MessageContract instead of DataContract.
Using a byte[] or returning the stream directly is supported.
[DataMember(Name = "Iamge")]
public byte[] Image { get; set; }
or
[OperationContract]
[WebGet(UriTemplate = "/Image")]
Stream GetImage();
or when using NetTcpBinding, WsHttpBinding, BasicHttpBinding, ...
[MessageContract]
public class ImageData
{
[MessageBodyMember]
public Stream Image { get; set; }
[MessageHeader]
public string Name { get; set; }
}
I have a WCF method:
public IQueryable<AmenitySummary> GetAmenities(string searchTerm)
Now, AmenitySummary is defined thus
[DataContract]
public class AmenitySummary
{
[DataMember]
public int AmenityId { get; set; }
[DataMember]
public string Amenity { get; set; }
[DataMember]
public string LowerCaseAmenity { get; set; }
}
In my client side solution I have a project in which I call this method. The problem is that the signature in the Reference.cs file is this
public object GetAmenities(string searchTerm) {
return base.Channel.GetAmenities(searchTerm);
}
How comes? Why isn't the return type IQueryable<AmenitySummary>? What am I missing?
Not only that, but when I try to use AmenitySummary on the client side I can't do it as it's not recognised. I think this is linked.
Thanks,
S
IQueryable is not serialiable without specific references (see svcutil.exe /references).
Otherwise use a WCF DataService (OData) or return an array of AmenitySummary from the service. In the later case you can convert the array to an IQuaryable instance.
I think it's because of IQueryable. You probably need to expose it too.
See this post:
Expose IQueryable Over WCF Service
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;
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; }
}
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...