Asked  7 Months ago    Answers:  5   Viewed   74 times

I am looking for a method to disable the browser cache for an entire ASP.NET MVC Website

I found the following method:

Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.Cache.SetNoStore();

And also a meta tag method (it won't work for me, since some MVC actions send partial HTML/JSON through Ajax, without a head, meta tag).

<meta http-equiv="PRAGMA" content="NO-CACHE">

But I am looking for a simple method to disable the browser cache for an entire website.

 Answers

36
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();

All requests get routed through default.aspx first - so assuming you can just pop in code behind there.

Tuesday, June 1, 2021
 
iceduck
answered 7 Months ago
18

I did some digging on a related question and looking at mvc 3 source, they definitely don't support any attribute other than Duration and VaryByParam. The main bug with their current implementation is that if you don't supply either one of these you will get an exception telling you to supply that, instead of an exception say that what you tried to use is not supported. The other major issue was that they will cache even if you turn off caching in the web.config, which seems really lame and not right.

The biggest issue I had with it all is that they are using the same attribute which works in both views and partial views, but in reality it should probably be 2 different attributes since the partial view is so limited and behaves a lot differently, at least in it's current implementation.

Saturday, July 3, 2021
 
weegee
answered 5 Months ago
12

Where exactly does it keep the copy of a page?

The location of where the cache is stored is determined by Location property of the OutputCacheAttribute. In your case you set Location=OutputCacheLocation.Client so it will keep the cache on the client browser.

And what are the differences between OutputCacheLocation.Client and OutputCacheLocation.Browser?

OutputCacheLocation.Browser doesn't exist. It's an invalid value. The documentation of the OutputCacheLocation enumeration type contains the possible values along with a description of its usage:

  • Any - The output cache can be located on the browser client (where the request originated), on a proxy server (or any other server) participating in the request, or on the server where the request was processed. This value corresponds to the HttpCacheability.Public enumeration value.
  • Client - The output cache is located on the browser client where the request originated. This value corresponds to the HttpCacheability.Private enumeration value.
  • Downstream - The output cache can be stored in any HTTP 1.1 cache-capable devices other than the origin server. This includes proxy servers and the client that made the request.
  • Server - The output cache is located on the Web server where the request was processed. This value corresponds to the HttpCacheability.Server enumeration value.
  • None - The output cache is disabled for the requested page. This value corresponds to the HttpCacheability.NoCache enumeration value.
  • ServerAndClient - The output cache can be stored only at the origin server or at the requesting client. Proxy servers are not allowed to cache the response. This value corresponds to the combination of the HttpCacheability.Private and HttpCacheability.Server enumeration values.
Thursday, August 5, 2021
 
Lawrence Taur
answered 4 Months ago
57

What are the resources that are being cached? I suspect js/css files, a good way to handle this is to add a query param with a version to the path of those resources in order to force the browser to load the new file if the version changed, something like this:

<script type="text/javascript" src="your/js/path/file.js?v=1"></script>
<link href="/css/main.css?v=1" media="screen,print" rel="stylesheet" type="text/css">

And when you release a new update of your website, replace the version as follows:

<script type="text/javascript" src="your/js/path/file.js?v=2"></script>
<link href="/css/main.css?v=2" media="screen,print" rel="stylesheet" type="text/css">

The browser will thing that the file is a new file and it will update the cache. Hope this helps.

In order to disable html caching, you can add a metatag to your file as follows:

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

But this will entirely disable caching of html files that have this metatag, I don't think there is a way to handle this as easily as with js/css files, you can set the metatag to refresh the html in a future date though. Here is an article describing how to use that metatag if you need more info:

http://www.metatags.info/meta_http_equiv_cache_control

Monday, August 9, 2021
 
Pupil
answered 4 Months ago
83

Kav, in your custom form control you has

  registerOnChange(fn: (v: any) => void) {
        this.formGroup.valueChanges.subscribe(fn);
    }

so, your component return the "value" of formGroup. As a control is disabled, the value not return this field. You can change your customControl to return the rawValue of the formGroup, for this you need create a onChangeFunction, and in a ngOnInit subscribe to changes and send the rawValues. As we subscribe it's good unsubscribe using a takeWhile and a variable

export class DetailsFields implements ControlValueAccessor,OnInit,OnDestroy {
    ...
    onChange: (v:any) => void = () => {}; //<--define a function
    isAlive:boolean=true; //<--use to unsubscribe, see below

    registerOnChange(fn: (v: any) => void) {
      this.onChange = fn; //<--equal to function
    }

    //In ngOnInit
    ngOnInit()
    {
      this.formGroup.valueChanges.pipe(takeWhile(()=>this.isAlive))
        .subscribe(v=>{
        //return this.formGroup.getRawValue()
        this.onChange(this.formGroup.getRawValue())
      })
    }
    //In ngOnDestroy
    ngOnDestroy() {  //make isAlive=False to unsubscribe
      this.isAlive=false;
    }

But in this case, you received the year always is enabled or not

There're another aproach, that is not have a custom form control, just a component to manage the make,year and color. For this, the first is change your app-component and create the form like another form with a formArray.

<div id="cars" [formGroup]="form">
  <div formArrayName="cars">
  <div *ngFor="let car of form.get('cars').controls; let i = index;" 
   [formGroupName]="i">
    <app-details-fields [formGroup]="form.get('cars').at(i)" ></app-details-fields>
  </div>
  </div>
</div>

See that in a formArray we iterate over form.get('cars').controls and we need put a [formGroupName]="i". In the component simply pass as input [formGroup] form.get('cars').at(i)

Of course, you need change your function "createCars" to return a formGroup. not a formControl that return an object type {make:..,color:..,year}

createCar(car: any) {  //return a formGroup,not a formControl
    return this.builder.group({
      make: car.make,
      color: car.color,
      year: car.year
    });
  }

Well, the details-fields becomes easer:

details-fields.component.ts

@Component({
  selector: 'app-details-fields',
  templateUrl: './details-fields.component.html',
  styleUrls: ['./details-fields.component.css']  ,
})

export class DetailsFields {
   @Input() formGroup:FormGroup

   disableYear() {
      this.formGroup.get('year').disable();
    }

    enableYear() {
      this.formGroup.get('year').enable();
    }
}

details-fields.component.html

<div [formGroup]="formGroup">
  <div class="car-wrap">
      <div>
          <p class="title">This car is a {{formGroup.get('make').value}}</p>
      <div>
        <input type="text" formControlName="make">
        <input type="number" formControlName="year">
        <input type="text" formControlName="color">
      </div>
      <div>
        <button style="margin-top: 3px;" (click)="enableYear()">Enable year</button>
        <button style="margin-top: 3px;" (click)="disableYear()">Disable year</button>
      </div>
    </div>
  </div>
</div>
Saturday, October 23, 2021
 
Joshua Walsh
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share