2013-06-26 110 views
0

我有两个相同的方法。HttpGet HttpPost方法偏差

我的[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]方法。

+0

如果您不需要其他KPI的,你可以添加一个WHERE(M => m.Date ...)到以VAR KPI开头的行= –

+0

@NickBray很遗憾,我必须显示kpiHistory表中包含项目的KPI,以及kpiHistory表中还没有条目的KPI。 –

回答

1

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

为什么不这样做以下(这种做法会给一个通用的功能,需要所有类型的过滤照顾/搜索等):

  • 使用HTTPGET没有任何PARAMS =>会给你默认列表
  • 使用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”现在握着你的查询字符串,你可以解析,并根据过滤器有你返回正确的列表。

+0

我确定这个功能完美,但对我来说实施起来似乎有点困难。我还很新,有几件事我不熟悉。我会努力尝试,但必须做一些学习,这绝不是坏事。 :) –

0

在您发布的方法是这样的

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

你将不得不改变,使其能够使用对象的相关属性你可以改变你的foreach循环。

+0

如果我没有弄错,这只会添加在kpiHistory表中有条目的项目吗?我需要它显示每个KPI(KPI表中的每一行),然后对于post方法,我仍然需要显示每个KPI,但是按日期过滤掉kpihistory中的数据。 –

+0

因此,例如我的KPI表格列出了40个不同的KPI。我的kpiHistory表格显示了每个KPI的所有数据。我总结这些数据并在我的视图页面上显示。如果KPI在kpihistory表中没有完成任何工作,我仍然需要显示它,如果它已经完成了工作,我只需要总结日期之间的数据。认为这是措辞更好。 –

+0

@JamesWilson你的问题缺少了很多相关的代码和信息。首先,你有一些模型对象,我们不知道它是如何创建的,甚至不知道它是如何创建的。其次,我不知道KPI是什么,KPI历史是什么,或者这些东西是如何从数据库中传出来的,等等。如果没有这些信息,我们所能做的只是猜测如何为您提供帮助。请编辑您的问题以添加更多详细信息。 – Becuzz

1

要在一定范围内的值相加,只需添加一个WHERE子句:

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

我试过了,它现在没有返回数据。这是奇怪的,因为有数据,但是当我试图通过数据过滤它时,根据页面没有任何东西存在。 –

1

正如另一张海报所述,您应该使用这两种控制器方法的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> 
}