Ignoring property in a class for response resource - Openrasta - c#

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; }
}

Related

Only return some fields in JSON

I have an API that returns some data of a class in JSON. Is there any way to return only some specific fields of a C# class in JSON?
For example:
class Person {
public int Id{ get; set; }
public string Name { get; set; }
public string Family { get; set; }
public string Gender { get; set; }
}
Person myPerson = new Person();
var Json = (new
{
Person = myPerson
});
return Request.CreateResponse(HttpStatusCode.OK, Json);
It returns ID, Name, Family, Gender. I need to return only the Name and Family. I thought I can create an object and add my specific fields in the class in that object and return object?
Use anonymous types?
return Request.CreateResponse(HttpStatusCode.OK, new {Name = person.Name; Family = person.Family});
You should consider applying the DRY principle.
The DRY principle is not "never write code twice", but rather that "every piece of knowledge must have a single, unambiguous, authoritative representation in the system".
What this means is that you have to build a model that has a meaningful name, contains properties that it actually has, and can be changed as needed later without having to figure out where else in the application it's used. I'm certain you could also find a name that would better represent this area of the application.
Should I create a different model with just the properties I need or
use the same model and have NULL values for the field I don't use? Or just create anonymous type and make this way harder in future?
I don't recommend using the same model for your case, from my understanding of it. It's going to make your life easier down the road if you build a model that has a meaningful name as I said before.
So what should we do? I have seen many people trying to use JsonIgnore in domain model but you should not get down that path. You should avoid using JsonIgnore in domain model. I will give an example for it.
For example:
class Person {
public int Id { get; set; }
public string Name { get; set; }
public string Family { get; set; }
public string Gender { get; set; }
}
So you have this model and you want other models to inherit from it but like in your case you don't want to return Id and Gender, only Name and Family. So you go like this.
class Person {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Family { get; set; }
public virtual string Gender { get; set; }
}
public class PersonNameModel : Person {
[JsonIgnore]
public override int Id { get; set; }
[JsonIgnore]
public override string Gender{ get; set; }
}
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.
But, you can do it with the help of JsonIgnore but this way does not support XML format. So, in case your application has to support XML format more (or only support XML), instead of using Json.Net, you should use [DataContract] which supports both JSON and XML.
Datacontract is a great solution. It gives me a clean REST API. At the same time when I save the data in a no-sql, the ignored properties are persisted despite the objects being stored as json.
[DataContract]
public class Person {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Family { get; set; }
public virtual string Gender { get; set; }
}
public class PersonNameModel : Person {
// included in JSON
[DataMember]
public override string Name { get; set; }
[DataMember]
public override string Family { get; set; }
// other inherited properties will be ignored
}
I will also mention another way of doing it as there are more (custom contact resolver, Web API convention ("ShouldSerialize")...)
Another way you can do it is to decorate your auto property with JsonProperty attribute in order to skip the serialization of that field if it is null.
Example:
class Person {
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? Id { get; set; }
public string Name { get; set; }
public string Family { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Gender { get; set; }
}
Happy coding!

WCF returning serialization exception when using .Net client but not Soap UI

I have an object called Organization that represents different rows in a database table called ORGANIZATION. Some organizations represent merchants and the merchant can have a "MerchantAux" record.
The Organization class looks like this:
[DataContract]
public class Organization : Core.Framework.BaseEntity
{
[Key]
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public virtual MerchantAux MerchantAuxRecord { get; set; }
public Organization()
{
}
}
The MerchantAux class looks like this:
[DataContract]
public class MerchantAux : BaseEntity
{
[Key]
[DataMember]
public int Code { get; set; }
[DataMember]
public int SettlementDelay { get; set; }
[DataMember]
public Nullable<System.Guid> WalletSiteId { get; set; }
[DataMember]
public bool? AddCardNotPresent { get; set; }
[DataMember]
public bool? BatchEmailNotification { get; set; }
[DataMember]
public string CsvEmailRecipients { get; set; }
[IgnoreDataMember]
public virtual ICollection<Organization> Organizations { get; set; }
public MerchantAux()
{
Organizations = new List<Organization>();
}
}
These objects are defined in a Models assembly. The WCF Service Assembly has a ServiceContract and OperationContracts to Get and Save Organizations.
Getting an organization works without issue. Saving an organization is failing with a VERY strange result.
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter boardingservice:organization. The InnerException message was 'The use of type 'MerchantAux' as a get-only collection is not supported with NetDataContractSerializer. Consider marking the type with the CollectionDataContractAttribute attribute or the SerializableAttribute attribute or adding a setter to the property.'. Please see InnerException for more details.
And there is no inner exception.
Oh yeah... Soap UI has no problem calling the Save method, but a .Net client throws the above error. Has anyone else seen this behavior where the serializer thinks that an object is a collection?
For the curious, I did try changing it to CollectionDataContract instead, but of course it fails straight away with an exception saying that MerchantAux doesn't implement IEnumerable (duh). Anyway... any ideas would be great.

WCF object within DataContract

[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!!!

Serialize object into JSON but only include properties with the [DataMember] attribute

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.

In c# how do you make a field name different then when it is serialized?

I have a WCF service that I have built from an XSD from a client. The client XSD calls for a field named 3rdPartyTrackingNumber. Because in c# I can't have a field that starts with a number I have named it ThirdPartyTrackingNumber. Is there a meta tag or something that I can put on the column that will render it as 3rdartyTrackingNumber when serialized?
public class OSSShipmentGroup
{
public string status { get; set; }
public string shipmentNumber { get; set; }
public object shipFrom { get; set; }
public string carrierName { get; set; }
[Some meta tag here]
public string ThirdPartyTrackingNumber {get; set;}
public OSSOrderDates dates { get; set; }
public OSSOrderAddress[] address {get; set;}
public OSSOrderShipmentItem[] containedItems { get; set; }
public OSSShipmentInvoice[] invoice {get; set;}
}
I know I can implement ISerializable and make the changes in GetObjectData, but if it is only one field i was hoping I could just add a meta tag to the field.
It depends on what serializer you are using. For example if you are using DataContractSerializer which is the default in WCF basicHttpBinding and wsHttpBinding you could use the [DataMember] attribute
[DataMember(Name = "ABC")]
public string ThirdPartyTrackingNumber { get; set; }
If you are using XmlSerializer then the [XmlElement] attribute should do the job:
[XmlElement(ElementName = "ABC")]
public string ThirdPartyTrackingNumber { get; set; }
For WCF, the normal process is to annotate the class with [DataContract], an each property with [DataMember], which has an optional Name="foo" property.
Note that by adding the class-level attribute you are saying "I will explicitly tell you which members to serialize; you can't then just annotate the one you want to rename.

Categories

Resources