manipulating .aspx file programmatically - c#

I was recently assigned a task of changing our asp.net web site localization to use custom resource provider (using sql database) instead of the default asrx resource files. Right now I'm chalenged with replacing hundreds of meta:resourcekey="resource-key" with '<%$ Resources:[filename,]resource-key %>' in our web site too many web pages. I want to do it programmatically.
first of all I'm not able to open .aspx files using XmlDocument, then I wonder how can I read meta:resource entries inside the aspx file as meta:resource is not any regular node attribute. any thoughts or example code how to solve this.
Thx.
Note: in the inserted '<%$ Resources:[filename,]resource-key %>' filename name sould be based on the aspx file name & resource-key on the control type and the resource value.
exemple: in UserPage.aspx page <asp:Label id="uid" meta:resource="userName"> should be replaced with <asp:Label id="uid" Text='<%$ Resources:UserPage,LBL_userName_text %>'.

Html is not valid xml, so no wonder an XmlDocument didn't work. Especially with that <%$ .. %> syntax.
Why not read it as plain text and search for the string "meta:resourcekey"?

This isn't a programming answer, but a utility like PowerGREP may be a viable solution.

Related

Can You Use A Global Resx File In ASP.Net For Both The CodeBehind And To Bind To Web Form Labels?

I am interested in using only Global resource files in the "App_GlobalResources" folder and not having separate files in the "App_LocalResources" for web form labels.
I like the idea of centralizing all the resource strings in one place.
My resx files in App_GlobalResources have the following properties:
Build Action: Embedded Resource
Copy to Output Directory: Do not copy
Custom Tool: PublicResXFileCodeGenerator
Custom Tool Namespace: Resources
This works fine when calling a variable in markup such as:
<p><%=MyStrings.This_is_a_test_string%></p>
It also works fine in the code behind:
Dim strTest As String = MyStrings.This_is_a_test_string
The problem occurs when I attempt to bind a global resource string to a web form control such as:
<asp:Label ID="lblFullName" runat="server" Text="<%$ Resources:MyStrings, This_is_a_test_string %>" AssociatedControlID="txtFullName"></asp:Label>
The web server displays this error:
The resource object with key 'This_is_a_test_string' was not found.
I did notice if I change "Build Action" to "Content" that the resx will correctly bind to the Label control.
However, the problem is the strings will no longer work in the markup or the codebehind any longer.
So, is there a way to use ONE global resource file for the markup, codebehind, and for web form Label controls?
Or, am I forced to use two separate resource files?
At this point I'll admit that I'm thoroughly confused.
I wasn't able to figure out how to use a global .resx file that I could both use explicitly in the code behind such as:
Dim strTest As String = MyStrings.TestString
and also bind to a webform control such as:
<asp:Label ID="lblFullName" runat="server" Text="<%$ Resources:MyStrings, TestString %>" AssociatedControlID="txtFullName"></asp:Label>
Therefore, I decided the simplest solution was to use the global resx files I had and instead of binding them to web form controls I simply set the web form controls explicitly using their ID in the codebehind like so:
lblFullName.Text = MyStrings.FullName
What I did was put a placeholder in the actual control text using { } so I could see if I forgot to set any of the text such as:
<asp:Label ID="lblFullName" runat="server" Text="{THIS IS A TEST STRING}" AssociatedControlID="txtFullName"></asp:Label>

How to get html control by ID that has hyphens?

