【发布时间】:2018-06-13 02:14:27
【问题描述】:
我正在用 C# 编写一个通用的报表 web api,我想要一个可选参数,因为有些报表只需要一个报表 ID 和主 ID,有时我需要报表 ID、主 ID 和辅助 ID。
但是目前这可行: http://localhost:50505/api/report/4/9981/0
但这不会: http://localhost:50505/api/report/4/9981
我不想传递零,因为该参数不用于 id 4 的报告。
这是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Description;
using IPD_Report.Api.Interfaces.Factories;
using IPD_Report.Dtos.RequestModels;
using IPD_Report.Dtos.ResponseModels;
using IPD_Report.SoapService.Attributes;
using IPD_Report.SoapService.Commands;
using IPD_Report.SoapService.Interfaces.Commands;
namespace IPD_Report.Api.Controllers
{
/// <summary>
/// This controller is used to generate reports based on report ID.
/// </summary>
[RoutePrefix("api/report")]
public class ReportController : ApiController
{
private readonly IReportCommands _reportCommands;
private readonly IDtoFactory _dtoFactory;
public ReportController(IReportCommands reportCommands, IDtoFactory dtoFactory)
{
_reportCommands = reportCommands;
_dtoFactory = dtoFactory;
}
/// <summary>
/// Generic GET request for returning report.
/// </summary>
/// <param name="reportId"></param>
/// <param name="primaryId"></param>
/// <param name="secondaryId"></param>
/// byte[]
[Route("{reportId}/{primaryId}/{secondaryId}")]
[ResponseType(typeof(byte[]))]
[HttpGet]
public IHttpActionResult Get(int reportId, int primaryId, int? secondaryId = 0)
{
var dto = _dtoFactory.GenerateModel(reportId, primaryId, secondaryId);
var stuff = GetAttribute(reportId, dto);
return Ok(stuff);
}
/// <summary>
/// Returns a list of available methods as a string list containing the method ID, method name, and returned filetype
/// </summary>
/// <returns>List<List<string>></returns>
[Route("getReportList")]
[ResponseType(typeof(IEnumerable<ReportTypeModel>))]
[HttpGet]
public IHttpActionResult GetReportList()
{
var methodInfo = typeof(ReportCommands).GetMethods()
.Where(x => x.GetCustomAttributes(false).OfType<MethodId>().Any())
.Select(x => x.GetCustomAttributesData().Select(y => y.ConstructorArguments)).ToList();
var methodList = new List<ReportTypeModel>();
for(var i =0;i<methodInfo.Count;i++)
{
var annotation = (methodInfo.ToList()[i]?.ToList().FirstOrDefault() ?? throw new InvalidOperationException()).ToList();
methodList.Add(new ReportTypeModel
{
Id = int.Parse(annotation[0].Value.ToString()),
Name = annotation[1].Value.ToString(),
Format = annotation[2].Value.ToString()
});
}
return Ok(methodList);
}
private object GetAttribute(int id, BaseModel baseModel)
{
var methodInfo = typeof(ReportCommands).
GetMethods()
.Where(x => x.GetCustomAttributes(false).OfType<MethodId>().Any())
.First(x => x.GetCustomAttributes(false).OfType<MethodId>().First().Id == id);
return methodInfo.Invoke(_reportCommands, new object[] { baseModel });
}
}
}
我需要一些帮助建议:
public IHttpActionResult Get(int reportId, int primaryId, int?secondaryId = 0)
我已将辅助 ID 作为可选参数写入,但如果我尝试调用此 url:http://localhost:50505/api/report/4/9981
我得到一个 404。
有什么建议吗?
尼克
【问题讨论】:
-
在路由模板
[Route("{reportId}/{primaryId}/{secondaryId?}")]中设为可选项 -
@Nkosi 我没有意识到您可以在路由属性中的路由参数中添加一个问号以将其表示为可选。那行得通。
标签: c# asp.net-web-api routing