MVC4 C#传递多参数报错:可选参数需为引用/可空类型排查
我来帮你分析这个问题,其实原因很直观,咱们一步步理清楚:
问题回顾
你原本在MVC4项目里传递单个参数的链接是正常的:
<a href="@Url.Action("MyAction", "Home", new { Id = @ViewBag.id})">@ViewBag.option2</a>
但改成传递三个参数后就报错了,修改后的链接代码:
<a href="@Url.Action("MyAction", "Home", new { Id = @ViewBag.id, Id2 = @ViewBag.grupo, Id3 = @ViewBag.correlativo })">@ViewBag.option2</a>
错误提示明确说参数grupo是null,但你明明确认了参数值非空,这问题出在哪呢?
Message = The parameters dictionary contains a null entry for parameter 'grupo' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult ModificarOrdenInicioFormulario(System.String, Int32, Int32)' in 'GFC_Site.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters
再看你的Action方法和路由配置:
控制器的Action定义:
public ActionResult MyAction(string Id, Int32 grupo, Int32 correlativo)
RouteConfig配置:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapMvcAttributeRoutes(); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
核心错误原因
参数名称不匹配!
你在Url.Action里传递的参数是Id2和Id3,但Action方法里对应的参数名却是grupo和correlativo。MVC的模型绑定是严格按照参数名称来匹配的,它找不到名为grupo和correlativo的传入参数,自然就会报null的错误,而grupo又是非空的int类型,所以直接触发了这个异常。
解决步骤
1. 修正链接中的参数名称
这是最关键的一步,把链接里的参数名改成和Action方法完全一致的,也就是把Id2换成grupo,Id3换成correlativo,修改后的链接代码:
<a href="@Url.Action("MyAction", "Home", new { Id = @ViewBag.id, grupo = @ViewBag.grupo, correlativo = @ViewBag.correlativo })">@ViewBag.option2</a>
这样MVC就能正确把ViewBag里的值绑定到Action的对应参数上了,问题基本就能解决。
2. 路由配置无需额外修改(可选说明)
你的默认路由只定义了id作为可选参数,但没关系——MVC会把路由模板里没定义的参数自动转为查询字符串传递,所以当前的默认路由完全能支持多参数传递,不需要修改。如果之后你想把这些参数放到URL路径里(比如/Home/MyAction/1/2/3这种格式),再添加自定义路由就行,比如:
routes.MapRoute( name: "MyActionRoute", url: "Home/MyAction/{Id}/{grupo}/{correlativo}", defaults: new { controller = "Home", action = "MyAction" } );
不过当前场景下用查询字符串就足够,这一步可以暂时跳过。
3. 验证参数传递(可选调试)
如果你还想确认参数是否真的传递成功,可以在Action里加个调试输出:
public ActionResult MyAction(string Id, Int32 grupo, Int32 correlativo) { // 调试用,查看参数值 System.Diagnostics.Debug.WriteLine($"Id: {Id}, Grupo: {grupo}, Correlativo: {correlativo}"); // 你的业务逻辑代码 return View(); }
运行后查看输出窗口就能确认参数是否正确接收了。
内容的提问来源于stack exchange,提问作者Pablo Tobar

