【问题标题】:OData Function with DateTimeOffset? parameter带有 DateTimeOffset 的 OData 函数?范围
【发布时间】:2015-09-10 11:57:12
【问题描述】:

我正在尝试实现一个接收两个 DateTimeOffset 的 OData 集合函数?参数(MinSentOn 和 MaxSentOn),并将从 Orders 表返回一些摘要信息,但是当我传递 DateTimeOffset 的时间部分时遇到路由问题,收到 HTTP 错误 500.0 - 内部服务器错误直接来自 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 路径并解决我遇到的一些路由问题,直到我碰到这堵墙,例如点或双转义(更改有 cmets):

<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 收到内部服务器错误(附图像)。似乎它试图解析为文件而不是控制器,问题出在哪里。

最终,我知道我可以将参数作为字符串接收并自己进行解析,但我想在不使用“锤子”的情况下实现它:)

【问题讨论】:

    标签: c# asp.net-web-api odata


    【解决方案1】:

    我认为您可以将 参数别名 用于 DateTimeOffset 参数值。

    例如:

    http://localhost:58806/odata/Order/D.ToExecutiveSummary(MinSentOn=null,MaxSentOn=@p)?@p=2015-08-10%2000:00:00.0000%2B01:00

    在下面的Uri中,你可以找到很多参数别名的例子: 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 APi@github 上进行跟踪

    谢谢。

    【讨论】:

    • 我发现了问题!我传递了错误的格式(缺少 T)并且服务器没有正确解析它。您的建议使我走上了正确的道路,因为它作为查询字符串参数仍然失败。另外:不知道 OData 支持的参数别名,非常感谢!
    【解决方案2】:

    我终于找到问题了!它与我使用的DateTimeOffset 格式有关。我忘记了 T,写了2015-08-10 00:00:00.0000%2B01:00 而不是2015-08-10T00:00:00.0000%2B01:00,它无法正确解析。 让我感到困惑的是 IIS 抛出了内部服务器错误而不是一些错误的请求或未找到,并且因为没有调用应用程序异常处理程序,所以我认为格式没问题,但 IIS 的路径有一些问题有不寻常的字符.

    @Sam Xu 的建议引导我走上正确的道路,因为即使使用别名(我不知道 OData 支持参数别名 - 谢谢!)它仍然抛出异常......

    最终还是我的失败,即使服务器的响应应该更有启发性......

    【讨论】:

      【解决方案3】:

      您需要像这样将其转换为 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

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多