ASP.NET MVC-パラメーターをコントローラーに渡す


105

次のようなアクションメソッドを持つコントローラーがあります。

public class InventoryController : Controller
{
    public ActionResult ViewStockNext(int firstItem)
    {
        // Do some stuff
    }
}

そしてそれを実行すると、次のエラーが表示されます。

パラメーターディクショナリに、パラメーター 'firstItem'のタイプ 'System.Int32'の有効な値が含まれていません。パラメータをオプションにするには、その型を参照型またはNullable型にする必要があります。

ある時点で機能していたため、パラメーターなしで関数を試すことにしました。コントローラーが永続的ではないことがわかったので、パラメーターを元に戻しましたが、メソッドを呼び出すときにパラメーターを認識できなくなりました。

このURL構文を使用してアクションを呼び出しています。

http://localhost:2316/Inventory/ViewStockNext/11

このエラーが発生する理由と、それを修正するために何をする必要があるか?

同じ理由で失敗するクラスに整数を取得する別のメソッドを追加しようとしました。文字列を取るものを追加しようとしましたが、文字列はnullに設定されています。パラメータなしで追加してみましたが、問題なく動作しますが、もちろん私のニーズには合いません。

回答:


106

ルーティングは、に沿って設定する必要があります{controller}/{action}/{firstItem}。あなたがデフォルトとしてルーティングを残した場合は{controller}/{action}/{id}、あなたの中global.asax.csのファイル、あなたはに渡す必要がありますid

routes.MapRoute(
    "Inventory",
    "Inventory/{action}/{firstItem}",
    new { controller = "Inventory", action = "ListAll", firstItem = "" }
);

...またはそれに近いもの。


44
または、「firstItem」の名前を「id」に変更します
カイルトラウバーマン'06

8
さらに、次のようにMapRouteに制約オブジェクトを追加するのが賢明ですnew { firstItem = @"\d" }。この方法では、パラメーターが任意の種類の数値である場合にのみ受け入れられます。次のように、正規表現を好きなように変更したり、小数点以下の桁数を制限したりするnew { firstItem = @"\d{4}" }こともできます。編集:完全に修正されたMapRouteの例:jsfiddle.net/HJRgT
KristianB

86

あなたはfirstItemをidに変更することができ、それは動作します

あなたはglobal.asaxのルーティングを変更できます(私はそれをお勧めしません)

そして、誰もこれに言及しなかったなんて信じられない、あなたは電話をかけることができます:

http://localhost:2316/Inventory/ViewStockNext?firstItem=11

@ Url.Actionでは次のようになります。

@Url.Action("ViewStockNext", "Inventory", new {firstItem=11});

あなたがしていることの種類に応じて、最後がより適切になります。また、ViewStockNextアクションではなく、インデックス付きのViewStockアクションを実行することも検討してください。(私の2セント)


15

Jarret Meyerの回答を言い換えるには、パラメーター名を「id」に変更するか、次のようなルートを追加する必要があります。

routes.MapRoute(
        "ViewStockNext", // Route name
        "Inventory/ViewStockNext/{firstItem}",  // URL with parameters
        new { controller = "Inventory", action = "ViewStockNext" }  // Parameter defaults
    );

その理由は、デフォルトルートは、パラメーターがないか、「id」というパラメーターを持つアクションのみを検索するためです。

編集:ええ、気にしないでくださいジャレットは投稿後にルートの例を追加しました。


8

またはルート属性でそれを行います:

public class InventoryController : Controller
{
    [Route("whatever/{firstItem}")]
    public ActionResult ViewStockNext(int firstItem)
    {
        int yourNewVariable = firstItem;
        // ...
    }
}

このプロパティは、古いMVCバージョンでは機能しない場合があります。
Suat Atan PhD 2017

また、これが機能するためにはroutes.MapMvcAttributeRoutes();、アプリケーションのRegisterRoutes(RouteCollection)メソッド内で呼び出されていることを確認する必要があります(通常はApp_Start \ RouteConfig.csに足場が組まれています)。デフォルトでは存在しない場合があります。
ダニエルスコット

7

Headspringは、アクションの属性のパラメーターにエイリアスを追加できる素晴らしいライブラリを作成しました。これは次のようになります。

[ParameterAlias("firstItem", "id", Order = 3)]
public ActionResult ViewStockNext(int firstItem)
{
    // Do some stuff
}

これにより、異なるパラメーター名を処理するためだけにルーティングを変更する必要がなくなります。ライブラリはまた、複数回の適用をサポートしているため、複数のパラメータースペルをマップできます(パブリックインターフェイスを壊さずにリファクタリングするときに便利です)。

Nugetから入手して、Jeffrey Palermoの記事を読むことができます。



3

ASP.NET Core Tag Helper機能の使用:

<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a>

皮肉なことに、最も短い答えが最良です(これ)。

1

これを達成する別の方法があります(Stephen WaltherのPagerの例でより詳細に説明されています)

基本的に、ビューでリンクを作成します。

Html.ActionLink("Next page", "Index", routeData)

routeDataでは、名前と値のペア(たとえば、routeData ["page"] = 5)を指定でき、コントローラーのIndex関数では、対応するパラメーターが値を受け取ります。あれは、

public ViewResult Index(int? page)

ページを5として渡します。認める必要があります。文字列(「ページ」)が自動的に変数になるのは非常に珍しいことですが、他の言語でもMVCはこのように動作します...


0

「id」が特別に扱われるのは、デフォルトのルートマッピングに追加されるためです。これを変更するには、Global.asax.csに移動すると、次の行が見つかります。

routes.MapRoute ("Default", "{controller}/{action}/{id}", 
                 new { controller = "Home", action = "Index", id = "" });

それを次のように変更します。

routes.MapRoute ("Default", "{controller}/{action}", 
                 new { controller = "Home", action = "Index" });

0

または、パラメータタイプを文字列に変更してから、メソッドで文字列を整数に変換することもできます。私はMVCを使い始めたばかりですが、パラメーターリストにnull許容オブジェクトが必要だと思います。そのようなパラメーターが指定されていないことをコントローラーが他にどのように示しますか?そう...

public ActionResult ViewNextItem(string id)...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.