Pass variable used in aspx page to user control - asp.net

We are in ASP.Net Webforms. I come from a LAMP Stack mindset...
ASPX Code (part of it)
<asp:Content runat="server" ContentPlaceHolderID="PH_MainContent">
<h3 class="fleft">
<asp:Literal runat="server" ID="li_title" />
...
<Example:userControl runat="server" someVariable="text" otherVariable=<%=li_title.Text%> thirdVariable=<%=Items["sort"].toString()%> />
So, li_title is a literal set in the code behind, I want to reuse it later, passing it to a userControl, where it shall be displayed in a javascript. Items is page.Items. I have also tried this.li_title (which is suggested to me in Visual Studio 2015).
After reading "quite a few" very similar questions, this seem the solution. However obviously I'm missing the point. What would that be..?

You can create a public property for each variable on your user control and set them in aspx. See this for more information

Related

Two-way data binding of controls in a user control nested inside a FormView doesn't work

I'm trying to perform two-way data binding on the controls in my user control, which is hosted inside a FormView template:
<asp:ObjectDataSource runat="server" ID="ObjectDataSource"
TypeName="WebApplication1.Data" SelectMethod="GetItem" UpdateMethod="UpdateItem">
</asp:ObjectDataSource>
<asp:FormView runat="server" ID="FormView" DataSourceID="ObjectDataSource">
<ItemTemplate>
<uc:WebUserControl1 runat="server"></uc:WebUserControl1>
</ItemTemplate>
<EditItemTemplate>
<uc:WebUserControl1 runat="server"></uc:WebUserControl1>
</EditItemTemplate>
</asp:FormView>
The web user control:
<%# Control Language="C#" ... %>
<asp:TextBox runat="server" ID="TitleTextBox" Text='<%# Bind("Title") %>'>
</asp:TextBox>
The binding works fine when the FormView is in View mode but when I switch to Edit mode, upon calling UpdateItem on the FormView, the bindings are lost. I know this because the FormView tries to call an update method on the ObjectDataSource that does not have an argument called 'Title'.
I tried to solve this by implementing IBindableTemplate to load the controls that are inside my user control, directly into the templates (as if I had entered them declaratively). However, when calling UpdateItem in edit mode, the container that gets passed into the ExtractValues method of the template, does not contain the TextBox anymore. It did in view mode!
I have found some questions on SO that relate to this problem but they are rather dated and they don't provide any answers that helped me solve this problem.
How do you think I could solve this problem? It seems to be such a simple requirement but apparently it's anything but that...
My current workaround for this is, although rather cumbersome, to subclass the FormView class and use subclassed controls in it, implementing my own data binding logic (taking the data field name from a new property) instead of using the <%# %> syntax. Apparently, the code the latter generates is the real culprit here as it doesn't support this nested control scenario.
I ended up, using old asp include statement
<--%include file = "filename" -->
instead of using user controls for dealing with the code duplication issue.

How do I develop an online survey application?

I want to develop application that contain number of question with independent radiobuttonlist which contain three option Yes, No, Unsure.
Daily visitors comes on the site & reply to the question. Also to show addition of the Yes, NO & Unsure in front of each question.
Please give me idea how to do such functionalty.
Regards,
Girish
Quickest and easiest way would be to piggy-back on an existing site.
http://www.polldaddy.com/ will allow you to embed polls in your own site
This is a very vague question and probably won't get much of an answer.
What technology do you want to use, .Net, Java. PHP etc, what resources do you have available?
Essentially you need some sort of database to store the questions and answers in and a front end web application built in whatever technology you decide on (as stated .net, Java or PHP are probably the most common).
Create a custom control that uses an Update Panel. Inside the update Panel you will have two PlaceHolders - 1 for your questions and 1 for your results. Hide the results placeholder by default. Once the radiobutton (OnSelectedIndexChanged) is selected, cause a postback and calculate the results. In the same Postback method, hide the Question placeholder and show the results placeholder with the calculated results.
Your page could look like this:
<UpdatePanel ID="upPanel" runat="server">
<ContentTemplate>
<asp:PlaceHolder ID="plcQuestion" runat="server">
Have you ever written asp.net code?
<asp:RadioButtonList ID="radList" AutoPostBack="true" OnSelectedIndexChanged="doStuff">
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
<asp:ListItem>Unsure</asp:ListItem>
</asp:RadioButtonList>
</asp:PLaceholder>
<asp:PlaceHolder ID="plcAnswers" runat="server" Visible="false">
Results:
Yes: <asp:Label ID="lblYesResults" runat="server" />
No: <asp:Label ID="lblNoResults" runat="server" />
Unsure: <asp:Label ID="lblUnsureResults" runat="server" />
</asp:PLaceholder>
</ContentTemplate>
</UpdatePanel>
Then, on your "doStuff" method, just save the results and populate whatever result display you are going for. Hope this helps!

asp.net - Use ascx as a layout template

