我有一个列出记录列表的索引视图。我有2个datepicker字段(FromDate,ToDate),我用它来允许用户过滤列表中的数据。用户第一次访问该页面时,FromDate和ToDate中的值没有传递给操作
Index(DateTime? fd, DateTime? td)
所以我使用默认值
fromDate = DateTime.Today.AddDays(-7); // and
toDate = DateTime.Today.AddDays(14);
使用默认数据加载索引视图后,用户现在可以使用日期字段更改日期范围。每次用户点击搜索时,我都会使用url将2个日期字段中的值传递给控制器中的Index操作。但是,第一个值(fd)不会传递给控制器。第二个值(td)正确传递给控制器。我做错了什么?或者有更好的方法/最佳实践来做到这一点?
我的索引视图:
<a id="btnSearch" class="btn btn-info" href="/Slide/Index/?fd=@ViewBag.FromDate.ToString("dd-MM-yyyy")&td=@ViewBag.ToDate.ToString("dd-MM-yyyy")"> Search </a>
<div class="input-group date">
<span>From: </span>@Html.TextBox("FromDate", (DateTime)ViewBag.FromDate, new { @class = "col-md-6", @style="width:80px" })
</div>
<div class="input-group date">
<span>From: </span>@Html.TextBox("ToDate", (DateTime)ViewBag.ToDate, new { @class = "col-md-6", @style="width:80px" })
</div>
<div class="row">
<table class="table table-hover" style="width:auto" id="sTable">
//this is where I list the result data here....
</table>
</div><!--End of row-->
我的路线:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Slide",
url: "Slide/Index/{fd}/{td}",
defaults: new { controller = "Slide", action = "Index", fd = UrlParameter.Optional, td = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
行动方法:
public ActionResult Index(DateTime? fd = null, DateTime? td = null)
{
DateTime fromDate;
DateTime toDate;
if (!fd.HasValue)
fromDate = DateTime.Today.AddDays(-7);
else
fromDate = fd.Value;
if (!td.HasValue)
toDate = DateTime.Today.AddDays(14);
else
toDate = td.Value;
IEnumerable<EZone_SlideInfo> lSlide = _slideRepo.GetSlideByExpiration(fromDate, toDate);
ViewBag.FromDate = DateTime.Parse(fromDate.ToShortDateString());
ViewBag.ToDate = DateTime.Parse(toDate.ToShortDateString());
return View(lSlide);
}
答案 0 :(得分:0)
您的硬编码查询字符串@{
// This code block can be put at the VERY TOP of the .cshtml view.
// That way, it doesn't clutter up your HTML source code potion with C# code.
var searchRouteValues = new RouteValueDictionary {
{ "fd", ViewBag.FromDate.ToString("dd-MM-yyyy") },
{ "td", ViewBag.ToDate.ToString("dd-MM-yyyy") }
};
var btnSearchHtmlAttributes = new Dictionary<string, object> {
{ "class", "btn btn-info" },
{ "id", "btnSearch" }
};
}
<!-- using ActionLink extension method -->
@Html.ActionLink(
linkText : "Search",
actionName : "Index",
controller : "Slide",
routeValues : searchRouteValues,
htmlAttributes : btnSearchHtmlAttributes
)
<!-- using RouteLink extension method -->
@Html.RouteLink(
linkText : "Search",
routeName : "Slide" /* NOTICE: this requires CUSTOM route registration */,
routeValues : searchRouteValues,
htmlAttributes : btnSearchHtmlAttributes
)
为:
作为最佳做法,请考虑使用Html.ActionLink()
或Html.RouteLink()
扩展方法,以便在路由模式更改(或)需要URL编码时不会被破坏。
// your code
routes.MapRoute(
name: "Slide",
url: "Slide/Index/{fd}/{td}",
defaults: new { controller = "Slide", action = "Index", fd = UrlParameter.Optional, td = UrlParameter.Optional }
);
你是否真的需要一个漂亮的URL,如下所示?
// default/generic route registration code
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
如果没有,请尽可能保持通用,如下所示。
Html.ActionLink()
只要您使用上面显示的<a id="btnSearch" class="btn btn-info"
href="/Slide/?fd=01/01/2015&to=01/02/2015">Search</a>
,您的网址路线仍可正常运作。它会像这样呈现超链接。
charArray
如果您按照上面的说明重写代码,我相信它会解决您的问题。
答案 1 :(得分:0)
您需要在/
之前移除?
- 它应该是
<a id="btnSearch" class="btn btn-info" href="/Slide/Index?fd=@ViewBag.....`,
但是您根据ViewBag
属性对网址进行了硬编码,因此您的文本框不会执行任何操作(它们的值永远不会发送到控制器方法),因此您的视图只会在今天之间显示记录 - 7天,今天+ 14天。还
ViewBag.FromDate = DateTime.Parse(fromDate.ToShortDateString());
没有意义 - 您将日期转换为字符串,然后将其转换回日期。此外,您的路由默认值应为defaults: new { controller = "Slide", action = "Index" }
,即没有可选参数。
如果您想根据2个日期的选择过滤记录,则需要发布表格
@using (Html.BeginForm("Index", "Slide", FormMethod.Get))
{
// you textboxes/datepickers
<input type="submit" .../>
}
以便将选定的值发布回方法。您应该使用具有日期和集合属性的视图模型
public class SearchVM
{
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
public IEnumerable<EZone_SlideInfo> Records { get; set; }
}
然后在你的视图中
@model SearchVM
@using (Html.BeginForm("Index", "Slide", FormMethod.Get))
{
@Html.TextBoxFor(m => m.FromDate)
@Html.TextBoxFor(m => m.ToDate)
<input type="submit" .../>
}
<table>
@foreach(var item in Model.Records)
{
// display your filtered results
和控制器方法
public ActionResult Index(DateTime? fromDate, DateTime? toDate) // no need for '= null'
{
fromDate = fromDate ?? DateTime.Today.AddDays(-7);
toDate = toDate ?? DateTime.Today.AddDays(14);
ModelState.Clear();
SearchVM model = new SearchVM()
{
FromDate = fromDate,
ToDate = toDate,
Records = _slideRepo.GetSlideByExpiration(fromDate.Value, toDate.Value);
};
return View(model);
}
当然,您可以通过使用javascript / jquery和ajax将所选日期发布到控制器方法来提高性能,该控制器方法仅返回已过滤的结果,以避免每次都重新生成视图。