C# | Web Application | Static contents caching issue Versioning | Azure PaaS - c#

I have a web application deployed on the Azure app service developed in ASP.NET MVC using C#.
I am using the following code for Static content (js, CSS) versioning.
public static void RegisterBundles(BundleCollection bundles)
{
// Update the base url for css and script with static content url and appends versionid
Styles.DefaultTagFormat = string.Format("<link href='{0}{{0}}?v=1' rel='stylesheet'/>"
, ApplicationConfigHelper.StaticContentUrl);
Scripts.DefaultTagFormat = string.Format("<script src='{0}{{0}}?v=1'></script>"
, ApplicationConfigHelper.StaticContentUrl);
// If we are in debug mode, then we will not bundle and minify for developer advantage
if (HttpContext.Current.IsDebuggingEnabled)
{
BundleHelper bundleHelper = new BundleHelper();
BundleTable.VirtualPathProvider = new StaticContentVirtualPathProvider();
bundleHelper.IncludeBundleFiles(bundles);
}
}
The same code was used to cache all the static contents in the browser before. Suddenly it stopped caching and started downloading the same in every request without any change in code and we don't know what is the root cause.
By initial finding and changing code, we came to know that it started caching both after removing the version of js and CSS while bundling the same as below sample code.
Styles.DefaultTagFormat = string.Format("<link href='{0}{{0}}?' rel='stylesheet'/>"
, ApplicationConfigHelper.StaticContentUrl);
Scripts.DefaultTagFormat = string.Format("<script src='{0}{{0}}?'></script>"
, ApplicationConfigHelper.StaticContentUrl);
Is there any specific way to set the version of static content while bundling in C#?

Related

How to print thing in for loop Console.WrileLine() in aspx

This is my code i want to print these array in for loop on aspx page
for (int i = 0; i < notes.Count; i++)
{
if (noteCounter[i] != 0)
{
Console.WriteLine(notes[i].Col2 + " : "
+ noteCounter[i]);
}
}
It was working fine in Console Application i just changed it to the Web application Web form and now i want to print it on screen just without html and css any
First Solution:
You can use Log.Write() instead of Console.Write() then check your logs on the Output window; Of course, you should run your app in debugging mode.
first import System.Diagnostics
using System.Diagnostics;
// skip
for (int i = 0; i < notes.Count; i++)
{
if (noteCounter[i] != 0)
{
Debug.WriteLine(notes[i].Col2 + " : "
+ noteCounter[i]);
}
}
Second Solution
You can log everything and save it on a separate file, then check it whenever you want to... Don't need to import anything, just write this method:
public void Logger(string lines)
{
//Write the string to a file.append mode is enabled so that the log
//lines get appended to test.txt than wiping content and writing the log
using(System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\path\\to\\log\\file.txt", true))
{
file.WriteLine(lines);
}
}
Third Solution
Logging in .NET Core and ASP.NET Core
NET Core supports a logging API that works with a variety of built-in and third-party logging providers. This article shows how to use the logging API with built-in providers.
Most of the code examples shown in this article are from ASP.NET Core apps. The logging-specific parts of these code snippets apply to any .NET Core app that uses the Generic Host. The ASP.NET Core web app templates use the Generic Host.
Read the full article at Microsoft
change Console.WriteLine to document.write

Reading base path from web.config

I have a web application created in MVC5/C#
The app uses jscript to call actions from a controller for certain instances. The problem I am having is that the application is nested deeper on IIS than on my local server.
Local:
var urlForModesl = "/ICS_Requisitions/Details";
IIS
var urlForModesl = "../ICS_Requisitions/Details";
Is there anyway I can grab the base path dynamically . . maybe from web.config or something? So that I don't have to keep switching back and forth. It's making testing a bit cumbersome, as there are similar situations throughout the application.
Have you tried Bundling of Js. If not follow this
// create an object of ScriptBundle and
// specify bundle name (as virtual path) as constructor parameter
ScriptBundle scriptBndl = new ScriptBundle("~/bundles/bootstrap");
//use Include() method to add all the script files with their paths
scriptBndl.Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"
);
//Add the bundle into BundleCollection
bundles.Add(scriptBndl);
BundleTable.EnableOptimizations = true;
Find more details on this link
https://www.tutorialsteacher.com/mvc/scriptbundle-mvc

MVC6 new minification and bundling with Bower/NPM

