我有一个公共行动结果,我希望在转交私人行动结果之前将其用作工作的预处理器。我计划使用第一个控制器操作来调用外部API,该API将请求的IP地址放在衡量该地址潜在欺诈活动的比例上。此API调用可能返回的可能级别为Low
,Medium
,High
。
我所思考的一般概念如下:
public async Task<ActionResult> RiskCheck(string id, int page) {
// Check risk for request with external API
var riskLevel = await SomeRiskCheckAsync();
return PageOutput(id, page, riskLevel);
}
[OutputCache(Location = OutputCacheLocation.Server, Duration = Int32.MaxValue, VaryByParam = "id;page;riskLevel")]
private async Task<ActionResult> PageOutput(string id, int page, string riskLevel) {
if (riskLevel.Equals("Low") {
return View("Low_Risk");
} else if (riskLevel.Equals("Medium")) {
return View("Medium_Risk");
} else {
return View("High_Risk");
}
}
最终目标是将有3个缓存视图对应于id和page的每个唯一组合,这样我就可以减少不断重新渲染视图的需要,这些视图将始终是相同的输出。
我对这种方法有两个问题。首先,当应用于这样的私有方法时,输出实际上是否会被缓存,或者它是否需要是面向动作结果的传统客户端?
其次,如果我能够在VaryByCustom
上使用RiskCheck
后卫并使用该自定义覆盖提前检查风险,我觉得我可以将两个视图合并为一个。这实际上是我首先采用的方法。但是,当我去覆盖GetVaryByCustomString(HttpContext context, string custom)
时,我意识到没有提供异步版本。
public override GetVaryByCustomString(HttpContext context, string custom) {
// Can't await this result
var riskLevel = await SomeRiskCheckAsync();
return riskLevel;
}
我无法承受不能保持应用程序的这一部分异步,因为它会经常被点击。
答案 0 :(得分:1)
回答你的第一个问题:
不会应用输出缓存。该属性必须位于实际的公共操作方法上,因为这是MVC框架所知道的并且具有查询的能力,而MVC对您对PageOutput
的调用一无所知,即使它确实存在,也可以说它应该是什么处理那条信息,即如果有另一个调用另一个具有不同输出缓存设置的私有函数,那么事情可能会很快失控。
我对第二个问题的看法:
我认为你可能正在使用异步框架,而不是解决问题:)你可能应该考虑摆脱它以使生活更轻松。至于将视图合并为一个,我需要更多地澄清视图包含的内容以及随着时间的推移它们彼此不同的可能性,因为产品规范中的功能会增加。