1

WebAPIによって自動的にシリアル化されるオブジェクトがありますが、データにコンテキストを提供するためにオブジェクトをラップしたいと思いました。例は次のとおりです。

public class SecureModel<T>
{
  public string Info { get; set; }
  public T Data { get; set; }
}

これにより、JSONリクエストで問題なくシリアル化/逆シリアル化でき、すべて問題ありません。ただし、リクエストの実行を終了する前に、その情報の一部を確認したいので、POSTのパラメーターを取得する場所にActionFilterを追加しました。

public class MyAuth : System.Web.Http.Filters.ActionFilterAttribute
{
  public override void OnActionExecuting(HttpActionContext actionContext)
  {
    var arg = actionContext.ActionArguments.FirstOrDefault().Value;
    // arg: get the Info?
    // if the info isn't correct, return a specific Response.
  }
}

引数を調べると、まさにそれが必要ですが、実際のジェネリック型を指定せずに、SecureModelに弱く型付けする方法を理解することはできません。これをSecureModel<object>にケースに入れて、ルートに適切にアクセスできるはずですが、それは許可されていません。これまでのところ、使用する必要のあるデータのみを取得できます。

var notStrongEnough = arg.GetType().GetProperty("Info");

ただし、これにはReflectionを使用したくないので、答えがないまま前進するのに苦労しています。この状況での私の代替案は、データを文字列に変更し、JSONオブジェクトを手動でシリアル化/逆シリアル化することですが、MVC3でWebAPIを使用する目的の一部が無効になります。

注: 基本クラスとしてSecureModelを使用するように設計を変更すると、データに対して実行しているハッシュの一部に課題が追加されるため、そのパスをたどらないようにします。

ありがとう!

編集:誤ったタイトル。

4

2 に答える 2

3

C#でのこの種の問題の一般的な解決策は、ジェネリック型が実装する非ジェネリックインターフェイスを作成することです。たとえば、クラスでは次のようになります。

public class SecureModel<T>
{
    public string Info { get; set; }
    public T Data { get; set; }
}

インターフェイスを定義できますISecureModel

public interface ISecureModel 
{
    string Info { get; }
    object Data { get; }
}

そして今、あなたはそれをあなたのデータクラスに実装することができます:

public class SecureModel<T> : ISecureModel
{
    public string Info { get; set; }
    public T Data { get; set; }

    object ISecureModel.Data {
        get { return Data; }
    }
}

プロパティの非ジェネリック()バージョンobjectとジェネリック( )バージョンが衝突するため、ここでは明示的なインターフェイス実装を使用します。TData

これで、情報を取得するには、にキャストするだけですISecureModel

于 2012-05-29T16:42:02.300 に答える
1

個人的には、型指定されていない個別のインターフェースを作成して実装することを選択します。

interface IObjectTypeSercureModel
{
    object GetData();
    string GetInfo();
}

ただし、ゲッターとセッターを別々のインターフェイスに分割できる場合は、C#テンプレートの共分散機能を使用できます。

public interface IReadModel<out T>
{
    T Data {get;}
    string Info { get; }
}
public interface IWriteModel<in T>
{
    T Data { set; }
    string Info { set; }
}
public class SecureModel<T> : IReadModel<T>, IWriteModel<T>
{
    public string Info { get; set; }
    public T Data { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var m = new SecureModel<string>();
        m.Data = "test";

        IReadModel<object> genericRead = (IReadModel<object>)m;
        Console.WriteLine(genericRead.Data);
    }
}
于 2012-05-29T16:41:48.453 に答える