I'm writing a generic report web api in C# and I want to have an optional parameter because some reports require only a report id and primary id and sometimes I need report id, primary id and secondary id.
However currently this works: http://localhost:50505/api/report/4/9981/0
But this doesn't: http://localhost:50505/api/report/4/9981
I don't want to pass a zero because the parameter is not used for report of id 4.
This is the code:
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 });
}
}
}
I need some help advise for this:
public IHttpActionResult Get(int reportId, int primaryId, int? secondaryId = 0)
I've writing secondary ID as an optional parameter but if I try to call this url: http://localhost:50505/api/report/4/9981
I get a 404.
Any advice?
Nick