web-dev-qa-db-ja.com

ASP.NET MVCのコントローラーに複数のパラメーターを渡す。また、LINQ-to-SQLでオンザフライクエリを生成する

ASP.NET MVCを学ぶために、基本的な問題管理システムに取り組んでいます。私はそれを立ち上げてかなりまともなレベルまで実行しましたが、問題に遭遇しました。

Openというビューを持つIssueという名前のコントローラーがあります。/Issue/Openは、現在システムにログオンしているすべての未解決の問題をリストします。私はそのようにルートを定義しました:

    routes.MapRoute( 
        "OpenSort",                                                         // Route name
        "Issue/Open/{sort}",                                                // URL with parameters
        new { controller = "Issue", action = "Open", sort = "TimeLogged" }  // Parameter defaults
    );

これは、IssueController.csの次のコードを使用して、これまでのところ正常に機能しています。

public ActionResult Open(string sort)
{            
    var Issues = from i in db.Issues where i.Status == "Open" orderby i.TimeLogged ascending select i;

    switch (sort)
    {
        case "ID":
            Issues = from i in db.Issues where i.Status == "Open" orderby i.ID ascending select i;
            break;

        case "TimeLogged":
            goto default;

        case "Technician":
            Issues = from i in db.Issues where i.Status == "Open" orderby i.Technician ascending select i;
            break;

        case "Customer":
            Issues = from i in db.Issues where i.Status == "Open" orderby i.Customer ascending select i;
            break;

        case "Category":
            Issues = from i in db.Issues where i.Status == "Open" orderby i.Category ascending select i;
            break;

        case "Priority":
            Issues = from i in db.Issues where i.Status == "Open" orderby i.Priority ascending select i;
            break;

        case "Status":
            Issues = from i in db.Issues where i.Status == "Open" orderby i.Status ascending select i;
            break;

        default:
            break;
    }            

    ViewData["Title"] = "Open Issues";
    ViewData["SortID"] = sort.ToString();

    return View(Issues.ToList());
}

これは正常に機能しています(ただし、クエリの定義をスイッチよりも適切に処理する方法はあるのでしょうか?)が、未解決の問題ビューで2つのことを実行できるようにしたいと思います。

  1. 見出しで並べ替え-OK
  2. 特定の見出し(技術者、顧客、カテゴリ、優先度、ステータス)でフィルタリング-??

2つのパラメーターをコントローラーに渡す方法がわからないので、クエリを整理できます。また、クエリをその場で生成する方法を理解していない限り、スイッチで(並べ替えオプションの数)*(フィルターオプションの数)が必要になることに気づきました。

ああ、誰かが私を正しい方向に向けることができますか?乾杯!

27
Rob Burke
  1. ルートから並べ替えを削除します。パラメータなしのルートを使用するだけです。
  2. 並べ替えやフィルターなどのクエリにクエリ文字列パラメーターを追加します。したがって、クエリは次のようになります。

http://example.com/Issue/Open?sort=ID&filter=foo

public ActionResult Open(string sort, string filter)

MVCフレームワークは、クエリ文字列パラメーターから引数を入力します。入力されていない可能性のあるこれらのクエリ文字列パラメーター引数には、必ずnull許容型(文字列など)を使用してください。

これは実際には、URLを記述するための「より正しい」方法だと思います。 URL自体がリソース(未解決の問題)を識別します。クエリ文字列パラメーターは、リソースの表示方法をカスタマイズします。

クエリの数に関しては、クエリ全体を一度に作成する必要がないことに注意してください。 .OrderBy拡張メソッドを使用して、既存のIQueryable <T>を並べ替えることができます。

var Issues = from i in db.Issues where i.Status == "Open" select i;

switch (sort)
{
    case "ID":
        Issues = Issues.OrderBy(i => i.ID);
        break;

    // [...]

    default:
        Issues = Issues.OrderBy(i => i.TimeLogged);
}     
33
Craig Stuntz

任意の数のパラメータが必要な場合は、次のようにすることができます。


public ActionResult Open(){            
   string[] keys = Request.QueryString.AllKeys;
   Dictionary queryParams = new Dictionary();
   foreach (string key in keys)
   {
     queryParams[key] = Request.QueryString[key];
   }
   string sort = queryParams["sort"];
   ...


10
kimsk

これはキムスクの回答へのコメントであるはずですが、何らかの理由でコメントするには私が吟味される必要があるため、間違った場所に投稿する必要があります。

任意の数のクエリ文字列パラメーターを処理するより良い方法は、次のようにActionFilterを使用することです。

_public class QueryStringFilterAttribute : ActionFilterAttribute
{
    public string ParameterName { get; private set; }

    public QueryStringFilterAttribute(string parameterName)
    {
        if(string.IsNullOrEmpty(parameterName))
            throw new ArgumentException("ParameterName is required.");
        ParameterName = parameterName;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var qs = new FormCollection(filterContext.HttpContext.Request.QueryString);

        filterContext.ActionParameters[ParameterName] = qs;

        base.OnActionExecuting(filterContext);
    }
}
_

これで、属性をso [QueryStringFilter("attributes")]のようにアクションに追加でき、クエリ文字列の値をFormCollectionとして渡します。これにより、Requestシングルトンに依存しなくなるため、アクションをより簡単にテストできます。

8
ungood

スイッチの代わりに、Dynamic Linqを使用して次のように言うことができます。

Issues = Issues.OrderBy("Status");

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

1
gurra777

すべてのプロセスについて説明している以下の投稿を確認してください http://www.c-sharpcorner.com/UploadFile/4b0136/editing-multiple-records-using-model-binding-in-mvc/

0
Valynk