传递params对象[]会更改Url.Action生成的URL

时间:2018-04-23 13:28:22

标签: c# asp.net-mvc asp.net-core asp.net-core-mvc

我在许多API方法中使用Url.Action方法来指定当前对象和相关对象的路由。代码如下所示:

public class FooController : BaseController
{
    protected override string ControllerName => "FooController";

    [HttpGet("{id}")]
    public IActionResult GetSingle(int id)
    {
        var entity = base.DbContext.FooEntities.SingleOrDefault(f => f.Id == id);

        var selfUrl = Url.Action(
            action: nameof(GetSingle),
            controller: this.ControllerName,
            protocol: Request.Scheme,
            values: new { id }
        );

        var viewModel = mapper.Map<FooViewModel>(entity, selfUrl);

        return Ok(viewModel);
    }
}

此代码按预期生成URL。

http://localhost:1080/foo/1

由于Request.Scheme属性始终相同且ControllerName是BaseController中的抽象属性,因此我尝试将URL构建方法解压缩到BaseController中,如下所示:

protected string GetActionUrl(string actionName, params object[] values)
{
    return Url.Action(
        action: actionName,
        controller: this.ControllerName,
        protocol: Request.Scheme,
        values: values);
}

并从FooController的GetSingle方法中调用它:

var selfUrl = base.GetActionUrl(nameof(GetSingle), id);

然而,这产生了一个完全不同的URL:

http://localhost:1080/foo?Length=1&LongLength=1&Rank=1&SyncRoot=1&SyncRoot=System.Object%5B%5D&IsReadOnly=False&IsFixedSize=True&IsSynchronized=False

我尝试将id包装到一个新的对象结构中:

var selfUrl = base.GetActionUrl(nameof(GetSingle), id);

这没有多大帮助:

http://localhost:1080/foo?Length=1&LongLength=1&Rank=1&SyncRoot=%7B%20id%20%3D%201%20%7D&IsReadOnly=False&IsFixedSize=True&IsSynchronized=False

导致此行为的原因是什么?我应该如何实现/编码GetActionUrl方法,以便获得所需的结果?

1 个答案:

答案 0 :(得分:2)

模型绑定器显然无法将值识别为参数。您需要某种方法来映射键和值。您可以使用匿名类,但在您的情况下,使用RouteValueDictionary会更容易。

因此,实例化该字典的实例,像往常一样填充它,并将其传递给此方法。