Prevent serialization of Azure TableEntity property in MVC 4 WebAPI

So, I have a Subscription model that inherits from the Azure TableEntity class for use in the Get WebApi method as follows:

 [HttpGet] public IEnumerable<Subscription> Subscribers() 

In this method, I make a Select query in the table of my subscribers to find all the subscribers, but I only want to return a few columns (properties) as follows:

 var query = new TableQuery<Subscription>().Select(new string[] { "PartitionKey", "RowKey", "Description", "Verified" }); 

The definition for the model is as follows:

 public class Subscription : TableEntity { [Required] [RegularExpression(@"[\w]+", ErrorMessage = @"Only alphanumeric characters and underscore (_) are allowed.")] [Display(Name = "Application Name")] public string ApplicationName { get { return this.PartitionKey; } set { this.PartitionKey = value; } } [Required] [RegularExpression(@"[\w]+", ErrorMessage = @"Only alphanumeric characters and underscore (_) are allowed.")] [Display(Name = "Log Name")] public string LogName { get { return this.RowKey; } set { this.RowKey = value; } } [Required] [EmailAddressAttribute] [Display(Name = "Email Address")] public string EmailAddress { get; set; } public string Description { get; set; } public string SubscriberGUID { get; set; } public bool? Verified { get; set; } } 

The following is the response from an XML API request:

 <ArrayOfSubscription> <Subscription> <ETag>W/"datetime'2013-03-18T08%3A54%3A32.483Z'"</ETag> <PartitionKey>AppName1</PartitionKey><RowKey>Log1</RowKey> <Timestamp> <d3p1:DateTime>2013-03-18T08:54:32.483Z</d3p1:DateTime> <d3p1:OffsetMinutes>0</d3p1:OffsetMinutes> </Timestamp> <ApplicationName>AppName1</ApplicationName> <Description>Desc</Description> <EmailAddress i:nil="true"/> <LogName>Log1</LogName> <SubscriberGUID i:nil="true"/> <Verified>false</Verified> </Subscription> </ArrayOfSubscription> 

As you can see, the model not only has several additional properties, such as SubscriberGUID , which I do not want to serialize in the response (and since they are not in the select request, they are still null), but TableEntity has fields like PartitionKey , RowKey , Etag and Timestamp , which are also serialized.

How can I continue to use Azure tables, but avoid serializing in the response these unwanted fields that I do not want to see.

+4
source share
4 answers

I disagree with the answer to using a specific DTO, but the Microsoft.WindowsAzure.Storage assembly now provides an IgnorePropertyAttribute attribute, which you can decorate with your public property to avoid serialization.

I have not tried it yet, but there is a TableEntity method called ShouldSkipProperty() that checks a few things before returning false (i.e. it does not skip):

  • Is the Property Name one of "PartitionKey", "RowKey", "Timestamp" or "ETag" β†’ skip
  • Are the ETERER of the receiver and setter non-public β†’ skip
  • Is it static -> skip
  • Does the property have an attribute IgnorePropertyAttribute -> skip

It seems to work.

+5
source

I would suggest using DTO (data transfer objects) to solve this type of problem. DTO may mean more code (more classes), but will benefit you in the long run. You have much better control over what will be superimposed on the wire. They are better from a security point of view, rather than using some serializer attributes to control what fits in the wire.

Refer to this asp.net web interface API guide for more details.

+1
source

Using DTO is the way, IMHO, but for clarification, since this was not so obvious from the messages where you need to implement DTO . I was hoping I could just use it as part of a request, which I couldn't. Instead, I had to do this:

 query.SelectColumns = new List<string> { "QuoteId", "RateId", "Date" }; var results = await MyCloudTable.ExecuteQuerySegmentedAsync(query, null); return results.Select(d => new MyDto { QuoteId = d.QuoteId, RateId = d.RateId, Date = d.Date }).ToList(); 

You should return your derived TableEntity object from your TableQuery, but since all the properties are null (from the explicit selection of the required columns) there is no additional data on the wire. Then you project into your DTO so that you can return exactly the object you need.

0
source

You do not need to inherit the TableEntity class. You can use the TableEntity.Flatten method to create a DynamicTableEntity from the Subscription class and write to the table store. And you can use the TableEntity.ConvertBack method to rebuild the subscription object when you read DynamicTableEntity back from azure table storage. These static helper methods are available in Azure Table Storage SDK version> = 8.0.0

TableEntity.Flatten: https://msdn.microsoft.com/en-us/library/azure/mt775434.aspx TableEntity.ConvertBack: https://msdn.microsoft.com/en-us/library/azure/mt775432.aspx

Eliminate the need to further write converter classes between DTO and data business models

0
source

All Articles