4

所以我有一個型號Subscription從Azure的TableEntity類繼承使用的的WebAPI獲取方法如下:防止Azure的TableEntity財產正在連載中的MVC 4的WebAPI

[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我不想被序列化響應(並且由於它們不是在選擇的查詢,它們是空反正),但TableEntity本身具有諸如PartitionKeyRowKeyEtag,並Timestamp其也被序列化領域。

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

回答

1

我會建議使用DTO(數據傳輸對象)來解決這類問題。 DTO可能意味着更多的代碼(更多類),但是從長遠來看,這會對您有所幫助。你對電線的控制要好得多。他們是從安全角度也更好,而不是使用一些特定的序列化的屬性來控制什麼被提上了線。

參考this asp.net網站API教程更多。

+0

這和我所做的唯一區別是DTO繼承自TableEntity,這是我需要爲了與Azure存儲表集成。 – 2013-03-19 02:43:59

+1

我沒有看到DTO繼承後端實體對象的原因。你應該有兩種類型代表你的表的模型類型,在你的情況下'訂閱',它繼承'TableEntity'。然後,您將擁有一個'SubscriptionDto',它不得繼承'TableEntity'並且包含您想通過您的Web API公開的字段/屬性。 – 2013-03-19 18:05:59

5

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

我還沒有真正嘗試過,但有一個名爲ShouldSkipProperty()TableEntity一個方法返回false之前檢查了一些東西(也就是不要跳過):

  • 爲屬性名稱之一「PartitionKey」, 「RowKey」, 「時間戳」 或 「ETag的」 - >跳過
  • 是getter和setter非公任 - >跳過
  • 它是靜態的 - >跳過
  • 是否擁有房產屬性IgnorePropertyAttribut Ë - >跳過

看起來像它會做的伎倆。

0

使用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派生的對象,但由於所有屬性都爲空(顯式地選擇列你想)上有沒有額外的數據線。然後投影到您的DTO中,以便您可以準確返回所需的對象。

0

您不需要從TableEntity類繼承。您可以使用TableEntity.Flatten方法從您的Subscription類創建一個DynamicTableEntity並寫入表存儲。當您從Azure表存儲讀取DynamicTableEntity時,可以使用TableEntity.ConvertBack方法重新構建您的訂閱對象。這些靜態輔助方法在Azure Table中存儲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 S之間轉換器類和業務數據模型