Asp.net mvc 直接从URL读取值而不嵌入时发生异常

Asp.net mvc 直接从URL读取值而不嵌入时发生异常,asp.net-mvc,Asp.net Mvc,在ASP.NET MVC 4项目中,我有以下简单功能: public string chk(int tmp) { string message = "Stoe.Brose, Genre =" + tmp; return message; } 我从url获取tmp值为:http://localhost:55142/store/chk/8 我得到的不是浏览器中显示的值,而是异常,如下所示: The parameters di

在ASP.NET MVC 4项目中,我有以下简单功能:

   public string chk(int tmp)
    {
          string message = "Stoe.Brose, Genre =" + tmp;
            return message;
    }
我从url获取tmp值为:
http://localhost:55142/store/chk/8

我得到的不是浏览器中显示的值,而是异常,如下所示:

    The parameters dictionary contains a null entry for parameter 'tmp' 
of non-nullable type 'System.Int32' for method 'System.String chk(Int32)'
 in 'MvcApplication3.Controllers.StoreController'. An optional parameter must
 be a reference type, a nullable type, or be declared as an optional parameter.
完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication3.Controllers
{
    public class StoreController : Controller
    {
        public string chk(int tmp)
        {
              string message = "Stoe.Brose, Genre =" + tmp;
                return message;
        }
    }
}

在路由配置(
~/App\u Start/RouteConfig.cs
)中,您有以下行:

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
这将告诉路由系统从何处提取参数。请注意,在操作之后,您告诉它
id
,并告诉它这是一个可选参数。但在控制器中,您需要的是
tmp
。有四种解决方案:


将控制器更改为使用
id
而不是
tmp
,并使
id
为空

public string chk(int? id)
{
    string message = "Stoe.Brose, Genre =" + id;
    return message;
}
routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{tmp}",
                defaults: new { controller = "Home", action = "Index", tmp = UrlParameter.Optional }
            );

public string chk(int? tmp)
   {
       string message = "Stoe.Brose, Genre =" + tmp;
       return message;
   }
public string chk(int? tmp)
{
    string message = "Stoe.Brose, Genre =" + tmp;
    return message;
}

将路由更改为期望
tmp
,并使
tmp
为空

public string chk(int? id)
{
    string message = "Stoe.Brose, Genre =" + id;
    return message;
}
routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{tmp}",
                defaults: new { controller = "Home", action = "Index", tmp = UrlParameter.Optional }
            );

public string chk(int? tmp)
   {
       string message = "Stoe.Brose, Genre =" + tmp;
       return message;
   }
public string chk(int? tmp)
{
    string message = "Stoe.Brose, Genre =" + tmp;
    return message;
}

或者通过查询字符串传递
tmp

/store/chk?tmp=5
并使其可为空

public string chk(int? id)
{
    string message = "Stoe.Brose, Genre =" + id;
    return message;
}
routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{tmp}",
                defaults: new { controller = "Home", action = "Index", tmp = UrlParameter.Optional }
            );

public string chk(int? tmp)
   {
       string message = "Stoe.Brose, Genre =" + tmp;
       return message;
   }
public string chk(int? tmp)
{
    string message = "Stoe.Brose, Genre =" + tmp;
    return message;
}

您还可以使用来告诉它如何映射参数。请注意,属性路由仅在MVC5及以上版本中可用

[Route("chk/{tmp}")]
public string chk(int? tmp)
    {
        string message = "Stoe.Brose, Genre =" + tmp;
        return message;
    }

查看路由的配置方式也可能会有所帮助。(通常在
RouteConfig.cs
App\u Start
文件夹中)。这是我在ASP.NET中的第一个程序。所以剩下的都是VS2013创建的相同代码。我没有改变其他任何事情。此外,当我将参数更改为
string type
时,我能够显示字符串值,并在URL中键入:
http://localhost:55142/store/chk/xyz
尝试将
公共字符串chk(int-tmp)
更改为
公共字符串chk(int-tmp)
。异常已消失,但我仍然看不到数字,即,8将其更改为
id
,而不是
tmp
,这可能是
RouteConfig.cs
中配置的默认值,也是我要求它的原因。我检查了所有解决方案,并且工作正常。你能解释一下为什么在字符串参数的情况下我没有面对这个问题吗?我只是不停地更改变量的名称,它起了作用。@Unbreakable字符串不是空的。它只是空的。因此它不需要抛出异常。这是因为您通过查询字符串传递了
tmp
,并且不需要将字符串更改为null,因为编译器知道如果
tmp
缺失,它可以使用空字符串,因此没有编译异常。如果您像这样通过tmp:
/store/chk/xyz
系统会认为
xyz
id
,而不是
tmp
,然后(假设您的操作方法签名是
公共字符串chk(字符串tmp))
然后
tmp
将为空。@Unbreakable这一切归结为设置路由以匹配操作方法中的参数。参数名称需要匹配,以便它自动将URL段映射到正确的参数,或者您必须通过键/值对(查询字符串)明确说明是否哪个值应该与哪个参数匹配。@Unbreakable我想到了一个基于属性路由的第四个解决方案,并将其添加到我的答案中。我个人使用属性路由,因为我喜欢将路由放在函数旁边。