4

我有一个控制器,其中包含两种不同的 Get 方法。一个int取值,而另一个String取值,如下所示:

public class AccountController : ApiController
{
    public String GetInfoByString(String sUserInput)
    {
        return "GetInfoByString received: " + sUserInput;
    }

    public String GetInfoByInt(int iUserInput)
    {
        return "GetInfoByInt received: " + iUserInput;
    }
}

我的 RouteConfig.cs 保持不变,如下所示:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

我的 WebApiConfig.cs 也没有改变,如下所示:

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

我希望能够通过使用单个链接来访问 Web API,例如:

// Hit GetInfoByInt
http://localhost:XXXX/api/account/1

// Hit GetInfoByString
http://localhost:XXXX/api/account/abc

我可以很好地打第一种情况,但是每当我尝试打第二种情况时,我都会收到以下错误:

<Error>
    <Message>The request is invalid.</Message>
        <MessageDetail>
            The parameters dictionary contains a null entry for parameter 'id' of 
            non-nullable type 'System.Int64' for method  'TestProject.String GetInfoByInt(Int64)' in 'TestProject.Controllers.AccountController'. 
            An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
        </MessageDetail>
 </Error>

有没有办法根据用户提供的是 aString还是a 来点击 Get 方法int?我假设需要在 RouteConfig 或 WebApiConfig 中进行更改,但我不太确定如何解决这个问题。也许这毕竟只是一个简单的解决方案?

另外,如果重要的话,我希望能够使用String包含字母和数字的 GetInfoByString ,例如'ABC123'or '123ABC'。GetInfoByInt 可以类似于'123'

如果可能的话,我真的很想坚持一个控制器,而不是把它分成多个控制器。

提前感谢您的帮助。

4

4 回答 4

4

如果您想将这两个操作分开,这是一种处理方式:

config.Routes.MapHttpRoute("GetAccountInfoByInt", "api/account/{iUserInput}", new { controller = "account", action = "GetInfoByInt" }, new { iUserInput = @"\d+" });
config.Routes.MapHttpRoute("GetAccountInfoByString", "api/account/{sUserInput}", new { controller = "account", action = "GetInfoByString" });

请注意,我们计划在未来通过在 Web API 的下一个版本中引入属性路由来使这种事情变得更容易:

https://aspnetwebstack.codeplex.com/wikipage?title=Attribute%20routing%20in%20Web%20API

如果您愿意使用我们的夜间构建,它应该已经可用。那么你所要做的就是添加几个属性:

[HttpGet("api/account/{sUserInput}")]
public String GetInfoByString(String sUserInput)

[HttpGet("api/account/{iUserInput:int}")]
public String GetInfoByInt(int iUserInput)
于 2013-06-06T18:18:33.603 回答
1

以下代码对我有用,请注意ActionNameHttpGet属性,也不是在您需要为 api定义操作参数的配置中。

public class AccountController : ApiController
{
    [HttpGet]
    [ActionName("GetInfoByString")]
    public String GetInfoByString(String sUserInput)
    {
        return "GetInfoByString received: " + sUserInput;
    }

    [HttpGet]
    [ActionName("GetInfoByInt")]
    public String GetInfoByInt(int iUserInput)
    {
        return "GetInfoByInt received: " + iUserInput;
    }
}

在 Config for Api 中执行相同操作

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapHttpRoute("DrawWebService",
                "api/{controller}/{action}/{value}",
                new { value = System.Web.Http.RouteParameter.Optional });

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}
于 2013-06-07T12:38:17.847 回答
0

克服此限制的一种方法是使用可为空的参数,例如

public ActionResult GetInfo(string sUserInput, int? iUserInput)

...并将您的逻辑限定为非空值。

于 2013-06-06T17:45:15.017 回答
0

一种解决方法是使用可为空的参数或尝试将字符串解析为整数然后限定。

public ActionResult GetInfo(string sUserInput)
{
    var result = sUserInput.IsInt
        ? GetInfoByInt(int.Parse(sUserInput))
        : GetInfoByString(sUserInput)
    return result;
}
于 2016-06-23T14:01:08.933 回答