I'm trying to implement an OData collection function that receives two DateTimeOffset? parameters (MinSentOn and MaxSentOn) and will return some summary information from an Orders table, but I'm having routing problems when I pass the time part of the DateTimeOffset, receiving an HTTP Error 500.0 - Internal Server Error directly from IIS, because it seems it's trying to reach a file and not the controller itself.
This is my current OData configuration:
odataBuilder.Namespace = "D";
var fc =
odataBuilder.EntityType<Order>().Collection
.Function("ToExecutiveSummary")
.Returns<ExecutiveSummary>();
fc.Parameter<DateTimeOffset?>("MinSentOn");
fc.Parameter<DateTimeOffset?>("MaxSentOn");
This is the function in my controller:
[HttpGet]
public async Task<IHttpActionResult> ToExecutiveSummary(DateTimeOffset? minSentOn, DateTimeOffset? maxSentOn, CancellationToken ct)
{
return await _uow.ExecuteAndCommitAsync(async () =>
{
var query = _uow.Orders.Query();
if (minSentOn != null) query = query.Where(e => e.SentOn >= minSentOn.Value);
if (maxSentOn != null) query = query.Where(e => e.SentOn <= maxSentOn.Value);
// TODO needs optimization, test only
var executiveSummary =
query.Select(e =>
new ExecutiveSummary
{
TotalOrders = query.Count(),
TotalProducts = query.Sum(ex => ex.Quantity),
TotalPharmacies = query.GroupBy(ex => ex.Pharmacy.Id, ex => ex.Pharmacy.Id).Count()
}).FirstOrDefault();
return Ok(executiveSummary);
}, ct);
}
Snippet of the web.config changes to support the OData path and solve some routing problems I faced until I hit this wall, like dots or double escapes (changes have comments):
<configuration>
<!-- ... -->
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<!-- Removed : and % from the path filter -->
<httpRuntime targetFramework="4.5.2" requestPathInvalidCharacters="<,>,*,&,\,?"/>
<globalization uiCulture="pt-PT" culture="pt-PT" />
</system.web>
<!-- ... -->
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<!-- to support the dot (.) for functions or actions -->
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="/*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<security>
<!-- to support double escapings, like 2015-08-10%2000:00:00.0000%2B01:00 -->
<requestFiltering allowDoubleEscaping="true"/>
</security>
</system.webServer>
<!-- ... -->
</configuration>
Now, during my testings, I'm facing the following:
If I don't pass the time part (example: http://localhost:58806/odata/Order/D.ToExecutiveSummary(MinSentOn=null,MaxSentOn=2015-08-10) ) the request reaches my code without any problem, making me believe that there aren't any problem with the OData configuration and route. But when I include the time part (example: http://localhost:58806/odata/Order/D.ToExecutiveSummary(MinSentOn=null,MaxSentOn=2015-08-10%2000:00:00.0000%2B01:00) ) I receive an Internal Server Error (image attached) directly from the IIS. It seems it is trying to resolve to a file instead to the controller, whence the problem.
Ultimately, I know I could receive the parameters as strings and make the parse myself, but I would like to implement this without using the "hammer" :)