ASP Webforms Resources
Embedded Resources
Instead of loading a resource such as an image or xml file from disc, you can embed it in the assembly, for easier deployment and caching. Add the resource to the project, then Properties- Build Action= Embedded Resource.
To access the file:
Stream stream = GetType().Assembly.GetManifestResourceStream("DemoWidgets.Globe.png");
Then put the stream into a constructor for System.Windows.Media.BitmapImage or whatever.
Asp 2:
- Add to file to custom control/ class library as Embedded Resource
- Add Mime type to Assembly.cs
[assembly: System.Web.UI.WebResource("DemoWidgets.Globe.png", "image/png")] - Reference with Page.ClientScript.GetWebResourceUrl(GetType(), resourceName)
protected override void CreateChildControls()
{
Image img = new Image();
//default namespace + [subfolder+] filename
const string resourceName = "DemoWidgets.Globe.png";
img.ImageUrl = Page.ClientScript.GetWebResourceUrl(GetType(), resourceName);
Controls.Add(img);
base.CreateChildControls();
}
Adding resources dynamically
An static image with subfolders- use ResolveUrl with ~ (squiggle)
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<uc1:MyUserControl ID="MyUserControl1" runat="server" />
<asp:UpdateProgress ID="UpdateProgress1" AssociatedUpdatePanelID="UpdatePanel1"
runat="server" DisplayAfter="500">
<ProgressTemplate>
<div style="position: absolute">
<img src='<%=ResolveUrl("~/images/progress.gif") %>' alt="Updating" /></div>
</ProgressTemplate>
</asp:UpdateProgress>
</ContentTemplate>
</asp:UpdatePanel>
Also useful like ResolveUrl is VirtualPathUtility which is like Path for virtual directories (GetFileName, GetDirectory, Combine). MakeRelative is neat.
Javascript
Add javascript. Also see RegisterClientScriptInclude, RegisterStartupScript and RegisterClientScriptResource (the typeof()/GetType() is a bit of a pain when you have shared scripts - you need to use a common type)
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "FixDefaultButton",
"function fireAlert(s) {alert(s);}", true);
RegisterStartupScript just puts the block at the bottom of the page, but the asp Ajax $addHandler allows you hook into the real Dom onload.
string onLoad = "pageInit('" + textBox1.ClientID + "');";
onLoad = "$addHandler(window, 'load', function() { " + onLoad + " } );";
ClientScript.RegisterStartupScript(GetType(), "PageLoad", onLoad, true);
ScriptManager
You can also add script references to the script manager.
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Scripts/jquery.validate.js" />
<asp:ScriptReference
Assembly="WebApplication1"
Name="WebApplication1.Scripts.EmbeddedScript.js" />
</Scripts>
</asp:ScriptManager>
For scripts which are embedded resources, add the WebResource attribute to AssemblyInfo.cs
[assembly: System.Web.UI.WebResource("WebApplication1.Scripts.EmbeddedScript.js", "text/javascript")]
Highlight on error
See the validomatic page.
jQuery
jQuery UI's dialog is by default outside the form, so do this:
var dlg = $('#<%= MyDialogPanel.ClientID %>').dialog({ autoOpen: false, title: '<%= Resources.WebResources.MyDialogTitle %>' });
dlg.parent().appendTo($("form:first"));
Stylesheets
Add a stylesheet
private void AddStyleSheet()
{
HtmlLink hlink = new HtmlLink();
hlink.Href = ResolveUrl("StyleSheet.css");
hlink.Attributes["rel"] = "stylesheet";
hlink.Attributes["text"] = "text/css";
Page.Header.Controls.Add(hlink);
}
Potential problem: If you're rebasing your urls in the head (i.e. your masterPage has <script type="text/javascript" src='<%= ResolveClientUrl("~/js/jquery.min.js") %>'></script>) you get an error ("The Controls collection cannot be modified because the control contains code blocks").
- Place a <asp:PlaceHolder runat="server"> around the header
- Use databinding and Page.Header.DataBind()