2015-09-10 2 views
2

Я пытаюсь реализовать функцию сбора данных OData, которая получает два DateTimeOffset? (MinSentOn и MaxSentOn) и вернет некоторую сводную информацию из таблицы Orders, но у меня возникают проблемы с маршрутизацией, когда я передаю временную часть DateTimeOffset, получив сообщение об ошибке HTTP 500. Ошибка внутреннего сервера непосредственно из IIS, поскольку кажется, он пытается достичь файла, а не самого контроллера.Функция OData с функцией DateTimeOffset? параметр

Error thrown by the IIS

Это моя текущая конфигурация OData:

odataBuilder.Namespace = "D"; 
var fc = 
    odataBuilder.EntityType<Order>().Collection 
     .Function("ToExecutiveSummary") 
     .Returns<ExecutiveSummary>(); 
fc.Parameter<DateTimeOffset?>("MinSentOn"); 
fc.Parameter<DateTimeOffset?>("MaxSentOn"); 

Это функция в моем контроллере:

[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); 
} 

Сниппает изменения web.config для поддержки пути OData и решить некоторые проблемы маршрутизации, с которыми я столкнулся, пока не ударил эту стену, как точки или двойные экраны (изменения имеют комментарии):

<configuration> 

    <!-- ...  --> 

    <system.web> 
    <compilation debug="true" targetFramework="4.5.2" /> 

    <!-- Removed : and % from the path filter --> 
    <httpRuntime targetFramework="4.5.2" requestPathInvalidCharacters="&lt;,&gt;,*,&amp;,\,?"/> 

    <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> 

Теперь, во время моих тестирование, я столкнулся следующее:

Если я не передать часть времени (пример: http://localhost:58806/odata/Order/D.ToExecutiveSummary(MinSentOn=null,MaxSentOn=2015-08-10)) запрос достигает мой код без каких-либо проблем, заставляя меня поверить, что нет никаких проблем с конфигурацией и маршрутом OData. Но когда я включаю временную часть (пример: http://localhost:58806/odata/Order/D.ToExecutiveSummary(MinSentOn=null,MaxSentOn=2015-08-10%2000:00:00.0000%2B01:00)), я получаю внутреннюю ошибку сервера (изображение прикреплено) непосредственно от IIS. Кажется, он пытается решить файл вместо контроллера, откуда проблема.

В конце концов, я знаю, что я мог бы получить параметры в виде строк и сделать сам разобрать, но я хотел бы осуществить это без использования «молоток» :)

ответ

2

Я, наконец, нашел проблему! Это было связано с форматом DateTimeOffset, который я использовал. Я забыл Т и написал 2015-08-10 00:00:00.0000%2B01:00 вместо 2015-08-10T00:00:00.0000%2B01:00, и он не мог правильно разобрать. Что меня смутило, так это то, что IIS выбрасывал внутреннюю ошибку сервера вместо некоторого «плохого запроса» или «не нашел», а потому, что обработчик исключений приложений не вызывался, поэтому я предположил, что формат одобрен, но у IIS возникла проблема с тем, персонажи.

Сюй предложение @ Сэм привести меня в правильном пути, потому что, даже используя псевдоним (я не знаю, OData была поддержка параметров псевдонима - спасибо за это) он по-прежнему бросает исключение ...

В конце концов, это был мой провал, даже если ответ сервера был более информативным ...

1

Вы должны бросить его в DateTimeOffset, как это :

cast(2015-08-10%2000:00:00.0000%2B01:00,Edm.DateTimeOffset) 

Источник: https://github.com/OData/WebApi/blob/master/OData/test/E2ETest/WebStack.QA.Test.OData/DateAndTimeOfDay/DateAndTimeOfDayTest.cs#L181

+0

Я все еще получаю 500, не работает. К сожалению, тест на функции с датами не пропускает DateTimeOffset со временем, поэтому я могу попробовать: https://github.com/OData/WebApi/blob/master/OData/test/E2ETest/WebStack.QA.Test .OData/DateAndTimeOfDay/DateAndTimeOfDayTest.cs # L346 –

4

Я думаю, что вы можете использовать псевдоним параметра для значения параметра DateTimeOffset.

Например:

http://localhost:58806/odata/Order/D.ToExecutiveSummary(MinSentOn=null,[email protected])[email protected]=2015-08-10%2000:00:00.0000%2B01:00

В следующем Ури, вы можете найти много примеров параметров псевдонима: https://github.com/OData/WebApi/blob/master/OData/test/UnitTest/System.Web.OData.Test/OData/Formatter/ODataFunctionTests.cs#L24-L43

Кроме того, в http://odata.github.io/WebApi/#04-06-function-parameter-support, вы можете найти простое руководство о параметре функции.

Однако проблема известная проблема, связанная с IIS и отслеживать на odata Web [email protected]

Спасибо.

+0

Я нашел проблему! Я пропускал неправильный формат (отсутствует T), и сервер не разбирал его правильно. Ваше предложение приведет меня к правильному пути, потому что он все еще терпит неудачу как параметр строки запроса. Кроме того: не знал, поддерживает ли псевдоним параметра OData, большое спасибо за это! –

Смежные вопросы