簡體   English   中英

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

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

所以我有一個模型Subscription ,它繼承自Azure的TableEntity類,用於WebApi Get方法,如下所示:

[HttpGet]
public IEnumerable<Subscription> Subscribers()

在這個方法中,我在我的訂閱者表上執行Select查詢以查找所有訂閱者,但我只想返回一些列(屬性),如下所示:

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

該模型的定義如下:

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

以下是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>

正如您所看到的,該模型不僅具有一些其他屬性,例如SubscriberGUID ,我不希望在響應中序列化(並且因為它們不在select查詢中,所以它們無論如何都是null),但TableEntity本身有字段例如PartitionKeyRowKeyEtagTimestamp也被序列化。

如何繼續使用Azure表,但避免在響應中序列化這些我不希望用戶看到的不需要的字段。

不同意使用特定DTO的答案,但Microsoft.WindowsAzure.Storage程序集現在提供了一個屬性IgnorePropertyAttribute ,您可以使用它來裝飾公共屬性以避免序列化。

我還沒有真正嘗試過,但TableEntity上有一個名為ShouldSkipProperty()的方法, TableEntity在返回false之前檢查一些事情(即不要跳過):

  • 屬性名稱是“PartitionKey”,“RowKey”,“Timestamp”還是“ETag” - > skip
  • 對於getter和setter是非公開的 - >跳過
  • 它是靜態的 - >跳過
  • 該屬性是否具有屬性IgnorePropertyAttribute - > skip

看起來它會做的伎倆。

我建議使用DTO(數據傳輸對象)來解決這類問題。 DTO可能意味着更多代碼(更多類),但從長遠來看會使您受益。 您可以更好地控制將要放在線上的內容。 從安全角度來看,它們也更好,而不是使用一些特定於序列化程序的屬性來控制線路上的內容。

有關更多信息,請參閱 asp.net Web API教程。

使用DTO是可行的方法,恕我直言,但要澄清,因為從帖子中不那么明顯是在哪里實施DTO 我希望我可以將它用作查詢的一部分,我不能。 相反,我必須這樣做:

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();

您必須從TableQuery返回TableEntity派生對象,但由於所有屬性都為null(從顯式選擇所需的列),因此線上沒有其他數據。 然后,您可以投影到DTO中,這樣您就可以准確地返回所需的對象。

您不需要繼承TableEntity類。 您可以使用TableEntity.Flatten方法從Subscription類創建DynamicTableEntity並寫入表存儲。 當您從azure表存儲中讀取DynamicTableEntity時,可以使用TableEntity.ConvertBack方法重新構建訂閱對象。 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

無需在DTO和業務數據模型之間進一步編寫轉換器類

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM