best practices for dynamic content - c#

I have a pretty extensive Classic ASP background (using server-side javascript), and my company is finally (FINALLY) making the push towards recoding everything in ASP.Net (using C#). I have a good grasp on good programming practices in Classic ASP and I usually try to make sure I code things the "right" way. I've been reading ASP.Net tutorials and feel like I have a pretty understanding of the basics. I have good discipline about separating client side javascript into external js files, keeping styling outside of the markup in external css files, etc. So, when reading these novice tutorials I understand the concept of the code-behind pages. It makes sense to me to separate the c# code from what will ultimately become the markup for the page. Making < asp:button > objects and the code-behind rules to alter them makes perfect sense.
However, I'm having a hard time wrapping my head around how to do something simple like I would have done in Classic ASP like this:
<%
if (condition) {
%>
<input type="button" value="click me" onclick="dosomething()" />
<%
}
else {
%>
<span>You don't have permission to see the button</span>
<%
}
%>
I'm having a hard time trying to figure out how I'm supposed to fit the conditional stuff you see above into the code-behind page. If I was showing a button under both circumstances, I'd make an <asp:button> object and style it in the code-behind page accordingly - but in the example above I'm only showing the button if the condition is true, and a span block if false.
I know that you don't HAVE to put ALL the c# code in the code-behind page. I can use the <% %> tags the same way I would do in Classic ASP. But, if I do that then it seems to me that it lessens the relevance of the code-behind page. For example, I know you can use an external css stylesheet to stylize your page and at the same time use inline styles on individual tags as well. I believe this to be poor practice, however. It makes it difficult to later have to adjust the styles on that element if you don't know whether to look in the markup or in the css file to find the relevant styles affecting that element.
It seems to me that the same would hold true for your markup and code-behind pages. Is it just a necessary evil to have to mix the 2, or is there a better way to do what I'm demonstrating above?

You could have in your markup:
<asp:Button .. Visible="False" />
<asp:Label .. Text="You do not have permissions" Visible="False" />
Note the Visible property. ASP.NET web forms is build on the idea of an object model, so the button and label are objects you can work with. In the code behind, you can have:
protected void Page_Load(object sender, EventArgs e) {
.
.
if (Xcondition = true) {
Button1.visible= true;
Label2.Visible = false;
}
else {
Button1.visible= false;
Label2.Visible = true;
}
}
Is the traditional way to accomplish this. You just have to figure out where in the lifecycle you need to do this, as load may not be the best (Init or PreRender event, for instance). If you only need to do this at startup once, do if (!Page.IsPostBack) { .. } to ensure it only runs once.

I made a small example that you can basically just copy/paste and mess around with a little.
This is the aspx code:
< body>
<form id="form1" runat="server">
<div>
<asp:TextBox runat="server" ID="txtCondition"></asp:TextBox>
<asp:Button runat="server" Text="Check condition" ID="btnCheckCondition" OnClick="btnCheckCondition_Click" />
<asp:Button runat="server" Text="Click me" ID="btnSubmit" OnClick="btnSubmit_Click" Visible="false"/>
<asp:Label runat="server" ID="lblMsg"></asp:Label>
</div>
</form>
</body>
this is the code behind: (if you double click on the btnCheckCondition, the click_event method will be automatically generated in your codebehind.
protected void btnCheckCondition_Click(object sender, EventArgs e)
{
if (txtCondition.Text == "Show the button")
{
btnSubmit.Visible = true;
lblMsg.Text = "You are allowed to see the button.";
}
else
{
lblMsg.Text = "You are NOT allowed to see the button.";
}
}
This will basically check the input in the textbox txtCondition. If it is equal to "Show the button", the second button will become visible. If the text is something else, the button will not appear and a label will say that you are not allowed to see the button.

have a label and a button in the page. check the condition from code behind and based on the condition, hide or show the control. you can use visibility attribute of the controls to hide or show them. Also use asp.net controls so that you can access them from code behind.

Unless you have a good reason not to, use the Visible property. (In ASP.NET Web Forms, you're asking for trouble if you change the structure of the component tree dynamically other than using repeater controls.) What I do is:
Page.aspx
<button type='button' Visible='<%# condition %>' runat='server'>
Click Me!
</button>
<span Visible='<%# !condition %>' runat='server'>
No button for you!
</span>
Page.aspx.cs
protected void Page_Load() {
if (!IsPostBack) DataBind(); // evaluates <%# ... %> expressions
}
(My preference is to make controls to "pull" data from code-behind instead of pushing it there, and use anonymous and plain HTML controls over their heavier equivalents when possible.) Any way of setting Visible before the page renders will work though.

First to help you with the easy way, to been able the condition to been recognized you need to define it and make it public on code behind. For example:
<%if (condition) {%>
<input type="button" value="click me" onclick="dosomething()" />
<%}else { %>
<span>You don't have permission to see the button</span>
<% } %>
and on code behind
public partial class OnePage : System.Web.UI.Page
{
public bool condition = false;
protected void Page_Load(object sender, EventArgs e)
{
// here change the condition
}
}
Second case with function call
<%if (fCheckAuth()) {%>
<input type="button" value="click me" onclick="dosomething()" />
<%}else { %>
<span>You don't have permission to see the button</span>
<% } %>
and on code behind
public partial class OnePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public bool fCheckAuth()
{
// return your evaluate
return false;
}
}
More asp.net form style
Now, working with the new asp.net (compared with the classic asp) you can also do that (and similar to that).
<asp:Panel runat="server" ID="pnlShowA">
<input type="button" value="click me" onclick="dosomething()" />
</asp:Panel>
<asp:Panel runat="server" ID="pnlShowB">
<span>You don't have permission to see the button</span>
</asp:Panel>
Use one asp:Panel to warp your full content, and on code behind you open it and close it.
public partial class OnePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (condition)
{
pnlShowA.Visible = true;
pnlShowB.Visible = false;
}
else
{
pnlShowA.Visible = false;
pnlShowB.Visible = true;
}
}
}

