Any suggestions to load a html page saved in the database?
html:
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>xxx</title>
</head>
<body>
<form id="Form1" runat="server" method="post">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
</form>
</body>
codebehind:
protected override void OnInit(EventArgs e)
{
this.IniciarFormulario();
using (ServicoECMClient proxy = new ServicoECMClient())
{
tipoDocumento = proxy.ObterTipoDocumento(int.Parse(tipoDocumentoID));
}
if (tipoDocumento == null)
{
throw new ApplicationException();
}
this.Page.Header.InnerHtml = tipoDocumento.estilo; //css
this.Page.Form.InnerHtml = tipoDocumento.form; // form
base.OnInit(e);
}
I can not retrieve the form values.
Look:
foreach (System.Web.UI.Control controle in this.Form1.Controls)
{
if (controle.GetType().Name == "HtmlInputText" || controle.GetType().Name == "HtmlInputSelect"
|| controle.GetType().Name == "HtmlInputRadio" || controle.GetType().Name == "HtmlInputTextCheckbox")
{
if (!string.IsNullOrEmpty(this.Request[controle.ClientID]))
{
documento_indice documentoIndice = new documento_indice();
documentoIndice.id_indice = int.Parse(controle.ClientID.Split('_')[1]);
documentoIndice.valor = this.Request[controle.ClientID];
documentoIndice.timestamp = DateTime.Now;
documentos_indices.Add(documentoIndice);
}
}
}
Controls is empty. => this.Form1.Controls
Any Suggestion?
There's another better way to do?
Thanks.
The short answer is, yes you can get this functionality to work. We provide all of our customer-specific customizations in a manner similar to this.
The long answer is that it will require some restructuring of your application and HTML.
The easiest way that we found to implement this is through UserControls. The basic approach is:
1) Create your page content that is stored in the DB as a UserControl, i.e.
<%# Control Language="vb" AutoEventWireup="false" %>
<input id="txtTest" type="text" runat="server" />
2) When you extract it from the DB, store it in a file on disk with an ascx extension (say content.ascx for now).
3) Modify your main page to add a div that runs at the server that the ascx will be loaded into:
<div id="divContent" runat="server">
</div>
4) In page init, load the control into the div and initialize it:
Dim oControl As Control
' Load a user control
oControl = Me.LoadControl("content.ascx")
If oControl IsNot Nothing Then
' Ensure viewstate is enabled
oControl.EnableViewState = True
' Set properties as required
oControl.ID = "ContentControl"
' Clear the existing control(s) from the content container
Me.divContent.Controls.Clear()
' And add the new one
Me.divContent.Controls.Add(oControl)
End If
5) Access the collection of controls contained in the div control.
Note that on a page postback the controls will not have content loaded into them until the page load event is fired due to the standard page lifecycle.
I have verified that codebehind is not required and this works correctly exactly as described above.
Unless you add the controls to the controls collection by hand (a tricky business) you're going to need to read your form values the old-fashioned way:
Request.Form["txtSomething"]
That means you can get the string values contained in your controls if you know their names, but not much else.
Related
This question might have already been asked, but I could not find any references to it so I apologize if it seems like a duplicate question.
What I'm trying to do is create a generic DialogBox as an ASP.NET UserControl; which would contain all the script required to create the dialog using jQuery. The dialog has a fixed set of buttons, but I'd like to be able to let the user define the content when they create the dialog. Suppose this is the markup for the user control:
<head>
<script type="text/javascript">
// jQuery script to create the dialog
</script>
</head>
<body>
<div runat="server" id="divContainer">
<!--Html Content Placeholder. What goes here?-->
</div>
</body>
And the code-behind:
[ParseChildren(true, "Contents")]
public partial class UCDialogBox : ExtendedUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Page.DataBind();
}
public List<Control> Contents { get; set; }
public DialogType Type { get; set; }
public string Title { get; set; }
}
And on the actual page after registering the control, I would like to be able to do something like this:
<uc:DialogBox runat="server">
<div>
<label>Hello World</label>
</div>
</uc:DialogBox>
The problem with this is, List<Control> only allows for ASP.NET controls. Normal HTML controls (such as what I have above) won't work.
Question 1: What type should I use to allow any HTML control to be nested inside the user control? I tried System.Web.UI.HtmlControls.HtmlControl but that didn't work either (ASP.NET says The element 'div' cannot be nested within the element 'dialogbox').
Question 2 What would I put as an HTML content placeholder on the user control which can be bound to the Contents property on the code behind? Something like
<SomePlaceholderControl DataSource="<%# Contents %>" />
Any help is appreciated.
Oddly enough, putting HTML controls inside the body of the user control doesn't cause a run-time error. In fact, the controls come across just fine. I guess it's just the designer that whines about it.
As for the placeholder, I didn't have to use any specific control; I simply used an HtmlTextWriter to render the controls into a well-formatted HTML string inside a method that gets called in the markup:
<div runat="server" id="divContainer">
<%# RenderContents() %>
</div>
And the code-behind method:
public string RenderContents()
{
StringWriter writer = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
foreach (var control in Contents)
{
control.RenderControl(htmlWriter);
}
return writer.ToString();
}
It works just fine.
I am not sure whether this is the correct approach, I have added a ITemplate inside the Dialog control and placed a HtmlGenericControl container which is Div control with runat = "server".
Now you can add the html controls and text inside this container.
<cc1:UCDialogBox ID="dialog" runat="server">
<HtmlPlaceHolder>
<div runat="server">
<h1>Title</h1>
<h2>Description</h2>
<div>Modal Content</div>
</div>
</HtmlPlaceHolder>
</cc1:UCDialogBox>
In custom server control you can get the container div content as innerHtml or innerText
public class UCDialogBox : WebControl, INamingContainer
{
private ITemplate htmlPlaceHolder = null;
[
Browsable(false),
DefaultValue(null),
Description("Add your html contorls"),
PersistenceMode(PersistenceMode.InnerProperty)
]
public virtual ITemplate HtmlPlaceHolder
{
get
{
return htmlPlaceHolder;
}
set
{
htmlPlaceHolder = value;
}
}
protected override void Render(HtmlTextWriter output)
{
HtmlGenericControl placeholder = new HtmlGenericControl();
htmlPlaceHolder.InstantiateIn(placeholder);
var html = placeholder.Controls[1] as System.Web.UI.HtmlControls.HtmlGenericControl;
var result = html.InnerHtml.Replace("\r", "").Replace("\n", "").Trim();
output.Write(result);
}
}
I have a user control in my master page under the login view under the Role groups.Here is the control.Its not in the content placeholder.However if i try to access it i get null result.How can i access this from my page code behind.I am having problem getting it from master page.
<asp:RoleGroup Roles="Students">
<ContentTemplate>
<uc1:studentsPanel runat="server" ID="studentcontrol" />
</ContentTemplate>
</asp:RoleGroup>
Here is how i am having my code
LoginView control = Page.Master.FindControl("studentcontrol") as LoginView;
if (control != null)
{
Label1.Text = "found";
}
Here's the code I use to get to controls in MasterPages
//Master page from user control
LoginControl control
Page page = (Page)this.Page;
MasterPage master = (MasterPage)page.Master;
control= (LoginControl )master.FindControl("studentcontrol");
if (control!= null)
{
Label1.Text = "found";
}
We can't see the whole code, but your snippets seem correct. Try first not to cast your control to LoginView - the reason might be that your panel is not of that type. To try out if the control is found at all, use
if(Page.Master.FindControl("studentcontrol") != null) {
Label1.Text = "found";
}
first before adding another possible source of failure.
There's two more explicit answers that don't need to be repeated here. You find wonderful explanations here and here.
as #Krishnraj said,
i dont know which is control within studentsPanel UserControl, but i assume that Label. You should access like that,
var Loginview = (Master.FindControl("LoginView1") as LoginView);
Control cont = new Control();
Loginview.RoleGroups[0].ContentTemplate.InstantiateIn(cont);
(cont.Controls[1].FindControl("_trylbl") as Label).Text = "Hello say";
How to check if ContentPlaceHolder is absolutely empty?
In the ContentPlaceHolder have text only, without tags and controls.
Example Page.Master:
<asp:ContentPlaceHolder runat="server" ID="Content" />
Example Test.aspx:
<asp:Content runat="server" ContentPlaceHolderID="Content">
Custom text without controls. Content.Controls.Count is 0 and Content.HasControls is false.
</asp:Content>
What I need to do is that when the placeholder is empty put a default content is in another control.
Overwrite tried twice for the same placeholder but I get error when dynamic load.
You can implement a method that will render the content control into a string, then check the string to find wheahter it contains any non-white space chars:
private bool HasContent(Control ctrl)
{
var sb = new System.Text.StringBuilder();
using (var sw = new System.IO.StringWriter(sb))
{
using(var tw = new HtmlTextWriter(sw))
{
ctrl.RenderControl(tw);
}
}
var output = sb.ToString().Trim();
return !String.IsNullOrEmpty(output);
}
protected void Page_PreRender(object sender, EventArgs e)
{
var placeholder = Master.FindControl("FeaturedContent");
var hasContent = HasContent(placeholder);
}
You need to find the ContentPLaceHolder on the master page first. Then you can cast the first control(which always exists) to LiteralControl and use it's Text property.
So this works as expected from Page_Load of the content-page:
protected void Page_Load(object sender, EventArgs e)
{
var cph = Page.Master.FindControl("Content") as ContentPlaceHolder;
if (contentPlaceHolder != null)
{
string textualContent = ((LiteralControl) cph.Controls[0]).Text;
if (string.IsNullOrEmpty(textualContent))
{
// ...
}
}
}
This seems to have changed, because I am seeing in 4.5 that HasControls DOES return true when there is only literal text in the Content, even a single whitespace. I do something like this in my master page:
<asp:Panel id="SidebarPanel" CssClass="Sidebar" runat="server">
<asp:ContentPlaceHolder id="SidebarContent" runat="server" />
</asp:Panel>
Sub Page_Load(...)
SidebarPanel.Visible = SidebarContent.HasControls
End Sub
This renders the sidebar content, if there is any, inside a <div class="Sidebar"> -- and avoids creating an empty div on the page when there's no content.
I really didn't want to run all the code for a render or risk that maybe some controls might have states that change after being rendered. So I came up with another approach.
public static int ChildrenCount(ContentPlaceHolder placeholder)
{
int total = 0;
total += placeholder.Controls.OfType<Control>().Where(x =>
(!(x is ContentPlaceHolder) && !(x is LiteralControl)) ||
(x is LiteralControl && !string.IsNullOrWhiteSpace(((LiteralControl)x).Text))
).Count();
foreach (var child in placeholder.Controls.OfType<ContentPlaceHolder>())
total += ChildrenCount(child);
return total;
}
For me the text I'd place directly into a Content element would be returned by OfType as a LiteralControl with the appropriate contents. Not only this but my formatting ("\r\n\t") would also be returned the same way. I'd also get ContentPlaceholders for subsequent master pages as they passed the slot in my web pages to the next master page or actual page.
So the task now is to get a count of controls that excludes these ContentPlaceholders and also excludes LiteralControls which are whitespace. This is pretty easy using the is operator. We'll just make sure a given control is neither of those types and then count it, or if it is a Literal we check if the contents are all whitespace or not. The last step is to recursively add the results of the same operation for all child ContentPlaceholders so nested master pages work as expected.
And then finally:
if (ChildrenCount(MyContentPlaceholder) == 0)
MyContentPlaceholder.Controls.Add(new LiteralControl("My default content!"));
My 2 cents:
If it's a constant content you'll have to insert AND there will be no <Content> at all:
<asp:ContentPlaceHolder>
<!-- Anything here will be inserted if there's no Content -->
</asp:ContentPlaceHolder>
Its not executing statements in if block in my method
Master Page:-
page load event:-
Control c = new Control();
DoSomething(c);
My method:-
protected void DoSomething(Control control)(
{
foreach (Control c in control.Controls)
{
if(typeof(c).Equals(Telerik.Web.UI.RadEditor))
{
Telerik.Web.UI.RadEditor rad = c as Telerik.Web.UI.RadEditor;
label1.Visible = true; label1.Text = "dhchk";
rad.CssFiles.Add("~/styles/myStyle.css");
rad.CssFiles.Add("~/styles/myStyle2.css");
rad.CssFiles.Add("~/styles/myStyle3.css");
}
else
{
DoSomething(c);
}
}
}
my content page:-
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<telerik:RadEditor ID="Editor1" EnableEmbeddedBaseStylesheet="false" EnableEmbeddedSkins=false runat="server">
</telerik:RadEditor>
<telerik:RadEditor ID="Editor2" EnableEmbeddedBaseStylesheet="false" EnableEmbeddedSkins=false runat="server">
</telerik:RadEditor>
[EDIT] ok when debugging..I rt clicked "c" and then Quick watch...it says "The name 'c' does not exist in the current context" (?!?!) how so ?
Well, the Master page renders first so you won't have access from the master page to any of the content page controls. You can achive this using events and passing the control from the content to the master
udpate:
Again - Accessing user controls from the master page is flaw in the whole master->content design. the closest thing I can imagine is adding static function
public static void AddDesign(RadEditor obj)
{
...
}
and then call the function form the Page_Load of the user control
MASTER_PAGE_CLASS_NAME.AddDesign(RadEditor1);
Well, I'm not sure, you can access controls in page like this.
At first: that editor should be probably in some Panel (or some other container), so i should look like this:
<asp:Panel ID="pnl1" runat="server">
<telerik:RadEditor ID="Editor1" EnableEmbeddedBaseStylesheet="false" EnableEmbeddedSkins=false runat="server" />
<telerik:RadEditor ID="Editor2" EnableEmbeddedBaseStylesheet="false" EnableEmbeddedSkins=false runat="server" />
</asp:Panel>
Then try this:
protected void Page_Load(object sender, EventArgs e)
{
foreach (Controls c in pnl1.Controls)
{
if (c is Telerik.Web.UI.RadEditor)
{
// do you stuff ...
}
}
}
You should change things around and call your MasterPage method from the content control.
In your masterpage add the method:
public void DoSomething(Telerik.Web.UI.RadEditor rad)
{
label1.Visible = true; label1.Text = "dhchk";
rad.CssFiles.Add("~/styles/myStyle.css");
rad.CssFiles.Add("~/styles/myStyle2.css");
rad.CssFiles.Add("~/styles/myStyle3.css");
}
Call the function from an appropriate event in your page/content control. eg Page.Load, Editor1.Load etc
Master.DoSomething(Editor1);
Update
From the masterpage, you should search for child controls in the Content controls
ContentPlaceHolder1.FindControl("Editor1");
or you could try something like:
foreach (Control c in ContentPlaceHolder1.Controls)
{
if(typeof(c).Equals(Telerik.Web.UI.RadEditor))
{
Telerik.Web.UI.RadEditor rad = c as Telerik.Web.UI.RadEditor;
label1.Visible = true; label1.Text = "dhchk";
rad.CssFiles.Add("~/styles/myStyle.css");
rad.CssFiles.Add("~/styles/myStyle2.css");
rad.CssFiles.Add("~/styles/myStyle3.css");
}
else
{
DoSomething(c);
}
}
The load and render events of the master page are fired after those of the content page (as said here). Hence the controls in the content page should be available by the time these two events are fired?
What I would like to do, is be able to pass two attributes to a user control, a ListName and a Permission, like so:
<uc:check id="uc" List="Shared Documents" Permission="OpenItems" runat="server">
<!-- have some HTML content here that is rendered if the permission is true -->
</uc:check>
Then in the actual check user control, have something similar to:
<%# Control language="C#" ClassName="check" %>
<%
// determine permission magic placeholder
if (DoesUserHavePermissions(perm))
{
// render nested HTML content
}
else
{
// abort rendering as to not show nested HTML content
}
%>
I have read the page on creating a templated control on MSDN, and while that would work - it really seems to be a bit overkill for what I am trying to do. Is there a control that already renders content based on a boolean expression or a simpler template example?
http://msdn.microsoft.com/en-us/library/36574bf6.aspx
Update:
The following code can be used in the ascx to model a very simple version of this:
<%# Control Language="C#" ClassName="PermissionCheck" %>
<%# Import Namespace="System.ComponentModel" %>
<script runat="server">
void Page_Init()
{
if (Allowed != null)
{
Panel container = new Panel();
Allowed.InstantiateIn(container);
PermissionBasedMessage.Controls.Add(container);
}
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate Allowed { get; set; }
</script>
<asp:Placeholder runat="server" ID="PermissionBasedMessage" />
Note: I oversimplified the check in the Page_Init method for this sample code. Additional logic checks can be added as needed.
And reference it in the calling HTML page:
<%# Register src="PermissionCheck.ascx" tagname="PermissionCheck" tagprefix="uc1" %>
<uc1:PermissionCheck ID="PermissionCheck1" runat="server">
<Allowed>Allowed Access</Allowed>
</uc1:PermissionCheck>
You could create a custom control instead of a user control: derive from the asp.net panel, add your two properties, then only render the control if the user has the required permission. E.g. something like this:
The control (put this in App_Code for example):
namespace MyControls
{
public class MyPanel : Panel
{
public string Permission { get; set; }
public string List { get; set; }
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
if (UserHasPermission()) base.Render(writer);
}
}
}
Using the control:
<%# Page ... %>
<%# Register Namespace="MyControls" TagPrefix="mc" %>
<html>
...
<mc:MyPanel runat="server" List="Shared Documents" Permission="OpenItems">
put content and/or other controls here
</mc:MyPanel>
...
Why don't you extend the LiteralControl, add properties for your settings, then render html to the .Value of the LieralControl? Seems pretty simple and a lot less of a headache than using Templated controls
The other answers are good for the generic form of your question, but for checking permissions SPSecurityTrimmedControl might do what you need.
Wrap your content with a place holder control and set the control's visibility to true or false (controls that have .Visible = false won't render any html)
<asp:PlaceHolder id="phWrapper" runat="server">
...
</asp:PlaceHolder>
Then in your code-behind set phWrapper.Visible = DoesUserHavePermissions(perm);
Hope that helps!