HttpGet HttpPost方法偏差

时间:2013-06-26 20:55:56

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

我有两种相同的方法。

我的[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(即使它没有数据(目前这样工作)) 必须过滤掉daterange方法中[HttpPost]之间的项目。

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

为什么不执行以下操作(此方法将提供一种通用功能,可以处理所有类型的过滤/搜索等):

  • 使用没有任何参数的HttpGet =&gt;会给你默认列表
  • 使用带有参数的HttpGet(过滤器)=&gt;会给你一个过滤的清单

创建自定义过滤器:

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
    }

因此,通过“f_”通过Url传输的任何内容都将被视为过滤器参数。

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

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

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

答案 2 :(得分:1)

如另一张海报所述,您应该使用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>
}

答案 3 :(得分:0)

您可以在将方法发布到此类

之后更改foreach循环
foreach (var item in kpi)
{
    if (startdate <= item.date && item.date <= enddate)
    {
        model.IPACS_KPIS.Add(item);
    }
}

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