从以 UTC-X 时区启动的程序中使用 SharpSVN.GetLog 时出现 SVN_ERR_RA_DAV_REQUEST_FAILED

问题描述 投票:0回答:1

我正在使用 SharpSvn NuGet 包(版本 1.14003.272)通过 https 访问 SVN 服务器。

注意:我的电脑设置为自动调整夏令时(夏令时)时间,我假设服务器(运行 Windows Server)也这样做。因此,当我说某件事使用时区 CET (UTC+1) 或 ET (UTC-5) 时,此时实际上可能是 CEST (UTC+2) 或 EDT (UTC-4)。

我的计算机(位于德国)的默认时区为 CET。这大概与同样位于德国的服务器相同。

使用默认设置,一切正常。

但是,当我在启动程序之前手动将电脑的时区调整为东部时间 (UTC-5) 时,

SvnClient.GetLog
功能会失败,并显示
SvnRepositoryIOException

此错误仅在程序启动时时区为 UTC-X 时出现,而不是在我选择 UTC 或 UTC+X 时区时出现。

以下是所有相关的异常属性:

HResult: -2146233088
InnerException: null
Message: "Unexpected HTTP status 400 'Bad Request' on '/path/to/repository/!svn/me'"
Source: "SharpSvn"
StackTrace: <see below>
SvnErrorCategory: 35
SvnErrorCode: SVN_ERR_RA_DAV_REQUEST_FAILED (175002)

这是堆栈跟踪:

at SharpSvn.SvnClientArgs.HandleResult(SvnClientContext client, SvnException error, Object targets)
at SharpSvn.SvnClient.InternalLog(ICollection`1 targets, Uri logRoot, SvnRevision altPegRev, SvnLogArgs args, EventHandler`1 logHandler)
at SharpSvn.SvnClient.Log(ICollection`1 targets, SvnLogArgs args, EventHandler`1 logHandler)
at SharpSvn.SvnClient.GetLog(ICollection`1 targets, SvnLogArgs args, Collection`1& logItems)
at [stack of my methods starts here]

我的

App.xaml.cs
看起来像这样:

public partial class App : PrismApplication
{
    protected override void Initialize()
    {  // X
        base.Initialize();

        // [...]
    }

    // [...]
}

我在标有

// X
的行上设置了断点;据我所知,这是程序运行的第一行代码。但不归路的关键更早,就在框架的启动代码中的某个地方:

  • 计算机的时区是UTC或UTC+X。我启动程序,在第
    X
    行中命中断点,将时区更改为 UTC-X,继续执行 -
    GetLog
    有效。
  • 时区为 UTC-X。我开始,点击断点
    X
    ,更改为 UTC 或任何 UTC+X,继续 -
    GetLog
    失败。

以下是我在尝试查找失败点时所做的一些观察:

  • 我在使用SharpSvn.1.9-x64时遇到了同样的错误;我更新到 SharpSVN 希望能够以这种方式修复错误,但不幸的是它没有帮助。
  • UTC+14/3/2/1/0 和 UTC 本身都可以工作,UTC-1 和 UTC-5 则不能。
  • 该存储库已有 2 年多历史,因此 UTC-X 引用的时间点并不是该存储库尚不存在。
  • 随时可以从右键菜单中使用 TortoiseSVN 的“显示日志”。
  • 执行“签出”或“更新”而不是“显示日志”是有效的,无论任何时区的恶作剧如何。
  • 使用 https 或 http 进行请求并没有什么区别。
  • 我用两个不同的服务器尝试过。

此时,我什至不知道该看哪里,因为我对 WebDAV 不太了解,也无法解释为什么时区设置只在应用程序启动期间重要,以及为什么它只对

GetLog
重要,但是不是其他命令。

c# timezone webdav sharpsvn
1个回答
0
投票

我找到了避免此错误的解决方案。

在我自己的

SvnGetLog
方法中,代码正在创建一个“所有修订版”
SvnRevisionRange
,本质上是这样的:

var range = new SvnRevisionRange(DateTime.MinValue, DateTime.MaxValue);

但是,

DateTime.MinValue
DateTime.MaxValue
属于
DateTimeKind.Unspecified
而不是
DateTimeKind.Utc

有多种方法可以创建有效的

SvnRevisionRange

  • DateTime.MinValue
    替换为
    new DateTime(DateTime.MinValue.Ticks, DateTimeKind.Utc)
    ,并对
    DateTime.MaxValue
    执行相同操作。
  • 使用
    1970-01-01 00:00:00 Unspecified
    作为
    from
    而不是框架的
    DateTime.MinValue
    0001-01-01 00:00:00 Unspecified
  • 使用
    new SvnRevisionRange(SvnRevision.Zero, SvnRevision.Head)
    (对我来说不是一个选项,因为所需的 API 有
    DateTime
    参数)

我无法真正提供明确的解释内部发生了什么,但我可以想象这样的事情:

在应用程序启动期间,.NET 框架存储运行时环境的时区,并随后使用它将

Unspecified
时间戳转换为本地时间或 UTC(基本上是“有根据的猜测”)。

当我从在 UTC 或 UTC+X 环境中启动的程序发送从

MinValue
开始的请求时,将该时间戳转换为 UTC 会将其保留在该日期,甚至将其向后移动到 0 年。也许这会触发捕获这些值并假设“开始”而不使用实际日期值的特殊情况。

但是,当我在 UTC-X 启动时,

MinValue
会转换为
hour X of day 0001-01-01
,它不是 0 或负数,因此特殊情况不会触发。这可能会导致 SVN 实际上尝试根据该日期值进行一些实际计算,这会导致错误,因为它超出了 UNIX 时间,或者导致下溢,导致
from > to
或类似的情况。

正如我所说,我完全不确定它是如何工作的以及会发生什么,但它适合所有症状。最重要的是,使用

DateTimeKind.Utc
而不是
DateTimeKind.Unspecified
解决了我的问题。

© www.soinside.com 2019 - 2024. All rights reserved.