在ASP.NET MVC中的查询字符串中使用DateTime创建ActionLink

时间:2010-01-07 17:54:15

标签: asp.net-mvc

我有一个带有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并使用Reflector在System.Web.Routing中进行探索,似乎是因为它使用了InvariantCulture,所以我无能为力。

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

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

7 个答案:

答案 0 :(得分:4)

鉴于该框架似乎是硬编码的,以便使用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上重现这些成员,包裹内部{ {1}}或更改所有代码以使用DateTime Value

答案 1 :(得分:2)

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

示例:

Year [ ] Month [ ] Day [ ]

我总是按顺序提供年,月,日的单独文本框,以便美国格式(月/日/年)与世界其他格式(日/月)之间不会产生混淆/年)。

答案 2 :(得分:1)

您可以在ActionLink中提供格式化日期吗?试试这个:

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

当然这会将BeginDate更改为字符串而不是DateTime ...但是这可能会对你有用吗?

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

poking around in System.Web.Routing using Reflector it
     

似乎是因为它使用了   InvariantCulture的

你真的对此感到害羞吗?我检查了Modelbinding和UrlBuilding的部分使用了CurrentCulture。你能看看在渲染链接之前设置CurrentCulture会发生什么吗?

答案 6 :(得分:1)

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

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