【问题标题】:Creating an ActionLink with a DateTime in the query string in ASP.NET MVC在 ASP.NET MVC 的查询字符串中创建带有 DateTime 的 ActionLink
【发布时间】:2010-02-12 17:40:06
【问题描述】:

我有一个带有 DateTime 搜索条件以及其他一些条件的搜索表单:

<form method="get" action="/app/search">
    <input type="text" value="13/01/2010" name="BeginDate"/>
    <input type="text" value="blah" name="SomeOtherCriterion"/>
<form>

所以我有一个带有默认操作(我们称之为索引)和 SearchCriteria 参数的搜索控制器。

public class SearchController
{
    public ActionResult Index(SearchCriteria searchCriteria) {//blah }
}    

public class SearchCriteria
{
    public DateTime BeginDate {get; set;}
    public string SomeOtherCriterion {get; set;}
}

现在,如果我想创建一个 ActionLink,传入一个 SearchCriteria 值,那么:

Html.ActionLink("Search", "Index", searchCriteria)

我得到美国格式的 BeginDate 查询字符串参数。在 Google 上查看并在 System.Web.Routing 中使用 Reflector 似乎是因为它使用了 InvariantCulture,所以我对此无能为力。

似乎以前没有人问过这个问题,所以我想我在做一些非常愚蠢的事情......请帮忙!

编辑:将 SearchCriteria 传递给 ActionLink 而不是匿名对象,以说明为什么我不能自己执行自定义 ToString()。

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    鉴于框架似乎是硬编码来使用 InvariantCulture 处理这段数据的,我认为您无法做很多事情来使其透明地工作。

    有一个丑陋的选择 - 下载 MVC 源代码并删除从 RouteParsedRoute 的所有违规类的代码,以创建您自己的 RouteBase 实现来满足您的需求。

    如果我绝对必须SearchCriteria 类上保留 DateTime 声明,那么这就是我会选择的路线(对不起双关语)。

    但是,一个更简单的解决方案是更改您的 SearchCriteria 类,以对 DateTime 字段使用稍微不同的声明,基于如下类型:

    public class MyDateTime
    {
      public DateTime Value { get; set; }
      //for passing MyDateTime in place of a DateTime without casting
      public static implicit operator DateTime(MyDateTime instance) { return instance.Value; }
      //so you can assign a MyDateTime from a DateTime without a cast
      //- e.g. MyDateTime dt = DateTime.Now
      public static implicit operator MyDateTime(DateTime instance) { return new MyDateTime() { Value = instance }; }
      //override ToString so that CultureInfo.CurrentCulture is used correctly.
      public override string ToString()
      {
        return Value.ToString(CultureInfo.CurrentUICulture);
      }
    }
    

    理论上,您应该能够毫不费力地推出此更改。

    如果您有大量代码使用 SearchCriteria 中的 DateTime 实例的成员(例如 .Days 等),那么最重要的工作可能是:您要么必须在 MyDateTime 上重现这些成员,然后围绕内部 DateTime Value或将所有代码更改为使用.Value.Member

    【讨论】:

    • 对我们来说不是很实用,但绝对是最具创造性的解决方案,所以我会接受。谢谢佐尔坦。
    【解决方案2】:

    为避免与区域设置和“文化”相关的问题, 我将日期和时间视为单独的未绑定字段,然后 在我的控制器中将它们组装到 DateTime 中。

    例子:

    Year [ ] Month [ ] Day [ ]

    我总是按顺序显示年、月和日的单独文本框,这样美国格式(月/日/年)和世界其他地区的格式(日/月)之间就不会混淆/年)。

    【讨论】:

      【解决方案3】:

      您能否在 ActionLink 中提供格式化的日期?试试这个:

      Html.ActionLink("Search", 
                      "Index", 
                      new {BeginDate = 
                            DateTime.Now.ToString("d", new CultureInfo("pt-BR");})
      

      当然,这会将 BeginDate 更改为字符串而不是 DateTime……但也许这对您有用?

      【讨论】:

      • 查看编辑。我希望能够直接传递 SearchCriteria 而不是使用匿名对象。我知道我在问题中遗漏了一些东西!
      • 啊,这有点难。我想你总是可以匿名 SearchCriteria 只是为了格式化日期字符串,但这将是一个巨大的痛苦......
      • 有人对你投了反对票。猜猜你不在乎 23000 点,但无论如何它似乎很苛刻。我赞成补偿。
      【解决方案4】:

      为此,我们使用 ISO(格式字符串中的“s” -- YYYY-MM-DDTHH:MM:SS)格式。它工作正常,JavaScript 也可以处理它。

      【讨论】:

      • 但是如何获取 ActionLink 或任何其他使用 RouteValueDictionary 将 DateTime 转换为这种格式的 MVC 方法?
      • 只要把它作为一个字符串:new RouteValueDictionary(new { SomeDate = anotherDate.ToString("s") })
      【解决方案5】:

      也许您可以使用Model Binder 来格式化和解析日期?只是重新阅读这篇文章并注意到它没有格式化日期......可能不会成功。我会留下答案,以防它提供任何无意的灵感:)

      【讨论】:

      • 谢谢克里斯。仅适用于处理传入请求的 AFAIK,无助于使用 ActionLink 创建 URL。
      【解决方案6】:
      poking around in System.Web.Routing using Reflector it
      

      似乎是因为它使用 不变的文化

      你真的对此感到不安吗?我检查的 Modelbinding 和 UrlBuilding 的部分使用了 CurrentCulture。如果您在呈现链接之前设置 CurrentCulture,您能否检查会发生什么?

      【讨论】:

      • 我正在查看的位是 System.Web.Routing.ParsedRoute.Bind。在底部,它将任何“未使用的值”放入查询字符串中。 (尽管此方法中的每个 ToString 都使用 InvariantCulture。)我尝试设置 CurrentCulture。它没有帮助。
      【解决方案7】:

      获取由 Scott Hanselman、Scott Guthrie、Phil Haack 和 Rob Conery 编写的 ASP.NET MVC 1.0 书籍。他们实际上在书中做了这个确切的场景。他们使用特定的路线。我现在正在查看第 216 页。

      他们通过分解日、月和年来做到这一点。然后,您有责任在这些值返回时使用它们。

      【讨论】:

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