While the question is not about using ASP.NET Web Forms versus ASP.Net MVC. I felt compelled to point out that it may be more beneficial going with ASP.NET MVC rather than ASP.NET Web Forms in your scenario.
I say this because Classic ASP and ASP.NET MVC inline style is similar. In most cases you could probably convert ASP (<% %>) to Razor(a different flavor of in-lining server-side code with HTML) with little modification to the underlining logic. I don't know about you but the less code I have to write the better. For example, your above code would convert to the following Razor syntax:
#if (condition) {
<input type="button" value="click me" onclick="dosomething()" />
}
else {
<span>You don't have permission to see the button</span>
}
To answer your question, I would disable the button on the server-side. Have a disabled on the client. In the case the button is disabled, enable the Label with the appropriate text.
//Code-behind
bool correctPermission = true;
submit.Enabled = correctPermission;
noPermissionMessage.Enabled = !correctPermission;
//Client Code
<asp:Button ID="submit" runat="server" Text="Click Me" />
<asp:Label ID="noPermissionMessage" runat="server" Text="You don't have permission to see the button" Enabled="false" />

Related

Using ASP.NET to Hide an HTML Div

I am using ASP.NET for a web page in order to make some server calls that involve looking up user organization information. Based on that information, we need to either hide or display a div. In the header I have a C# function that definitely runs. I have tried the following lines to hide the div.
divID.Style.Add("display","none");
and
divID.Visible = false;
In the body, I am currently using an asp:Panel that runs at server and contains the id "divID". No matter what I do, I can't get the div to hide (without manually putting the styling in). I tried putting the scripts before and after the body, and it didn't make a difference. Any suggestions on the best way to do this would be appreciated.
EDIT:
Here is the C# initiating code.
<script runat="server" language="C#">
void getUserInfo(Object sender, EventArgs ev){
The rest of the C# code is irrelevant, but the relevant line shown above is definitely being run.
The HTML portion looks something like this.
<asp:Panel runat="server" id="divID" style="width:200px; height:130px; ">
<div style="text-align:center">Test Data</div>
</asp:Panel>
C# code is always compiled and run from the server-side, and so cannot impact the state of a page once rendered unless you use postbacks or callbacks. If you want to change the visible state of a control on the client-side, you will need to use Javascript on the client side (possibly triggered by a button click) to show and hide the control.
As an example, check out the solution at the link below.
https://forums.asp.net/t/1603211.aspx?Show+hide+div+on+button+click+without+postback
<script type="text/javascript">
function ToggleDiv(Flag) {
if (Flag == "first") {
document.getElementById('dvFirstDiv').style.display = 'block';
document.getElementById('dvSecondDiv').style.display = 'none';
}
else {
document.getElementById('dvFirstDiv').style.display = 'none';
document.getElementById('dvSecondDiv').style.display = 'block';
}
}
</script>
<asp:Button ID="btn" runat="server" Text="Show First Div"
OnClientClick="ToggleDiv('first');return false;" />
<asp:Button ID="Button1" runat="server" Text="Show Second Div"
OnClientClick="ToggleDiv('second');return false;" />
<br />
<div id="dvFirstDiv" style="display: none;">
First Div
</div>
<div id="dvSecondDiv" style="display: none;">
Second Div
</div>
In the header I have a C# function that definitely runs.
If you're talking about the HTML page header - no, it definitely not running. C# code is executed only server side.
Based on your post, I'm assuming we're talking WebForms here and yo have a script block in your aspx file. While this is fine, I recommend placing the server-side code into a code behind file.
So all you need to do is to add a handler for the PreRender phase of the page life cycle and place your logic for showing/hiding the div in there.
public void Page_Prerender(object sender, EventArgs e)
{
divID.Visible = false;
' OR
'divID.Style.Add("display","none");
}
Note that setting the Visible property of a WebForms control excludes the control from rendering to the page, whilst setting display: none renders it as HTML but it isn't displayed on the page.
Try in backcode: divID.Controls.clear();
This worked for me.

Displaying a div on a button click in asp.net

I want to display a particular div on the click of a button
My asp code is as follows
<asp:Button ID="Button1" class="btn" runat="server" OnClick="Submit" />
<div runat="server" id="signup" Visible="false">Some Content </div>
Now in the CodeBehind i have written the following code
protected void Submit(object sender, EventArgs e)
{
Button1.Visible = false;
signup.Visible = true;
}
But every time i get the error as
the name signup does't exist in the current context
i am not able to figure out the problem in the code..
You probably have wrong html for the div, you can also use style="visible:none" instead of Visible="false"
Change
visible:"false"
To
Visible="false"
This has to be done through JavaScript, I believe in the onClientClick attribute of the button. I'm currently searching for the code to jog my own

asp post back issue and html controls

My html.
<input id="rdb1" type="radio" name="rdbData" checked="checked" />
<input id="rdb2" type="radio" name="rdbData" />
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
Button is only asp:button but radio buttons are not.First time when page is load rdb1 is selected.But when i click the button btnTest with check rdb2, page is refreshed and select 1st redio button.To prevent this i try jquery like this.
Inside Document.ready:
var btnTest = "<%=btnTest.ClientID %>";
$('#' + btnTest).bind("click", function() {
if ($('#rdb1').attr("checked")) {
$('#rdb2').attr("checked", false);
$('#rdb1').attr("checked", true);
}
else {
$('#rdb1').attr("checked", false);
$('#rdb2').attr("checked", true);
}
});
But its not work.How can we handle this type of situation.Where i am getting wrong.Any idea or any alternative.Thanks.
If that is the request I would suggest you have a hidden field (server side) which will keep the state of which input radio button is selected (use jquery to update the hidden field when user clicks on the radio buttons). Then on postback as the hidden field is set at runat="server" it will maintain its value (viewstate) and you can simply use jquery to set the right radio button as selected. Does that make sense ?
I repeat that the requirement is ABSURD. How are they going to tell you used server-side controls without looking at the code anyway. This is like requiring that you write the code using chopsticks or something.
However just as an exercise I provide the following solution:
<input id="rdb1" type="radio" name="rbdData" value="rbd1" <%= Rdb1Checked %> />
<input id="rdb2" type="radio" name="rbdData" value="rbd2" <%= Rdb2Checked %> />
<asp:Button ID="btnTest" runat="server" Text="Test" onclick="btnTest_Click" />
And the code behind:
protected string Rdb1Checked
{
get
{
if (IsPostBack)
{
if (Request["rbdData"] == "rbd1")
{
return "checked";
}
else
{
return "";
}
}
return "checked";
}
}
protected string Rdb2Checked
{
get
{
if (IsPostBack)
{
if (Request["rbdData"] == "rbd2")
{
return "checked";
}
else
{
return "";
}
}
return "";
}
}
Ask why they have these requirements. Maybe they don't want to see the client IDs in which case you may set the ClientIDMode to Static and avoid auto generated IDs. You can remove them completely by setting them to null, etc. Maybe they don't like what Web Forms renders for Radio buttons in which case using server side inputs would be OK. The requirement on its own simply does not make sense.
Shree
The fact is that client click (added by jQuery) executes before the call to server. If you want to persist the selectin, try using server sided controls:
<input id="rdb1" type="radio" name="rdbData" checked="true" runat="server" />
<input id="rdb2" type="radio" name="rdbData" runat="server" />
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
Try this if it does work for you.
Hope it helps.
When the "Test" button is clicked, the page posts back to the server, which re-renders all client-side controls just as if the page has been loaded for the first time. Since the entire page is reloaded, jQuery will also "forget" about the state of the controls, so that approach won't work either. The simplest way to prevent this is to ensure the radio buttons run on the server side. For instance:
<asp:RadioButton id="rdb1" Checked="True" GroupName="RadioGroup1" runat="server" />
<asp:RadioButton id="rdb2" GroupName="RadioGroup1" runat="server" />
Hope that helps!
What do you mean? That you have a requirement that does not let you use "servr side controls" or that your IDE does not allow that?
By definition, in ASP.NET all HTML controls inherit from a server control. Simply adding runat="server", you can access that control from codebehind, although it will still render in page as a normal HTML control.

How to handle validation when JavaScript is disabled in ASP.NET

I'm using some of the typical ASP.NET's Validation Controls in my website. Now I'm trying to disable the JavaScript in my browser to test my application and of course the Validation Controls no longer works. I think it's best to try to make them work using one of the suggested solutions down here instead of reinvesting the wheel and build a validation layer for the page or my objects -Am I thinking right?-
What do you think of these options and why:
Include in clicked button's event a code to check if the page is valid and if not explicitly call the Page.Validate(); method
Check if whether the JavaScript is enabled and if not I should call Page.Validate();
If you there's a better way to do it please let me know.
Javascript form validation is purely for user convenience. This stops them from submitting a form with an invalid phone number or whatever.
All inputs should actually be validated on the server when whatever request is being made is received. Here's the ideal flow, and you'll see that a browser not having javascript enabled is no big deal:
browser -> javascript validation (optional) -> server validation (if this fails, go back to initial page with errors)
So even if they have no JS, the page still submits the data, then you can return an error from the server. This is a poorer user experience typically (full page reload, potential retyping of inputs unless you repopulate the forms) which is why JS is often included in validation schemes.
The validation controls are designed to validate primarily on the server side. The client-side validation is optional (see the EnableClientScript property). So if they aren't working with Javascript disabled, then you're probably missing a little boilerplate code in your page, such as this snippet from the MSDN documentation on Page.IsValid:
private void ValidateBtn_Click(Object Sender, EventArgs E)
{
Page.Validate();
if (Page.IsValid == true) // yes, it is written this way in the MSDN documentation
lblOutput.Text = "Page is Valid!";
else
lblOutput.Text = "Some required fields are empty.";
}
You can also call Page.Validate and check Page.IsValid in your Page's OnLoad event, so that you can prevent a postback from proceeding to the next step when the form needs to be re-submitted. You probably don't even need to call Validate() explicitly — Button.CausesValidation is true by default.
You will need to do custom Server Side validation... http://msdn.microsoft.com/en-us/library/aa479013.aspx (information toward the bottom)
Something like this:
<%# Page Language="C#" %>
<script runat="server">
void Button1_Click(Object sender, EventArgs e) {
if (Page.IsValid) {
Label1.Text = "VALID ENTRY!";
}
}
void ValidateNumber(object source, ServerValidateEventArgs args)
{
try
{
int num = int.Parse(args.Value);
args.IsValid = ((num%5) == 0);
}
catch(Exception ex)
{
args.IsValid = false;
}
}
</script>
<html>
<head>
</head>
<body>
<form runat="server">
<p>
Number:
<asp:TextBox id="TextBox1"
runat="server"></asp:TextBox>
<asp:CustomValidator id="CustomValidator1"
runat="server" ControlToValidate="TextBox1"
ErrorMessage="Number must be even"
OnServerValidate="ValidateNumber"></asp:CustomValidator>
</p>
<p>
<asp:Button id="Button1" onclick="Button1_Click"
runat="server" Text="Button"></asp:Button>
</p>
<p>
<asp:Label id="Label1" runat="server"></asp:Label>
</p>
</form>
</body>
</html>

Accessing Code Behind for a Control in a Master Page

I need to display a control consistently across a set of pages. So I'm using a MasterPage to do that in ASP.NET/C#. However I also need to programmatically access this control, mostly provide options to view/hide depending on whether the controls checkbox is clicked.
Here is the Source for the MasterPage
<div id="verifyInitial" runat="server">
<asp:CheckBox ID="chkInitialVerify" runat="server"
oncheckedchanged="chkInitialVerify_CheckedChanged" />
I agree that my initial data is correct.
</div>
<div id="verifyContinuous" runat="server">
<asp:CheckBox ID="chkContinuousVerify" runat="server"
oncheckedchanged="chkContinuousVerify_CheckedChanged" />
I agree that my continuous data is correct
</div>
Now in the code behind I want to perform the following operations. Basically if a person clicks on the checkbox for the initial div box, then the initial box disappears and the continous box shows up. However it seems that the code behind for the MasterPage does not activate whenver I click on the checkbox. Is that just the way MasterPages are designed? I always thought you could do add some sort of control functionality beyond utilizing the Page Load on the Master Page.
protected void chkInitialVerify_CheckedChanged(object sender, EventArgs e)
{
verifyContinuous.Visible = true;
verifyInitial.Visible = false;
}
protected void chkContinuousVerify_CheckedChanged(object sender, EventArgs e)
{
verifyContinuous.Visible = false;
}
If you're expecting the two controls to trigger a change for that page immediately then you'll need to set the AutoPostBack property to true for both of them:
<div id="verifyInitial" runat="server">
<asp:CheckBox ID="chkInitialVerify" runat="server" oncheckedchanged="chkInitialVerify_CheckedChanged" AutoPostBack="true" />
I agree that my initial data is correct.
</div>
<div id="verifyContinuous" runat="server">
<asp:CheckBox ID="chkContinuousVerify" runat="server" oncheckedchanged="chkContinuousVerify_CheckedChanged" AutoPostBack="true" />
I agree that my continuous data is correct
</div>
Otherwise, you need an <asp:button /> or some other control on the page to trigger a postback and cause your event handlers to run. The button, or other control, can either be on your masterpage or on your content page, the choice is entirely yours.

Categories

Resources