This is my layout template (ascx without code behind)
<%# Control Language="C#" AutoEventWireup="true" Inherits="ws.helpers.LayoutUC" %>
<div>blah blah blah</div>
<ws:Panel runat="server" ID="left"></ws:Panel>
<ws:Panel runat="server" ID="main"></ws:Panel>
<ws:Panel runat="server" ID="right"></ws:Panel>
Modules will be added into ws:Panel later.
I also allow my user create their own ascx file to custom their page layout. And because of this i do a string replace all dangerous part like script tag (runat="server"), all asp.net html tag, <%, <%#, <#.... from their custom.
Im not worry about XSS, so dont comment on it, and ask why?
I want know your thinking about this. Is is safe? Is it scalable? Is it standard or a bad way?
Have a look at the INaminingContainer Interface http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx.
<asp:YourControl>
<LeftColumn>
<asp:Literal ID="literal1" runat="server" Text="User created literal" />
</LeftColumn>
</asp:YourControl>
In the .ascx from the users, they register your control and insert asp.net code into properties. In the 'YourControl' class you create placeholders and insert the markup set to a specific property into these placeholders. (e.g. everything between <LeftColumn> and </LeftColumn> will the inserted into
<asp:Placeholder ID="PlaceholderLeftColumn" runat="server"/>
Edit: I summed some of the TemplateContainer issue up and posted it here: http://www.tomot.de/en-us/article/2/asp.net/how-to-create-an-asp.net-control-that-behaves-as-a-template-container-to-nest-content-via-markup
You are allowing user-uploaded content; this is inherently unsafe and there are whole books dedicated to best practices. Given that you are doing it anyway, as long as you make sure you scrub the input, is it scalable? You are allowing creation of user-uploaded files on your site. How many will there be? How many users? What about load-balancing? This solution will not scale for many users, files, or servers.
It sounds like you are trying to create a simple CMS. Why not use one that exists currently, or adopt parts of an open source solution?

One user control updating another during AJAX Postback?

I developed a user control that displays a list of products and it works pretty good. Then I dropped this user control into another user control that allows the user to pick different criteria and the product UC updates to show those products, all pretty slick and with AJAX via UpdatePanel.
All was working just fine... then another requirement came in. The "search" control needs to be separate from the product control (so they can be positioned separately). Initially, I thought this was no problem as I would give the search control a reference to the product control and then it would talk to it via reference instead of directly inside the control (which has been removed).
And they do talk. But the product control loads, but refuses to display.
I checked and it is being passed via reference and not a copy ( as best I can tell ).
There is an updatepanel in the search control. There is an update panel in the product control. And then for good measure, there is an update panel surrounding them both in the actual search aspx page.
I've tried setting the product control update panel to conditional and then fire the .Update() method manually.
What's the secret here?
TIA!
SOLVED
Thanks to Jamie Ide for the tip to use events.
Search Control and Product control still have internal update panels, and NO LONGER have them on this particular page.
Search Control now raises an event OnSearchResultsUpdated and exposes the found items in properties. The page subscribes to this event and takes the properties and passes them to the product control and triggers triggers a .Refresh() method on the product control which simply calls the .Update() on its internal updatepanel.
The Product control, FYI, accepts products in several different flavors. A list of distinct SKUs, a list of product ids, a named collection in our database and finally a given product category.
Our designers need to be able to create a new page, drop the control onto it and set some properties and voila! New site page. They don't want to require a programmer's involvement. So keeping the controls self contained is a requirement. Fortunately all the changes I made still work completely with the other uses of the product control.
THANKS AGAIN SO MUCH!
I don't think there's really enough information to work with here, but my best guess is that the Product control is not getting data bound. You may try calling myProdcutsCtrl.DataBind() from the search control (or something inside the Product control that cause a DataBind() for instance myProductCtrl.Search(value1, value2, value3).
One other thing you might try is removing the UpdatePanels and seeing if things work. Then add them back in once you get core functionality going.
UPDATE: I've gone ahead and put some example code that works here which I believe accomplishes what you want. What follows are snippets for the sake of saving space, but include all code necessary to make it run. Hopefully this will at least give you something for reference.
Things to try:
EnablePartialRendering="true|false" setting it to false will force the natural postbacks and is good for debugging UpdatePanel problems.
Make sure you are seeing Loading... come up on your screen. (maybe too fast depending on your dev computer)
Page.aspx
<%# Register Src="~/Product.ascx" TagPrefix="uc" TagName="Product" %>
<%# Register Src="~/Search.ascx" TagPrefix="uc" TagName="Search" %>
...
<asp:ScriptManager runat="server" ID="sm" EnablePartialRendering="true" />
Loaded <asp:Label ID="Label1" runat="server"><%= DateTime.Now %></asp:Label>
<asp:UpdateProgress runat="server" ID="progress" DynamicLayout="true">
<ProgressTemplate><b>Loading...</b></ProgressTemplate>
</asp:UpdateProgress>
<uc:Search runat="server" ID="search" ProdcutControlId="product" />
<uc:Product runat="server" ID="product" />
Search.ascx
<asp:UpdatePanel runat="server" ID="searchUpdate" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<p>
<asp:Label runat="server" AssociatedControlID="filter">Less than</asp:Label>
<asp:TextBox runat="server" ID="filter" MaxLength="3" />
<asp:Button runat="server" ID="search" Text="Search" OnClick="SearchClick" />
</p>
</ContentTemplate>
</asp:UpdatePanel>
Search.ascx.cs
public string ProdcutControlId { get; set; }
protected void SearchClick(object sender, EventArgs e)
{
Product c = this.NamingContainer.FindControl(ProdcutControlId) as Product;
if (c != null)
{
c.Search(filter.Text);
}
}
Product.ascx
<asp:UpdatePanel runat="server" ID="productUpdate" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:Label runat="server">Request at <%= DateTime.Now %></asp:Label>
<asp:ListView runat="server" ID="product">
<LayoutTemplate>
<ul>
<li id="itemPlaceHolder" runat="server" />
</ul></LayoutTemplate>
<ItemTemplate>
<li><%# Container.DataItem %></li></ItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
Product.ascx.cs
IEnumerable<int> values = Enumerable.Range(0, 25);
public void Search(string val)
{
int limit;
if (int.TryParse(val, out limit))
product.DataSource = values.Where(i => i < limit);
else
product.DataSource = values;
product.DataBind();
productUpdate.Update();
}
Code does NOT represent best practices, just a simple example!
I'm fairly new to AJAX, but I don't think it's a good idea for user controls to have UpdatePanels. I would also advise you not to have the user controls reference each other; they should communicate through events and methods controlled by their container.
I do something similar with two user controls for a master-details display. The master raises an event when an item is selected from a list, the containing page handles the event and calls a method on the details display to display the selected item. If I remember correctly, my first attempt had UpdatePanels in the user controls and I wasn't able to make that work. Having the user controls inside an UpdatePanel on the page works fine.
If I understand you right you have a layout like this:
Outer UpdatePanel
SearchControl
Search UpdatePanel
ProductControl
Product UpdatePanel
Databound Control
Which one of those update panels is actually being called?
I assume that if you check the network traffic with something like Fiddler or Firebug if you're using Firefox, you aren't seeing any HTML for the product update panel coming back?
Have you tried doing something like:
UpdatePanel productUpdate =
Page.FindControl("Product UpdatePanel") as UpdatePanel;
if (null != productUpdate){
productUpdate.Update();
}
By default, if a postback is made from an UpdatePanel, only that control will be updated/re-rendered (this is called partial page-rendering).
To also update/re-render other UpdatePanels, you have to either:
set their UpdateMode property to Always
add the control that makes the postback to their Triggers collection
Check this page in MSDN for details.

Aspx Property Interpolation

I'm a bit new to .Net development, been working in Java for some time now. I have an aspx page and we need to externalize some strings to make it more flexible.
If I have a table somewhere and there is just a string sitting outside an asp tag, I can replace it so that
<th> Specific Foo String </th>
becomes
<th> <%= Strings.foo %> </th>
and everything is fine, the problem I'm running into is how do you do this kind of interpolation on an asp tag property
I tried changing
<asp:Label runat="server" ID="lblFoo" Text="Specific Foo String Entry" />
to
<asp:Label runat="server" ID="lblFoo" Text='<%= Strings.foo %> Entry' />
and
<asp:Label runat="server" ID="lblFoo" Text='<%#Eval("Strings.foo") %> Entry' />
but neither worked. Is what I'm doing not possible in the aspx file, I know that I can simulate this by rewriting their properties in the code behind, but that's a level of overhead I'd rather not deal with.
Thanks
I think you are looking to do this:
<asp:Label runat="server" id="label1" Text='<%# Strings.Foo + " Entry"%>' />
Then in your code behind (most likely in your OnPageLoad) you need to call
if(!Page.IsPostBack) Page.DataBind();
You need to be cautious however as calling DataBind on controls like textboxes or any labels that may have changed due to logic in the code behind will have their values overwritten with the bound values. Checking that you are not on a post back can help with this, but there are still gotchas.
Also note that I had to move the " Entry" text into the binding statement. If it is placed outside the last '%>' then the binding does not work and it will spit out:
<%# Strings.foo %> Entry
In the codebehind of the page you would do this:
lblFoo.Text = Strings.foo + " Entry";
A good place to put this code would be in the overriden OnLoad method but that is simply a suggestion as I am unfamiliar with your application and the life cycle needs of your page.
If you want to do all this in the aspx page then simply do this:
<span><%= Strings.foo %> Entry</span>
as a Label renders as a span anyhow.
If your objective is an HTML table of strings, then you can create either a ListView or a GridView and DataBind to that. It would save you the trouble of writing out all of your properties and will also produce the correct table tags for the data.
Without knowing more about your data, I cannot provide a detailed code snippet.
You're talking about resources. Read Basic Instincts Resources and Localization in ASP.NET 2.0 which shows you the built in resource editor, and how to use the "<%$ ... %>"-binding, or using meta:resourceKey attribute.

Resources