Accessing app setting from aspx and add concatenated text - asp.net

I've got a project where I'm tasked with changing hard-coded domain references from one domain to another in a group of legacy C#/VB web projects. I want to parameterize the domains as much as possible instead of just replacing with a different hard-coded value. The problem is that there are over 800 of these references in about 30 different solutions, so creating variables in each code-behind to bind to would take forever.
I have added the new domains to the appSettings section of the web.config file, and this works:
<asp:HyperLink Text="Link" NavigateUrl="<%$appSettings:DomainX %>" runat="server" />
But I need to be able to do something like this:
<asp:HyperLink Text="Link" NavigateUrl="<%$appSettings:DomainX %>/newPage.aspx" runat="server" />
But when I add the "/newPage.aspx" the page doesn't compile anymore. I don't really care if this is done with an asp:HyperLink tag or just a tag.
Any ideas on how I can accomplish this?
Thanks.

I think you have two options. The easiest is to just use a plain old anchor tag, if you're not doing anything with the HyperLink server side:
Link
Alternatively, you could set the NavigateUrl in the Page_Load, since <%= will not work properly within the HyperLink server tag:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
link1.NavigateUrl = string.Concat("http://",
ConfigurationManager.AppSettings["DomainX"], "/newPage.aspx");
}
You could also see if you can make a custom binding, something like $myBinding:DomainX, but I don't know if that's possible off the top of my head (I would assume it is though).
EDIT
That $appSettings:DomainX code is called an ASP.NET Expression, and can you can create custom expressions. This post from Phil Haack covers how to set them up, in case you are interested.

How about something along the lines of:
<%=ConfigurationManager.AppSettings["DomainX"].ToString() + "/newPage.aspx" %>

I would go with one of two different approaches that would save you the need to change the NavigateUrl in the .aspx itself.
One option is to inherit from HyperLink class and overriding the NavigateUrl property, adding the ConfigurationManager.AppSettings["DomainX"] in the getter method. Having this, just change <asp:HyperLink ... to <UC:MyLink ...
Second option is adding small function to each page (can be in one shared place and just called from each page) that will iterate over all the hyperlinks controls and dynamically add the domain. To find all controls of certain type you can use such code for example.

Related

Multiple CMSEditableRegion in ascx?

I have three CMSEditableRegion controls inside of an ascx which needs to be on an aspx page 3 or more times.
The problem is that each of the region controls will always contain the content of the last set of them.
After doing a little research, I've found out it saves the content of the control in the database under the ID of the control meaning that the first CMSEditableRegion will have its content overwritten by the last CMSEditableRegion's content (since there are at least three with the same server ID - one per ascx). Well, rather, that was for Kentico 5 but what I'm seeing tends to support this. Unfortunately, the solution I found for Kentico 5 does not work in Kentico 10.
How can I have multiple CMSEditableRegion controls in an ascx that is going to be on the aspx page multiple times?
Edit: We are indeed using the portal manager (correctly) and our master is set up using the specified Kentico Documentation.
You need to ensure each CMSEditableRegion's control ID is unique so that the data for each instance is stored separately in the database.
You can achieve this by setting the ID of the control in the codebehind file of your web part ascx.
Place the CMSEditableRegion into your ascx...
<cms:CMSEditableRegion runat="server" ID="cerContent" RegionTitle="WYSIWYG" RegionType="HtmlEditor" />
...and then set the control's ID in the code behind...
cerContent.ID = this.ID + cerContent.ID;
The unique ID is generated here by concatinating the control's ID with this.ID, which is the unique ID of the web part's instance when it is placed on a page.
Works for me in Kentico 10.
Add this to your web-parts code-behind.
public override void OnContentLoaded()
{
base.OnContentLoaded();
if (!this.StopProcessing)
{
theCMSEditableRegion.ID = theCMSEditableRegion.ID + base.ID;
}
}
When you use portal engine you can have as many as you want and that should apply to aspx development model. Did you follow the example?
I would look inside the DB to make sure that XML is saved correctly:
select CONVERT(xml,DocumentContent), * from cms_document where documentid = 123
When you save web parts (in portal engine this is the equivalent of CMSEditableRegion), the xml looks like this:
<content>
<webpart id="editabletext1;fe77e447-3af4-440f-a736-7c1e321cb3fc">456</webpart>
<webpart id="editabletext;3bb22493-8e7d-47c1-9dc0-dfc5aeff3157">123</webpart>
</content>
Yours should look the same or very similar. it might have something to do the IDs or bindings.
I think you are missing Portal Manager:
<cms:CMSPortalManager ID="manPortal" runat="server" EnableViewState="false" />
But easiest way to understand how this works is to open Kentico APX template in CMSTemplates/CorporateSite. In there you will find master page (root.master) with Home page template (HomeASPX.aspx). In master you can see portal manager is placed and in home you can add as many editable regions as you want. I did try this.
Hope this solves your problem.

