[Edit]: I added the TokenType enum, what caused the whole issue...
I have an issue using WCF and unfortunately I didn't find any useful help.
I am creating a WCF based application. When the server responds to the client's request, I want the send back the following class:
[DataContract]
public enum TokenType
{
User,
Device
}
[DataContract]
public class AuthenticationResponse
{
[DataMember]
public LogonStatus Status { get; set; }
[DataMember]
public AccessToken Token { get; set; }
}
[DataContract]
public struct AccessToken
{
[DataMember]
public string TokenID
{
get;
set;
}
[DataMember]
public TokenType Type
{
get;
set;
}
[DataMember]
public string Uid
{
get;
set;
}
[DataMember]
public string Name
{
get;
set;
}
[DataMember]
public DateTime ExpirationTime
{
get;
set;
}
[DataMember]
public DateTime GenerationTime
{
get;
set;
}
[DataMember]
public bool IsExpired
{
get
{
return DateTime.Now > this.ExpirationTime;
}
}
}
When I send the AuthenticationResponse back to the client, it always fails.
My qusetion: Is there any chance to use class/struct objects within DataContract object or do I have to replace the AccessToken object with basic types (e.g. string) in the AuthenticationResponse object?
Thanks all your helps!
Best regards
Gabor
The problem is your public bool IsExpired has no setter and thus cause problems while serializing the object.
A workaround is to set a protected/private setter to your property with an empty body (or replace it by a method)
[DataMember]
public bool IsExpired
{
get
{
return DateTime.Now > this.ExpirationTime;
}
set
{
/* Dummy setter for serialization fix */
}
}
You can find more information about Serialization here : https://msdn.microsoft.com/en-us/library/182eeyhh.aspx
More specifically :
Items That Can Be Serialized
The following items can be serialized using the XmLSerializer class:
Public read/write properties and fields of public classes
Ahh...
Sorry for that. I was really stupid... I forgot to paste the TokenType enum in my original question what is part of AuthenticationResponse class, and this was the problem... I forget the set the [EnumMember] attributes...
After I added, everything worked well.
Sorry for this stupid and really beginner problem...
Thanks all your helps!!!
Related
I have an issue that I can't trace the origin of within my WebAPI project. The API has been working, however, when deploying I found I was receiving an error relating to serialization of an object that implied I needed a DataContract attribute on the class and DataMember attributes on each serializable property.
I've applied these attributes, however, I still see the error.
The code that presents the error is:
[ResponseType(typeof(PortalUser))]
public HttpResponseMessage Get([FromUri]int userId)
{
var user = Request.CreateResponse(repository.GetById(userId));
if (user != null)
return Request.CreateResponse(user);
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Not found");
}
Where PortalUser is defined as:
[Serializable]
[DataContract]
public class PortalUser : IUser<string>
{
public PortalUser() { }
[DataMember]
public string Id { get; set; }
[DataMember]
public string EmailAddress { get; set; }
[DataMember]
public string MobileTelephone { get; set; }
[DataMember]
public string Firstname { get; set; }
[DataMember]
public string Surname { get; set; }
[DataMember]
public string Company { get; set; }
[DataMember]
public string HashedPassword { get; set; }
[DataMember]
public string PasswordSalt { get; set; }
[DataMember]
public byte[] AuthenticatorQrCodeImage { get; set; }
[DataMember]
public string AuthenticatorFallbackCode { get; set; }
[DataMember]
public int FailedLoginCount { get; set; }
[DataMember]
public DateTime LastFailedLoginAttempt { get; set; }
[DataMember]
public string ManagerId { get; set; }
[DataMember]
public string UserName { get { return EmailAddress; } set { EmailAddress = value; } }
[DataMember]
public string TwoFactorAuthenticationSecretKey { get; set; }
}
As you can see, I've already tried adding the attributes suggested in the error (Error 1 below). I have also tried removing the XmlMediaFormatter, which then started throwing errors about not being able to access the ReadTimeout on a stream (Error 2 below).
Error 1:
Type
'System.Net.Http.ObjectContent`1[PolicyService.Common.Models.PortalUser]'
cannot be serialized. Consider marking it with the
DataContractAttribute attribute, and marking all of its members you
want serialized with the DataMemberAttribute attribute. If the type is
a collection, consider marking it with the
CollectionDataContractAttribute. See the Microsoft .NET Framework
documentation for other supported types.
Error 2:
"Message":"An error has occurred.","ExceptionMessage":"Error getting
value from 'ReadTimeout' on
'Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream'.","ExceptionType":"Newtonsoft.Json.JsonSerializationException","StackTrace":"
at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object
target)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter
writer, Object value, JsonContainerContract contract, JsonProperty
member, JsonProperty property, JsonContract& memberContract, Object&
memberValue)\r\n at ...
I've seen instances of similar error messages, however, it sounds like most of these were resolved by adding the DataContract attributes, which hasn't helped here.
Has anyone else seen this, or can anyone help shed any light on the issue?
It looks like your issue might be that you are creating a response out of a response...You create a response, then if not null, try to create another response with the original response. So, I imagine it is trying to serialize the original response, not your object.
WHY this does not work for the ContactData[] array property !? the received array is always empty!!!
WCF can serialize ContactData whithout any problem, but not a simple array of ContactData !?!? this is crazy o_O
What is the simplest and fastest way to send correctly this collection of ContactData through a wcf call ??
[DataContract]
public class MessageData
{
[DataMember]
public ContactData From { get; set; }
[DataMember]
public ContactData[] To { get; set; }
[DataMember]
public string MessageText { get; set; }
}
[DataContract]
public class ContactData
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Address { get; set; }
}
It turned out to be my service reference that was not up to date, i deleted and recreated the service reference and it just worked fine, sorry for my stupidity...
I misunderstood something I had read about serialization of collections and thought there was something different to do here.
try
public List<'ContactData> To { get; set; }
remove ' in <'
How can I serialize the given object into JSON but only include properties with the [DataMember] attribute.
User MyUser = new User();
string MessageJson = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MyUser);
public class User
{
[DataMember]
public string username { get; set; }
public string password { get; set; }
}
You need to use DataContractJsonSerializer for that.
Note that, I think you'll also need DataContract attribute on the class.
You can use JSON.Net.
If a class has many properties and you only want to serialize a small subset of them then adding JsonIgnore to all the others will be tedious and error prone. The way to tackle this scenario is to add the DataContractAttribute to the class and DataMemberAttributes to the properties to serialize. This is opt-in serialization, only the properties you mark up with be serialized, compared to opt-out serialization using JsonIgnoreAttribute.
[DataContract]
public class Computer
{
// included in JSON
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal SalePrice { get; set; }
// ignored
public string Manufacture { get; set; }
public int StockCount { get; set; }
public decimal WholeSalePrice { get; set; }
public DateTime NextShipmentDate { get; set; }
}
You can place the [ScriptIgnore] attribute on the properties that you do not want to include in your result.
I am trying to use the WCF Test Client to test a WCF service I have built.
The service has one method "SubmitRequest".
[OperationContract]
Response SubmitRequest(Request request);
When I load up the WCF Test Client, the method is grayed out with the message "This operation is not supported in the WCF Test Client because it uses type WcfLibrary.Objects.Request
Below is the type definition, does anyone see anything wrong?
[DataContract]
public class Request
{
[DataMember]
public string LoanNumber { get; set; }
[DataMember]
public string ClientCode { get; set; }
[DataMember]
public Region Region { get; set; }
[DataMember]
public RequestType RequestType { get; set; }
[DataMember]
public List<RequestParameter> RequestParameters { get; set; }
[DataMember]
public List<MspWebCallType> MspWebCallsForXmlRequest { get; set; }
[DataMember]
public Hashtable XmlRequestParameters { get; set; }
public Request(string loanNumber, string clientCode, Region region, RequestType requestType, List<RequestParameter> requestParameters)
{
LoanNumber = loanNumber;
ClientCode = clientCode;
Region = region;
RequestType = requestType;
RequestParameters = requestParameters;
}
}
[DataContract]
public class MspWebCallType
{
[DataMember]
public string WebService { get; set; }
[DataMember]
public string Operation { get; set; }
[DataMember]
public string Version { get; set; }
[DataMember]
public Hashtable Parameters { get; set; }
[DataMember]
public Msp.FavReadViews FAVReadViewIndicator { get; set; }
[DataMember]
public Msp.DsReadIndicators DSReadInidicator { get; set; }
}
[DataContract]
public enum Region
{
[EnumMember]
P2,
[EnumMember]
PROD
}
[DataContract]
public enum RequestType
{
[EnumMember]
None,
[EnumMember]
XmlRequest,
[EnumMember]
SomeOtherRequestType
}
[DataContract]
public struct RequestParameter
{
[DataMember]
public string ParameterName { get; set; }
[DataMember]
public string ParameterValue { get; set; }
}
Thanks.
EDIT w/ answer...
The operation was not available via the WCF Test Client because the type MspWebCallType had a property of type Hashtable. Once I removed this property it fixed the issue. Thanks for everyone's help.
The following is a list of features not supported by WCF Test Client:
Types: Stream, Message, XmlElement, XmlAttribute, XmlNode, types that
implement the IXmlSerializable interface, including the related
XmlSchemaProviderAttribute attribute, and the XDocument and XElement
types and the ADO.NET DataTable type.
Duplex contract.
Transaction.
Security: CardSpace , Certificate, and Username/Password.
Bindings: WSFederationbinding, any Context bindings and Https binding,
WebHttpbinding (Json response message support).
Source: MSDN
Check Msp.FavReadViews and Msp.DsReadIndicators to ensure they comply.
It might be because Request needs to have a public non-parametric constructor.
Answering here as this is the first result on Google currently for this error:
In addition to #Igby Largeman 's answer, you will also receive this error if somewhere in your operation or data contracts, you have used a type that is not serializable.
Take an example of the Exception class in .NET...
I had a case whereby a developer on my team had opted to send back the Exception object to the service's client via a DTO, rather than put the exception message into the DTO manually. Visual Studio will not warn you at build time (it should, really), that the class is not serializable, it will only fail at runtime.
So if you are receiving this error and have ruled out the answer above, ensure you check the types used in your contracts and DTOs; something not being serializable could be your culprit.
I hope this saves someone some time.
I had the same error and the problem was that the class had an System.Drawing.Image property. I remove it from the class and it worked. I convert the byte array to a base64 string.
I'm using Openrasta framework. I've simple POCO which is used in my API and this will be sent as ResponseResource to client. It looks like below:
Public class User
{
Public int Id { get; set; }
Public string Name { get; set; }
Public string Code { get; set; }
}
When sending response to user I dont want to send property "Id" back to the user. How can I make openrasta serialzers to ignore this property? I tried putting XmlIgnore attribute for this property but it didn't work.
Any ideas?
Since [XmlIgnore] isn't working, I am guessing you are using either the Json or XmlDataContract codecs. These are based on DataContractSerializer, in which case the mechanism to control the serialization is to mark the type as [DataContract], at which point inclusion becomes opt in rather than automatic, i.e.
[DataContract]
public class User
{
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Code { get; set; }
}