简体   繁体   中英

Restricting a cached MVC action to Request.IsLocal?

I have an MVC action with an OutputCache as I need the data to be cached to minimize calls to myService.

[HttpGet]
[OutputCache(Duration = 86400, Location = OutputCacheLocation.ServerAndClient, VaryByParam = "myVariable")]
public JsonResult GetStuffData(string myVariable)
{
    if (Request.IsLocal)
    {
        return myService.CalculateStuff(myVariable)
    }
    else
    {
        return null;
    }
}

I want this only to be accessible from the server it's running on hence the Request.IsLocal.

This works fine, however if someone accesses GetStuffData remotely then it will return null, and null will be cached for a day... making that particular GetStuffData(myVariable) useless for a day.

Similarly, if it was locally called first, then external requests will receive the cached local data.

Is there a way to restrict the entire function to Request.IsLocal instead of just the return value?

So for example, if it's externally accessed you'd just get 404, or Method Not Found etc. But if it was Request.Local you'd be served the cached result.

If it wasn't for the caching this would run perfectly fine, but I'm struggling to find a way to combine Request.IsLocal and caching.

Extra Info that may be relevant:

I call GetStuffData through C# to getcached StuffData by fetching a json object like this... (calling the action directly never resulted in it being cached, so I switched to simulating a webrequest)

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToGetStuffData);
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream()) {
    StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
    return reader.ReadToEnd();
}

You can use custom authorization filter attribute like

public class OnlyLocalRequests : AuthorizeAttribute
{
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.Request.IsLocal)
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                return false;
            }
            return true;
        }
}

and decorate your action as

[HttpGet]
[OnlyLocalRequests]
[OutputCache(Duration = 86400, Location = OutputCacheLocation.ServerAndClient, VaryByParam = "myVariable")]
public JsonResult GetStuffData(string myVariable)
{}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM