简体   繁体   English

阻止Azure TableEntity属性在MVC 4 WebAPI中序列化

[英]Prevent Azure TableEntity property from being serialized in MVC 4 WebAPI

So I have a Model Subscription which inherits from Azure's TableEntity class for use in a WebApi Get method as follows: 所以我有一个模型Subscription ,它继承自Azure的TableEntity类,用于WebApi Get方法,如下所示:

[HttpGet]
public IEnumerable<Subscription> Subscribers()

In this method, I do a Select query on my subscribers table to find all subscribers, but I only want to return a few of the columns (properties) as follows: 在这个方法中,我在我的订阅者表上执行Select查询以查找所有订阅者,但我只想返回一些列(属性),如下所示:

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

The definition for the model is below: 该模型的定义如下:

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 XML response of the API query: 以下是API查询的XML响应:

<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 a few additional properties such as SubscriberGUID which I do not want to be serialized in the response (and since they are not in the select query, they are null anyway), but TableEntity itself has fields such as PartitionKey , RowKey , Etag , and Timestamp which are also being serialized. 正如您所看到的,该模型不仅具有一些其他属性,例如SubscriberGUID ,我不希望在响应中序列化(并且因为它们不在select查询中,所以它们无论如何都是null),但TableEntity本身有字段例如PartitionKeyRowKeyEtagTimestamp也被序列化。

How do I continue to use Azure tables but avoid serializing in the response these undesired fields I do not want the user to see. 如何继续使用Azure表,但避免在响应中序列化这些我不希望用户看到的不需要的字段。

Not disagreeing with the answer of using a specific DTO, but the Microsoft.WindowsAzure.Storage assembly now provides an attribute, the IgnorePropertyAttribute , that you can decorate your public property with to avoid serialization. 不同意使用特定DTO的答案,但Microsoft.WindowsAzure.Storage程序集现在提供了一个属性IgnorePropertyAttribute ,您可以使用它来装饰公共属性以避免序列化。

I haven't actually tried it yet but there is a method on TableEntity called ShouldSkipProperty() that checks a number of things before returning false (ie don't skip): 我还没有真正尝试过,但TableEntity上有一个名为ShouldSkipProperty()的方法, TableEntity在返回false之前检查一些事情(即不要跳过):

  • Is the Property Name one of "PartitionKey", "RowKey", "Timestamp" or "ETag" -> skip 属性名称是“PartitionKey”,“RowKey”,“Timestamp”还是“ETag” - > skip
  • Are EITHER of the getter and setter non-public -> skip 对于getter和setter是非公开的 - >跳过
  • Is it static -> skip 它是静态的 - >跳过
  • Does the property have the attribute IgnorePropertyAttribute -> skip 该属性是否具有属性IgnorePropertyAttribute - > skip

Looks like it'll do the trick. 看起来它会做的伎俩。

I would suggest using DTO (data transfer objects) to solve this type of issues. 我建议使用DTO(数据传输对象)来解决这类问题。 DTO's might mean more code (more classes) but would benefit you in the long term. DTO可能意味着更多代码(更多类),但从长远来看会使您受益。 You have much better control as to what would be put on the wire. 您可以更好地控制将要放在线上的内容。 They are better from a security standpoint too rather than using some serializer specific attributes to control what is being put on the wire. 从安全角度来看,它们也更好,而不是使用一些特定于序列化程序的属性来控制线路上的内容。

Refer to this asp.net web API tutorial for more. 有关更多信息,请参阅 asp.net Web API教程。

The use of the DTO is the way to go, IMHO, but to clarify, since it wasn't as obvious from the posts is where to implement to the DTO . 使用DTO是可行的方法,恕我直言,但要澄清,因为从帖子中不那么明显是在哪里实施DTO I was hoping I could have just used it as part of the query, which I could not. 我希望我可以将它用作查询的一部分,我不能。 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 have to return your TableEntity derived object from your TableQuery, but since all the properties are null (from explicitly selecting the columns you want) there is no additional data on the wire. 您必须从TableQuery返回TableEntity派生对象,但由于所有属性都为null(从显式选择所需的列),因此线上没有其他数据。 You then project into your DTO so you can return exactly the object you need. 然后,您可以投影到DTO中,这样您就可以准确地返回所需的对象。

You do not need to inherit from TableEntity class. 您不需要继承TableEntity类。 You can use TableEntity.Flatten method to create a DynamicTableEntity from your Subscription class and write to table storage. 您可以使用TableEntity.Flatten方法从Subscription类创建DynamicTableEntity并写入表存储。 And you can use TableEntity.ConvertBack method to recompose your subscription object when you read the DynamicTableEntity back from azure table storage. 当您从azure表存储中读取DynamicTableEntity时,可以使用TableEntity.ConvertBack方法重新构建订阅对象。 These static helper methods are available in Azure Table Storage SDK version >= 8.0.0 Azure Table Storage SDK版本> = 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 TableEntity.Flatten: https: //msdn.microsoft.com/en-us/library/azure/mt775434.aspx TableEntity.ConvertBack: https ://msdn.microsoft.com/en-us/library/azure/mt775432.aspx

Eliminating the need for you to further write up converter classes between DTO s and Business Data Models 无需在DTO和业务数据模型之间进一步编写转换器类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM