【问题标题】:HttpGet HttpPost method deviationHttpGet HttpPost 方法偏差
【发布时间】:2013-06-27 21:49:27
【问题描述】:

我有两种相同的方法。

我的 [HttpGet] 方法返回我的 KPI 模型的所有数据列表。

我的 [HttpPost] 版本需要为我的 KPI 模型返回一个日期范围内的数据列表。

[HttpGet]
public ActionResult ViewDepartment (int id = 0)
{
   // populate the IPACS_kpiHistory with all available data in the department
var kpi = model.IPACS_Department.IPACS_Functions.SelectMany(m => m.IPACS_Processes).SelectMany(m => m.IPACS_Procedures).SelectMany(m => m.IPACS_KPIS);

foreach (var item in kpi)
{
    model.IPACS_KPIS.Add(item);
}
   return View(model);
}

[HttpPost]
public ActionResult ViewDepartment (int id, System.DateTime startDate, system.DateTime endDate)
{
   // populate the IPACS_kpiHistory with all available data in the department
var kpi = model.IPACS_Department.IPACS_Functions.SelectMany(m => m.IPACS_Processes).SelectMany(m => m.IPACS_Procedures).SelectMany(m => m.IPACS_KPIS);

foreach (var item in kpi)
{
    model.IPACS_KPIS.Add(item);
}
   return View(model);
}

在视图页面上,我需要显示每个 KPI(在 IPACS_KPIS 中找到)的列表,然后我将每个 KPI 的数据(在 IPACS_kpiHistory 中找到)相加。

这是我的查看页面部分:

@foreach (var item in @Model.IPACS_KPIS)
{
    <tr class="gradeX">
        <td>
            @item.name
        </td>
        <td>
            @item.IPACS_kpiHistory.Select(m => m.startAmount).Sum()
        </td>
        <td>
            @item.IPACS_kpiHistory.Select(m => m.completedAmount).Sum()
        </td>
        <td>
            @item.IPACS_kpiHistory.Select(m => m.endAmount).Sum()
        </td>
    </tr>
}

如何正确过滤掉 [HttpPost] 的数据并找到 startDateendDate 之间的值?

我能想到的唯一方法是向我的模型添加 2 个属性 startDateendDate 并使用剃须刀页面上的属性,但尝试查看是否可以在控制器并保持剃须刀页面清洁。

标准:

必须显示每一个 KPI(即使它没有数据(目前是这样工作的)) 必须在[HttpPost] 方法中过滤掉不在daterange 之间的项目。

【问题讨论】:

  • 如果您不需要其他 KPI,您可以将 Where(m => m.Date ...) 添加到以 var kpi = 开头的行
  • @NickBray 遗憾的是,我必须显示在 kpiHistory 表中确实有项目的 KPI,以及在 kpiHistory 表中还没有条目的 KPI。

标签: c# asp.net-mvc linq razor


【解决方案1】:

你的方法是错误的。 POST 应该只用于将数据发布回服务器。当表单处理是“幂等的”时,应该使用“GET”方法,并且仅在这些情况下。简单来说,我们可以说“GET”基本上只是用于获取(检索)数据,而“POST”可能涉及任何事情,例如存储或更新数据、订购产品或发送电子邮件。

为什么不做以下事情(这种方法将提供一个通用功能来处理所有类型的过滤/搜索等):

  • 使用不带任何参数的 HttpGet => 会给你默认列表
  • 使用带有参数(过滤器)的 HttpGet => 会给你一个过滤列表

创建自定义过滤器:

public class SearchAttribute : ActionFilterAttribute
    {
        #region Public Methods and Operators

        /// <summary>
        /// Overrides method OnActionExecuting, fires before every controller action is executed. Method retrives list search parameters from current url and saves them in
        /// SearchParams base controller dictionary.
        /// </summary>
        /// <param name="filterContext">
        /// The filter Context.
        /// </param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            foreach (string key in filterContext.HttpContext.Request.QueryString.AllKeys)
            {
                if ((key != null) && key.StartsWith("f_"))
                {

                        filterContext.Controller.ViewData[key] =
                            filterContext.HttpContext.Request.QueryString[key].ToLower();

                }
            }
        }

        #endregion
    }

所以任何通过 Url 带有“f_”的东西都将被视为过滤器参数。

用您在上面创建的 FilterAttribute 装饰您的控制器:

[Search]
public ActionResult Index()
{
   var qs = this.ControllerContext.RequestContext.HttpContext.Request.QueryString
   ....
}

"qs" 现在保存您可以解析的查询字符串,并根据过滤器返回正确的列表。

【讨论】:

  • 我确信这可以完美运行,但对我来说实现它似乎有点困难。我还是个新手,这里有几件事我不熟悉。我会努力尝试,但必须做一些学习,这绝不是一件坏事。 :)
【解决方案2】:

要对一定范围内的值求和,只需添加一个 Where 子句:

@item.IPACS_kpiHistory.Where(m => m.date >= Model.MinDate && m.date <= Model.MaxDate)
    .Sum(m => m.startAmount)

【讨论】:

  • 我试过了,现在没有返回任何数据。这很奇怪,因为有数据,但是当我尝试通过数据过滤掉它时,根据页面什么都不存在。
【解决方案3】:

正如另一张海报所述,您应该将 Get 用于这两种控制器方法。这没什么大不了的,但这是正常的惯例。然后,您将拥有一种方法,即 get 并获取 id、开始日期、结束日期。

如果您只使用 get 或同时使用 get 和 post,您仍然可以解决此问题,而无需在视图中显示任何逻辑(因为它不应该存在)。

为模型添加开始日期和结束日期。然后在控制器中设置这些属性或变量。然后在模型上创建一个方法 Model.GetFilteredKPIS() 该方法返回模型中开始日期和结束日期之间的所有 KPIS。

那么剃须刀就干净了:

@foreach (var item in @Model.GetFilteredKPIS())
{
    <tr class="gradeX">
        <td>
            @item.name
        </td>
        <td>
            @item.IPACS_kpiHistory.Select(m => m.startAmount).Sum()
        </td>
        <td>
            @item.IPACS_kpiHistory.Select(m => m.completedAmount).Sum()
        </td>
        <td>
            @item.IPACS_kpiHistory.Select(m => m.endAmount).Sum()
        </td>
    </tr>
}

【讨论】:

    【解决方案4】:

    您可以将您的 post 方法中的 foreach 循环更改为类似的内容

    foreach (var item in kpi)
    {
        if (startdate <= item.date && item.date <= enddate)
        {
            model.IPACS_KPIS.Add(item);
        }
    }
    

    您必须更改它以使用对象的相关属性。

    【讨论】:

    • 如果我没记错的话,这只会添加在 kpiHistory 表中有条目的项目,对吧?我需要它来显示每个 KPI(KPI 表中的每一行),然后对于 post 方法,我仍然需要显示每个 KPI,然后按日期过滤掉 kpihistory 中的数据。
    • 例如,我的 KPI 表列出了 40 个不同的 KPI。我的 kpiHistory 表显示了每个 KPI 的所有数据。我总结了这些数据并将其显示在我的视图页面上。如果 KPI 在 kpihistory 表中没有完成任何工作,我仍然需要显示它,如果确实有工作完成,我只需要对日期之间的数据求和。认为这措辞更好。
    • @JamesWilson 您的问题缺少很多相关代码和信息。首先,您有一些模型对象,我们不知道它是如何创建的,甚至其中有什么。其次,我不知道 KPI 是什么,KPI 历史是什么,或者这些东西是如何从你的数据库中出来的,等等。没有这些信息,我们所能做的就是猜测如何帮助你。请编辑您的问题以添加更多详细信息。
    猜你喜欢
    • 2023-03-15
    • 2011-10-04
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    相关资源
    最近更新 更多