I started getting up to date with the ASP.NET 5 and MVC 6, and I see a lot of internet posts about Bower VS NPM.
The default started MVC template however uses both, is this required for the taskrunner (gulp) to work or is there another reason?
Second question is about the resource path, in MVC < 6 you could declare a relative path to research the minified/bundled js/css. This way each MVC View would have its own path to its own specific js/css. How can I do this with gulp?
In MVC < 6 the js/css would NOT minify when debug enabled (as default setting), so it remains readable. I see the option to use an if-like statement on the environment variable like
environment names="Development">script path
and another one for production in the view. This seems very cumbersome, is there a simple solution for not minifying in debug instead of having to list all paths twice (one minified and one not)?
Have one version of watch minify your js files and one that doesn't. Either way all of your project paths can just point to the built js file to prevent having to switch back and forth for dev or prod. You would need to break the minify stuff out of the 'scripts' task below and create a task that just does that.
//Concatenate & Minify JS
gulp.task('minscripts', function () {
return gulp.src(config.alljs, { base: 'public/' })
.pipe($.concat('all.js'))
.pipe(gulp.dest('_build'))
.pipe($.rename('all.min.js'))
.pipe($.uglify())
.pipe(gulp.dest(config.build));
});
gulp.task('scripts', function () {
return gulp.src(config.alljs, { base: 'public/' })
.pipe($.concat('all.js'))
.pipe(gulp.dest('_build'))
.pipe($.rename('all.min.js'))
.pipe(gulp.dest(config.build));
});
gulp.task('watchWith', function () {
gulp.watch('public/app/views/*.js', ['lint', 'minscripts']); //<- runs 'scripts' here
gulp.watch('public/css/*.less', ['less']);
});
gulp.task('watchWithout', function () {
gulp.watch('public/app/views/*.js', ['lint', 'scripts']);
gulp.watch('public/css/*.less', ['less']);
});

Can I run a ASPX and grep the result without making HTTP request?

How can I just make a function call, without URL, and without HTTP, to a simple ASP.NET file, and capture the byte stream it generated?
More background information,
I need a some kind of template can put a little logic inside, to render some INI like text files. I give up those libraries ported from Java and come up a solution of using ASP.NET for template engine. (I am NOT using it to build a website, not even a HTML.)
I have written a ASP.NET page (no WebForm, no MVC), which accept a XML POST, and it generate a long text file based on a set of simple but not too simple rules.
I generate the XML from DB objects, submit to the ASP page, grep the result and it works very well. However, the problem is that we want to use as a library, using by a WCF. Because of this, I failed to use a relative path and I have to store the URL of the ASP somewhere in the configuration, which I do not want to.
It will be hosted on a IIS server, but not called (at least not directly) from any frontend ASP, and will never called from end user.
PS. I was originally looking for a simple template engine for C#, but they are too old and not maintenance anymore, poor documentation, missing integrated editor/debugger, too simple, and the they might speak different languages.
PPS. I've also thought about T4, but it does not have a editor nor debugger in VS 2008.
You can run an ASPX page without IIS, without an HTTP message, if you build a host for the ASPNET runtime.
Example:
public class MyAspNetHost : System.MarshalByRefObject
{
public void ProcessRequest(string page)
{
var request = new System.Web.Hosting.SimpleWorkerRequest
(page, // the page being requested
null, // query - none in this case
System.Console.Out // output - any TextWriter will do
);
// this will emit the page output to Console.Out
System.Web.HttpRuntime.ProcessRequest(request);
}
public AppDomain GetAppDomain()
{
return System.Threading.Thread.GetDomain();
}
}
public class Example
{
public void Run(IEnumerable<String> pages)
{
// ASPNET looks for assemblies - including the assembbly
// that contains any custom ASPNET host - in the bin\
// subdirectory of the physical directory that backs the
// ASPNET Host. Because we are going to use the current
// working directory as the physical backing directory for
// the ASPNET host, we need to ensure there's a bin
// subdirectory present.
bool cleanBin = false;
if (!Directory.Exists("bin"))
{
cleanBin = true;
Directory.CreateDirectory("bin");
}
// Now, ensure that the assembly containing the custom host is
// present in that bin directory. The assembly containing the
// custom host is actually *this* assembly.
var a = System.Reflection.Assembly.GetExecutingAssembly();
string destfile= Path.Combine("bin", Path.GetFileName(a.Location));
File.Copy(a.Location, destfile, true);
host =
(MyAspNetHost) System.Web.Hosting.ApplicationHost.CreateApplicationHost
( typeof(MyAspNetHost),
"/foo", // virtual dir - can be anything
System.IO.Directory.GetCurrentDirectory() // physical dir
);
// process each page
foreach (string page in pages)
host.ProcessRequest(page);
}
}
If you want to clean up that bin directory, you have to get the AppDomain to unload first. You can do that, like this:
private ManualResetEvent aspNetHostIsUnloaded;
private void HostedDomainHasBeenUnloaded(object source, System.EventArgs e)
{
// cannot clean bin dir here. The AppDomain is not yet gone.
aspNetHostIsUnloaded.Set();
}
private Run(IEnumerable<String> pages)
{
try
{
....code from above ....
}
finally
{
if (host!= null)
{
aspNetHostIsUnloaded = new ManualResetEvent(false);
host.GetAppDomain().DomainUnload += this.HostedDomainHasBeenUnloaded;
AppDomain.Unload(host.GetAppDomain());
// wait for it to unload
aspNetHostIsUnloaded.WaitOne();
// optionally remove the bin directory
if (cleanBin)
{
Directory.Delete("bin", true);
}
aspNetHostIsUnloaded.Close();
}
}
}
This makes sense for testing ASPX pages, and that sort of thing. But I'm not so sure this is the right thing, for your scenario. There are more direct ways to generate text files. But, it may be right for you. If you really like the template engine idea, hosting ASPNET may be just the thing for you.
In your case, you would want to modify the custom Host so that the output for each page goes to a StringWriter instead of Console.Out, and then you could do Grep (or more likely a search with Regex) on that output. You might also want to modify it to accept all the input data as a querystring. You'd need to format the page request to do that.
EDIT: There's a good article on MSDN Magazine on this technique of hosting the ASPNET runtime. From December 2004.
EDIT2: There's a simpler way to manage the bin directory. Just create a symbolic link named bin, pointing to ".". Then, you can remove the symlink after the call to AppDomain.Unload(), without waiting. Looks like this:
public void Run(string[] pages)
{
bool cleanBin = false;
MyAspNetHost host = null;
try
{
// This creates a symlink.
// ASPNET always looks for a bin\ directory for the privateBinPath of the AppDomain.
// This will create the bin dir, pointing to the current dir.
if (!Directory.Exists("bin"))
{
cleanBin = true;
CreateSymbolicLink("bin", ".", 1);
}
host =
(MyAspNetHost) System.Web.Hosting.ApplicationHost.CreateApplicationHost
( typeof(MyAspNetHost),
"/foo", // virtual dir - can be anything
System.IO.Directory.GetCurrentDirectory() // physical dir
);
foreach (string page in pages)
host.ProcessRequest(page);
}
finally
{
// tell the host to unload
if (host!= null)
{
AppDomain.Unload(host.GetAppDomain());
if (cleanBin)
{
// remove symlink - can do without waiting for AppDomain unload
Directory.Delete("bin");
}
}
}
}
This eliminates the need for the ManualResetEvent, copying files, synchronization, etc. It assumes the assembly for the custom ASPNet Host as well as all the assemblies required by the ASPX pages you run are contained in the current working directory.
This sounds like a very similar issue which is generating HTML emails on a server. There are some answers here that do that (for MVC):
ASP.NET MVC: How to send an html email using a controller?
You can proceed in a similar fashion for non-MVC by loading and rendering a control (ASCX) to a file.