I have a front end written in html that I am converting to asp, and many of the controls have names with "-" in them. This is causing crazy headaches, as there is no time to rename everything, and the ctrl-f and replace somehow breaks my css. Is there any way to access these controls in the code behind while they have the dashes? I have tried the code below.
//Can find when there is no dash in it, but that breaks the css after find/replace of full solution
HtmlGenericControl body = (HtmlGenericControl)this.Page.FindControl("page-list");
body.Attributes.Add("class", GlobalVariables.webAppSkin);
//I have also tried this, but logout stays null
WebControl logout = (WebControl)Page.FindControl("logout-link");
This is the html control:
<body id="page-list">
Sorry, that's not gonna happen.
You cannot have an element with an id containing "-", and still be a runat="server" ASP.NET control.
Microsoft's docs about the control's IDs states:
http://msdn.microsoft.com/en-us/library/system.web.ui.control.id.aspx
Only combinations of alphanumeric characters and the underscore character ( _ ) are valid values for this property. Including spaces or other invalid characters will cause an ASP.NET page parser error.
If you tried adding runat="server" to the body tag you showed: <body id="page-list">, it would give you the following line in aspx.designer.cs:
protected global::System.Web.UI.HtmlControls.HtmlGenericControl page-list;
Which is obviously throwing an exception on C# syntax.
<body id="page-list"> is not a HTML Control (i.e. an instance of (a subclass of) System.Web.UI.Control because it doesn't have the runat="server" attribute. If you were to add runat="server" then you would get a JIT compile-time error message informing you that "page-list" is not a valid identifier.
ASP.NET Web Forms 4.0 added the ClientIDMode attribute, however it doesn't allow you to set a completely custom ID attribute value. There's no easy solution for this without using <asp:Literal> or implementing your own control (or my preferred option: switching to ASP.NET MVC).
You can access controls in code behind with their ID if you write runat="server". Here is the example for your case
<body runat="server" id="testID">
In code behind you can access it like this:
body.Attributes.Add("class", value);

Making a asp.net web site template without using master page?

I am very new to asp.net and my job.
I was assigned a project to make a simple online order web application using asp.net c#.
The specification has been strictly defined (copied below)
Regarding the common content of the site, I need to make head, top and left(a search function)
"The design in /design/: Head.aspx Top.aspx Left.aspx"
-- Does that mean I am not allowed to use (nested) master page?
--- If so, how can I make a template without using master page?
Another option is to use the Server.Execute() method to render the contents of three separate pages into your base page if you have to use pages instead of usercontrols and still must have three separate pages rendered into one.
In the old days we did this with iis html includes.
If the head/top/left content is just basic HTML, then you could just put the HTML in a separate file and use an include link/reference in the original .aspx page.
If the content is all like a search function, then I agree with Henk's comment, create an .ascx User Control (which is really no different than an .aspx page with an .ascx extension) and then just reference that control on your .aspx page like this:
//put this at the top of your .aspx page
<%# Register src="usercontrols/YourControl.ascx" tagname="nameOfControl" tagprefix="ucControlName" %>
//then reference your control where you want it in your .aspx page
<ucControlName:nameOfControl ID="nameOfControl" runat="server" Visible="True" />
Here's an MSDN article on creating user controls: MSDN User Control
Maybe shoot the person who wrote the spec an email and ask why they have an issue with using a master page - this is kind of exactly why you would use one?!
JM

How do I create hyperlinks from resource files?

I have some text which is loaded from a resource file. Ordinarily, to get dynamic content I would use:
string.Format(GetLocalResourceObject("SomeText"), PhoneNumberAsString)
I want to do the same with a link, only the link needs to be application relative as I have URLs like mysite.com/page.aspx and mysite.com/fr/page.aspx.
I normally use an <asp:HyperLink /> tag to create the links as I can then just put a squiggle at the start NavigateUrl="~/page.aspx". However, I don't know of a way to get a dynamic HyperLink to appear as a string without adding it as a control to something.
Simply writing ToString() outputs System.Web.UI.WebControls.HyperLink..
How do I get a link out of a resource file and make it into a hyperlink using ASP.NET Webforms?
UPDATE
With some help from the answers I now have the following code on my page:
<p><%= string.Format(GetGlobalResourceObject("Resource", "MoreThan1000Users").ToString(), ResolveUrl("~/contact-us.aspx")) %></p>
and in my resource file I have:
If you would like more than 1000 users please call our sales team.
Does this seem like good practice or is there another way to achieve what I'm doing? I don't know if I should be happy or not that there is HTML inside the resource file.
Since you haven't posted code, I'm guessing somewhere you have a HyperLink WebControl object that you're hitting ToString() on. If that's the case, you can access the URL associated with it using its myHyperLinkControl.NavigateUrl property.
If you're storing the link in your resource with a squiggle/tilde (which is good) then you can replace the squiggle with your application location. If you have a control/page, then you can easily call its ResolveURL method (which takes the tilde and automatically replaces it) There's some existing solutions if you don't have a control/page reference with your context, then there's some discussion to do that here: ResolveUrl without an ASP.NET Page
I guess this is what you want:
Server.MapPath("~/page.aspx")
That will work inside your aspx and your code-behind.

How can i localize the url for a sitemap?

I have 2 links, one english one spanish. is there anyway i can localize that in .net? I was thinking of using sitemap
Sure, you can use resources for that, either global or local.
For local resource (pertinent to that .aspx page), switch to design mode, click Tools -> Generate Local Resource.
This will create the "meta:resoucekey" bits for you for all of your server side controls and also will generate the resource file under a "App_LocalResources folder". Copy that resource file and rename it to the spanish that you want to use.
For example If your file name was mypage.aspx, the local resource generated would be mypage.aspx.resx and your new file will be mypage.aspx.es.resx (this will use traditional spanish). Markup below:
<asp:HyperLink runat="server" ID="myLink" Text="The Link" meta:resourcekey="myLink" />
In the local resource files, make sure the key matches the id: keys should be "myLink.NavigateURL" and the values should be your link
If you go the global resource route, then just add new resource file to the App_GlobalResources folder in the solution, name it whatever you want and make a copy of it for the other language. For example the new global resource is MyGlobalResources.resx. and the spanish resource MyGlobalResources.es.resx. Now put the following in your markup:
<asp:HyperLink runat="server" ID="myLink" NavigateURL="<%$ Resources:MyGlobalResources, myLink %>" Text="The Link" />
In the global resource files, the key is whatever your want. Just make sure it matches what you put in the markup: in this case the key should be "myLink" and the value should be your url.
Now, when you switch languages, the correct resource file should pick up and the correct URL should be shown.
P.S. You can localize lots of properties from the server side controls. I hard coded the "Text" property just for simplicity.
Here are a few links that go over localization:
http://msdn.microsoft.com/en-us/library/ms227427.aspx
http://www.west-wind.com/presentations/wwDbResourceProvider/introtolocalization.aspx
http://msdn.microsoft.com/en-us/magazine/cc163566.aspx
Hope I was clear enough :)
EDIT
I don't know how I completely missed the "sitemap" factor. The answer is yes and no. In a single site map you can only localize the Title,Description and custom attributes, not the URL. However, you can create a different sitemap for each locale and add them to the web.config file. Here is a link that explains how to do that (bottom of the page): Localize SiteMap
-D

Categories