4

したがって、次のように、WebApi Get メソッドで使用するためにSubscriptionAzure のクラスから継承するモデルがあります。TableEntity

[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には、応答でシリアル化したくないなどの追加のプロパティがいくつかあるだけでなく (それらは選択クエリに含まれていないため、いずれにせよ null です)、TableEntity 自体にも次のようなフィールドがあります。 as PartitionKeyRowKeyEtagTimestampも連載中です。

Azure テーブルを引き続き使用しながら、ユーザーに見せたくないこれらの望ましくないフィールドを応答でシリアル化しないようにするにはどうすればよいですか。

4

4 に答える 4

7

特定の DTO を使用するという答えに反対するわけではありませんが、Microsoft.WindowsAzure.Storage アセンブリは、IgnorePropertyAttributeシリアル化を回避するためにパブリック プロパティを装飾できる属性 を提供するようになりました。

私はまだ実際に試していませんが、返される前にいくつかのことをチェックするメソッドがTableEntity呼び出されています(つまり、スキップしないでください):ShouldSkipProperty()false

  • プロパティ名は「PartitionKey」、「RowKey」、「Timestamp」、または「ETag」のいずれかです -> スキップ
  • getter と setter のどちらかが非公開 -> スキップ
  • 静的ですか - >スキップ
  • プロパティに属性があるか IgnorePropertyAttribute -> スキップ

それはトリックを行うように見えます。

于 2014-01-12T05:56:34.530 に答える
2

この種の問題を解決するには、DTO (データ転送オブジェクト) を使用することをお勧めします。DTO はより多くのコード (より多くのクラス) を意味するかもしれませんが、長期的にはメリットがあります。ワイヤーに何が置かれるかについて、はるかに優れた制御が可能です。セキュリティの観点からも、シリアライザー固有の属性を使用して何が送信されるかを制御するよりも優れています。

詳細については、このasp.net Web API チュートリアルを参照してください。

于 2013-03-19T02:35:05.320 に答える
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 に射影します。

于 2015-01-04T18:24:56.850 に答える
1

TableEntity クラスから継承する必要はありません。TableEntity.Flatten メソッドを使用して、Subscription クラスから DynamicTableEntity を作成し、テーブル ストレージに書き込むことができます。また、TableEntity.ConvertBack メソッドを使用して、Azure テーブル ストレージから DynamicTableEntity を読み取るときにサブスクリプション オブジェクトを再構成できます。これらの静的ヘルパー メソッドは、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 とビジネス データ モデルの間のコンバーター クラスをさらに作成する必要がなくなります。

于 2017-03-13T22:51:45.660 に答える