2012-04-09 3 views
4

標準のASP.NET MVC 3コントローラには、次のシグネチャを持つアクションがあります。 public ActionResult Index(int? page, string sort, string sortDir) 私のビューはWebGridを使用しており、 。ダイナミック式APIを使用する場合のASP.NET MVC 3コントローラのアクションパラメータの検証

次へ私は動的表現API(別名動的LINQ)を使用して、パラメータをクエリに変換します。例:

var customerSummary = CustomerManager.CustomerRepository.GetQuery() 
     .OrderBy(sort + " " + sortDir) 
     .Select(c => new CustomerSummaryViewModel() 
        { 
         Id = c.Id, 
         Name = c.Name, 
         IsActive = c.IsActive, 
         OrderCount = c.Orders.Count 
        }) 
     .Skip(page.Value - 1 * 10) //10 is page size 
     .Take(10) 
     .ToList(); 

ゴール

私は何をしたいの(そしておそらく有効なラムダを作成する)ソートするためのパラメータを検証するためにDynamic Expressions API自体を使用することです。例えば、私は彼らがParseExceptionを生み出すかどうかを確認するためにDynamicExpression.Parse()DynamicExpression.ParseLambda()メソッドを使用したいのですが、私はデフォルト(「名前ASCを」昇順名前で例えばソート)との誤ったのparamsを置き換えることができ、その場合には...

問題

問題は、私はParseLambdaを使用して、私は(それが唯一のプロパティ名になります)方向を使用することはできません.OrderByにそれを送りたい場合IQueryable拡張子は文字列のみ を取るということです。例えば、私はこれを行うことができます。

var se = DynamicExpression.ParseLambda<Customer, string>("Name"); // now I can use .OrderBy(se) which is same as .OrderBy(c=>c.Name) 

が、ではなく、この

var se = DynamicExpression.ParseLambda<Customer, string>("Name DESC"); 

要約

I)が1にダイナミックLINQを使用して検証し、2)ソートする(述語を構築したいと思います

)アクションに基づいて、私はDymaic LINQに非常に精通していないよしかし、あなたは次の操作を行うことができます

答えて

0

パラメータ:

var customerSummary = CustomerManager.CustomerRepository.GetQuery(); 

if ("desc".Equals(sortDir, StringComparison.CurrentCultureIgnoreCase)) 
    customerSummary = customerSummary.OrderByDescending(sort); 
else 
    customerSummary = customerSummary.OrderBy(sort); 

var pageNumber = page.GetValueOrDefault(); 
if (pageNumber < 1) 
    pageNumber = 1; 

customerSummary = customerSummary 
    .Select(c => new CustomerSummaryViewModel() 
     { 
     Id = c.Id, 
     Name = c.Name, 
     IsActive = c.IsActive, 
     OrderCount = c.Orders.Count 
     }) 
    .Skip((pageNumber - 1) * 10) 
    .Take(10) 
    .ToList(); 

私のプロジェクトでは(私は生の表現を使用していた以外は)何か似たようなことをしましたが、さらに進んでいます。

class TableViewModel 
{ 
    public string SortColumn { get; set; } 
    public bool IsAsc { get; set; } 
    public int? PageNumber { get; set; } 
} 

を、作業をソートする/すべてのページングを行うヘルパーメソッドを作成しました:

私はこのようなベースのViewModelを作成しました。署名は、このようなものです:

public static IQueryable<T> TableHelper(this IQueryable<T> source, TableViewModel model) { ... } 

と私は私のテーブルコントロールからデータを受信し、要求されたデータの一部を返却する必要がある場合、コントローラのアクションは、次のようになります。一般的なもので、その前後の

public ActionResult Index(TableViewModel model) 
{ 
    var data = _productRepository.AsQueryable().TableHelper(model); 

    ... //Operation on data 
} 

ヘルパーの呼び出しは、フィルタリングやスムージングを自由に適用することができます。

非常に便利です。

私はViewModelを拡張する必要があるとき、それを継承し、新しいメンバーを子モデルに追加します。

UPD:あなたがDLINQ滞在することを決定した場合、次のシグネチャを試してみてください - OrderBy("Name", "ascending");

UPD2:あなたのsortパラメータを検証したい場合は、私が思うに、反射が唯一の一品です。このような何か:

bool doSort = typeof(Product).GetProperty(sort, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy /*Or whatever flags you need*/) != null 

この道を行く、あなたはdoSortがtrueの場合にのみOrderBy/OrderByDescendingロジックを適用する必要があります。それ以外の場合は、並べ替えをスキップするか、既定のロジックを適用します。

私の意見では、コードから必要な機能が増えるほど、DLINQがそれに適しているようです。 PropertyInfoが得られたら、次の合理的なステップはそれを表現に使用することです。一度それをしたら、DLINQの場所はどこですか? :)

私は式と反射コードがアクションで非常に醜いですが、私の場合のようにExtensionMethodの外に移動することに同意します。コントローラの基本クラスのNonActionメソッドでは、それを見て:)

+0

私はダイナミックLINQ(Pew質問として)を使用したいと思います。しかし、それに加えて、あなたの例で "ソート"パラメータをどのように検証するのですか? 「並べ替え」が下敷きモデルの有効なプロパティであることをどうやって確認しますか? :) – zam6ak

+0

私は答えを更新しました(UPD2を参照)。 DLINQで注文するには、私の最初のUPDを見たことがありますか?それはあなたのために働くのですか? – ILya

+0

ところで、間違ったフィールド名を渡すとDLINQはどうなるでしょうか?それは例外を投げるだろうか? – ILya

関連する問題