ASP.NET5 MVC 6 路由,带可选参数/默认参数值

ASP.NET5 MVC 6 routing with optional parameter / default parameter value

我正在 VS2015、C#、ASP.NET5 MVC6 堆栈中构建 Restful 风格 API,但在路由方面遇到了一些麻烦。

我直接在控制器中使用属性:

[HttpGet("machine/{machineId}-{cnt:int}")]
public IActionResult GetReportsByMachineId(string machineId, int cnt)
{
    var item = _reportRepository.GetReportsByMachineId(machineId, 0, cnt);
    if ((item == null) || (!item.Any()) )
    {
        return HttpNotFound();
    }
    return new ObjectResult(item);
}

当我调用 api/report/machine/[machineName]-5 时它工作 - 我从数据库收到 5 文档。

但我想让 cnt 参数可选并具有默认值 - 因此对 api/report/machine/[machineName] 的调用是有效的。

基于 http://stephenwalther.com/archive/2015/02/07/asp-net-5-deep-dive-routing 目前我已经尝试过:

[HttpGet("machine/{machineId}-{cnt:int=10}")] - 控制器没有捕捉到 api/machine/{machineName}(我得到欢迎页面代码)

[HttpGet("machine/{machineId}-{cnt?}")] - 应用无法启动(我什至没有看到 MVC 欢迎页面)

[HttpGet("machine/{machineId}-{cnt:int?}")] - 应用无法启动(如上)

有什么想法吗?

整个控制器的代码(我没有指定任何其他路由): http://pastebin.pl/view/11050284

Optional URI Parameters and Default Values

您可以通过向路由参数添加问号来使 URI 参数可选。如果路由参数是可选的,则必须为方法参数定义一个默认值。

[HttpGet("machine/{machineId}/{cnt:int?}")]
public IActionResult GetReportsByMachineId(string machineId, int cnt = 10) {...}

在这个例子中,api/report/machine/nazwa_maszyny/10api/report/machine/nazwa_maszynyreturn相同的资源。

或者,您可以在路由模板中指定默认值,如下所示:

[HttpGet("machine/{machineId}/{cnt:int=10}")]
public IActionResult GetReportsByMachineId(string machineId, int cnt) {...}

这与前面的示例几乎相同,但应用默认值时的行为略有不同。

  • 在第一个例子("{cnt:int?}")中,默认值 10 被直接分配给方法参数,因此参数将具有这个精确值。

  • 在第二个示例 ("{cnt:int=10}") 中,默认值“10”经历了模型绑定过程。默认模型绑定器会将“10”转换为数值 10。但是,您可以插入自定义模型绑定器,它可能会做一些不同的事情。

我几乎可以正常工作了,当我传递 CompanyID 时 url 有效,但如果我将其留空,它默认为 00000-00000-00000etc。问题是我无法根据函数指定默认 guid。

错误

public async Task<IActionResult> Edit(Guid CompanyId = GetCurrentUserAsync().Result.CompanyId, Guid? id)

这是无效的,因为默认值必须是编译时常量。

有没有一种方法可以默认使用 GetCurrentUserAsync()。Result.CompanyId 而无需检查每个函数 if(CompanyId == Guid.Empty) GetCurrentUserAsync().Result.CompanyId

Startup.cs

routes.MapRoute(name: "areaRoute", template: "{area:exists}/{CompanyId?}/{controller}/{action=Index}/{id?}");

控制器

public async Task<IActionResult> Edit(Guid CompanyId, Guid? id)
{
    if (id == null)
    {
        return NotFound();
    }
    var companyCredential = await _context.CompanyCredential.Where(p => p.CompanyId == CompanyId).SingleOrDefaultAsync(m => m.Id == id);
    if (companyCredential == null)
    {
        return NotFound();
    }
    ViewData["CompanyId"] = new SelectList(_context.Company, "Id", "Id", companyCredential.CompanyId);
    return View(companyCredential);
}