ASP.NET best control to hide data inside it?

I would like to use a control which will contain links to other pages and put all these links inside a control (EG table) so that I will be able to hide it with code (show only for administrator)
Other than a table which control should I use? Should I use a panel or something else?
If you want to hide some link use simple Hyperlink control and set visible property only for administrators. You can use Repeater control to render table and and in ItemTemplate set Hyperlink.
Otherwise you can use Placeholder and place table in it, and set visible property of Placeholder, Placehodler wont render anything.
And after all you can use that same Table, add ID and runat="server" attributes and set visible from Code behind.
for example :
<table ID="myTable" runat="server">
...
and then in code hide whole table :
protected void Page_Load(object sender, EventArgs e)
{
myTable.Visible = false;
}
I would use a <asp:PlaceHolder because it is just a placeholder.. and has no other semnatic value like table,panel or this things..
Depends on your goals, as Antonio Bakula said, you can go through and set each individual link as non-visible.
Or if there are a lot of them, throw them in a panel that you can switch on and off wholesale.
You can use a panel to insert all your other controls in it (hyperlinks, buttons...etc)
and in your code you can show and hide your panel and all what's inside by calling
panel.visible=true
panel.visible=false
A panel is a good choice.
An <asp:Panel /> is rendered in HTML as a <div>. If you aren't familiar with HTML, a <div> is just a box, and you can put anything (including a <table>) inside of one. For example, each answer on StackOverflow is shown inside of a <div>.
If you set Visible="false", then the entire <div> will be removed from your HTML output, even though it exists on the .aspx page. Basically, you can very effectively hide the links from non-administrators using this approach.
However, this is stil not very secure. It is very common for malicious users to attempt to find Administrator links just by guessing them (e.g.: /admin/default.aspx, /admin/admin.aspx, etc...). You should use roles to prevent users from accessing your Admin links. Roles prevent certain types of users (e.g.: Users who haven't logged in, or non-admin users) from even visiting these pages. Instead of seeing the page, the users will be shown an error message instead.

Reuse a Variable Multiple Times on an ASP.NET Page

I feel somewhat foolish asking such a simple question, but I can't seem to find an answer. I'm new to ASP.NET (C#), but I'm learning by building a simple set of web pages that display a report. I have a variable that represents a company name. I need to output this variable in multiple places on the web page. The only way I have found to output a variable this is with:
company_name.Text = "Acme Windows";
then
<asp:literal id="company_name" runat="server" />
My problem is that I want to use company_name in multiple places on the page. Do I really have to create a separate variable holding the the same value for each time it is placed on the page? If I just copy the above XML code to all the places I want to show the variable it obviously creates a compile error since that ID is already defined.
I feel like I'm missing something very obvious.
The easiest way to do this is to create a string variable or property in your code-behind class and use the <%= %> notation (short for Response.Write) to render it on your page inline:
// You can do this anywhere on your .aspx, as many times as you like.
<%= this.CompanyName %>
// Better yet, html encode the value to protect against various threats,
// such as cross-site script injection (XSS)
<%= HttpUtility.HtmlEncode(this.CompanyName) %>
.NET 4.0 introduces a new shortcut notation (Html Encoding Blocks) to html-encode your output:
<%: this.CompanyName %>
Regarding your original approach, ASP.NET web controls like Literal represent individual parts of a web page - you can't use them multiple times on a page because the object instance company_name refers to the specific part of the HTML generated by the <asp:literal> in your .aspx page.
In this case, you create a property on the page and output that in every place you need it.
public string CompanyName { get { return "Acme Windows"; } }
And in the aspx:
.NET 4.0:
<%:this.CompanyName%>
Before 4.0:
<%=this.companyName%>
You could add the control dynamically:
Literal myLiteral = new Literal();
myLiteral.text = "Acme Windows";
this.Page.Controls.Add(myLiteral);
You can also add the control within a specific control on the page, by changing the this.Page.Controls reference to the particular control you want to add the literal to.
Why is this a community wiki?
Anyway, you have several possibilities to achieve what you want. Placing multiple variables holding the same name is for sure not best practice. If you have it filled with, let's call it, "semi-dynamic" value, I'd not put it hardcoded within your code. What I would do is to use a global resource file.
You create a new resource file in the App_GlobalResources folder and add a key "COMPANY_NAME" with value "Acme Windows". Then within your ASPX code you can do something like
<asp:literal id="company_name" runat="server" Text="<%$ Resources:GlobalResources, Button_Save %>"/>
I've written a blog post some time ago which details this approach. The advantage of the resource file is that you don't have to touch the code.
If you want to further "refactor" then - assuming you have some general company info you have to display on different positions on the page - you could create a separate UserControl which contains the information like company name, phone number, contact info etc. Within that control you have your literal, label, whatever you use to display that information exactly 1 time. This UserControl is then placed on the places on the actual page where you need it, even multiple times.
The simplest answer is you need to define multiple controls.
But a better solution would be to do this:
Create a property on the code behind side of things:
protected CompanyName{get;set;}
Then, in the aspx side of things, reference that with the <%= %> commands
<span><%=CompanyName %></span>

Allowing any property/attribute on a server/usercontrol

I've noticed that on most, if not all, standard web controls in the System.Web.UI.WebControls namespace, you can add any properties you want to them without crashing the page.
Take the asp:Button control for an example.
This code is perfectly valid:
<form runat="server">
<asp:Button runat="server" Text="Test button" crapAttribute="crapValue" />
</form>
Now, I've got a custom server control which crashes if I add arbitrary attributes to it. It only accepts attributes which have a corresponding public property defined.
The error I get is something like this "The control does not have a public property named "crapAttribute" ".
I would like my custom controls to accept any attribute without crashing. What do I need to do for that to work?
I've looked at the standard controls in Reflector and they do have all kinds of attributes and stuff but there was nothing that I saw which immediately caught my eye.
My custom controls are inheriting from WebControl for what it's worth.
You don't have to do anything in particular to allow arbitary attributes to be added the control markup. Things deriving from WebControl would normally scoop up these attributes and dump them in the Attributes collection.
I can't think of reason why this would fail. You would have to remember to render the Attributes collection in your implementation of Render if you have one.
Can you add a simple example of the code of a new control that fails to your question?
One way of doing it is adding the custom property in code behind
myCustomControl.Attributes.Add("customproperty", "value");
This should do the job for you.
However, I am interested in knowing how to do it in the server control itself.

Access html control from server side

How can i access html control from code behind in asp.net. I do not want to use "runat=server" as it is causing problems.
I have made an empty html table and from my code behind, I want to add <td> to it.
Please help.
Thanks,
Prachi
This is not possible without runat="server".
You say this was causing problems. Please say what problems it was causing.
You say you were accessing the table using getElementById? The ID of a server control changes based on what controls it's inside of. You need to get the changed ID to use:
var tab = getElementById("<%= myTable.ClientId %>");
or something to that effect.
You should use runat=server attribute if you want to access it at code behind.
But maybe you can generate some javascript code that adds the td/tr to your table at codebehind. and you can register it yo your page to run at startup.
runat="server"
to the table and the tr elements, there is no way the code behind can access them (as this tells the frame work to expose the elements to the server).
What are you actually trying to do? Have you looked at either DataGrid, GridView or simple Repeater control? These allow you to define a table structure and dynamically add controls to it (usually through data binding, although there are ways to add items to thier ItemCollections).
one way that you could do this is to add some inline scripting and a public string variable. in your code behind, make a public class-level variable:
public String myColumns
then in your Page_Load event, create your HTML as a string and save it in your myColumns variable:
protected void Page_Load() {
//do stuff
myColumns = someStringWithTDTagsInIt
}
Then in your .aspx page, do the following:
<table id=maintable"><tr><%=myColumns %></tr></table>
It should render your HTML as you wanted it to in your Page_Load event (or whatever event you want, if you want it to load on a button click or something) without using a "runat=server" tag.
Please note that this is not the recommended way to achieve this (controls are typically more efficient) but this should be a valid solution to the question you posed.
simple example.
just you place the runat="server" then you can access .
html controls are cannot access at server side. if you place runat server then it access in the server.

Resources