所以我有一个模型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本身包含PartitionKey
,RowKey
,Etag
和Timestamp
等字段,这些字段也被序列化。
如何继续使用Azure表,但避免在响应中序列化这些我不希望用户看到的不需要的字段。
答案 0 :(得分:6)
不同意使用特定DTO的答案,但Microsoft.WindowsAzure.Storage程序集现在提供了一个属性IgnorePropertyAttribute
,您可以使用它来装饰公共属性以避免序列化。
我还没有真正尝试过但是TableEntity
上有一个名为ShouldSkipProperty()
的方法在返回false
之前会检查很多事情(即不要跳过):< / p>
看起来它会起作用。
答案 1 :(得分:2)
我建议使用DTO(数据传输对象)来解决此类问题。 DTO可能意味着更多代码(更多类),但从长远来看会使您受益。您可以更好地控制将要放在线上的内容。从安全角度来看,它们也更好,而不是使用一些特定于序列化程序的属性来控制线路上的内容。
有关更多信息,请参阅this asp.net web API教程。
答案 2 :(得分:1)
使用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,这样就可以准确地返回所需的对象。
答案 3 :(得分:1)
您不需要继承TableEntity类。您可以使用TableEntity.Flatten方法从Subscription类创建DynamicTableEntity并写入表存储。当您从azure表存储中读取DynamicTableEntity时,可以使用TableEntity.ConvertBack方法重新构建订阅对象。 Azure Table Storage SDK版本&gt; = 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和业务数据模型之间进一步编写转换器类