我有一个公开的行动结果,在将其移交给私人行动结果之前,我想将其用作工作的预处理器。我正在计划使用第一个控制器操作来调用外部API,该API将请求IP地址放置在一个规模上,以衡量该地址的潜在欺诈活动。此API调用可能返回的级别为LowMediumHigh

我在想什么的总体思路如下:

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;
}


我忍不住无法保持应用程序的这一部分异步,因为它将经常受到攻击。

最佳答案

要回答您的第一个问题:

没有输出缓存将不被应用。该属性必须位于实际的公共操作方法上,因为这是MVC框架所知道的所有内容并具有审问的能力,而MVC对您对PageOutput的调用一无所知,即使这样做了,也应该讨论该怎么做。那条信息,即如果另一个调用另一个具有不同的输出缓存设置的私有函数怎么办……事情很快就会失控。

我对第二个问题的看法:

我认为您可能正在使用异步框架来解决问题,而不是解决问题:)您可能应该考虑摆脱它,以使生活更轻松。至于将视图合并为一个视图,这是我需要进一步澄清的内容,即视图所包含的内容以及随着产品规格功能的增加它们之间随时间变化的可能性。

10-08 11:11