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

Gaz*_*Gaz 5 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>
Run Code Online (Sandbox Code Playgroud)

所以我有一个带有默认Action(让我们称之为Index)和SearchCriteria参数的Search控制器.

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

public class SearchCriteria
{
    public DateTime BeginDate {get; set;}
    public string SomeOtherCriterion {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

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

Html.ActionLink("Search", "Index", searchCriteria)
Run Code Online (Sandbox Code Playgroud)

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

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

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

And*_*tan 4

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

Route有一个丑陋的选择 - 下载 MVC 源代码并从下至上删除所有有问题的类的代码,ParsedRoute以创建您自己的RouteBase实现来完成您需要的操作。

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

然而,一个更简单的解决方案是更改您的 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

如果您有很多代码使用 SearchCriteria 中 DateTime 实例的成员(例如 .Days 等),那么艰巨的工作可能是:您要么必须在 上重现这些成员,MyDateTime环绕内部DateTime Value,要么更改所有代码以使用.Value.Member