how to add a WebPart to all pages in a SharePoint site?

I am using SharePiont Server 2007 Enterprise with Windows Server 2008 Enterprise, and I am using publishing portal template. I am developing using VSTS 2008 + C# + .Net 3.5. I want to know how to add a WebPart to all pages of a SharePoint Site? Any reference samples?
I want to use this WebPart to display some common information (but the information may change dynamically, and it is why I choose a WebPart) on all pages.
There are two ways to do this depending on your situation.
If the sites exist already, you need to iterate over the sites, adding the web part:
http://blogs.msdn.com/tconte/archive/2007/01/18/programmatically-adding-web-parts-to-a-page.aspx
If the sites do not exist then you can add the web part to the site template:
How to add a web part page to a site definition?
Here's the code from Shiraz's first link worked out a bit more:
(Note: This code is not optimized, for instance, looping through a List's Items collection is not something you should normally do, but seeing as this is probably a one time action there's no problem)
private void AddCustomWebPartToAllPages()
{
using(SPSite site = new SPSite("http://sharepoint"))
{
GetWebsRecursively(site.OpenWeb());
}
}
private void GetWebsRecursively(SPWeb web)
{
//loop through all pages in the SPWeb's Pages library
foreach(var item in web.Lists["Pages"].Items)
{
SPFile f = item.File;
SPLimitedWebPartManager wpm = f.GetLimitedWebPartManager(PersonalizationScope.Shared);
//ADD YOUR WEBPART
YourCustomWebPart wp = new YourCustomWebPart();
wp.YourCustomWebPartProperty = propertyValue;
wpm.AddWebPart(wp, "ZONEID", 1);
f.Publish("Added Web Part");
f.Approve("Web Part addition approved");
}
// now do this recursively
foreach(var subWeb in web.Webs)
{
GetWebsRecursively(subWeb);
}
web.Dispose();
}

Categories

Resources