Resources cannot be accessed in aspx page - asp.net

i have a solution in which i have a web project and couple of other projects. I have added another project that has nothing but a resx file. I have referenced this resource project dll into the web project. is there any possible way i could access the resource in dll into the aspx page. For ex:
<asp:Button ID="Button1" runat="server" Text="<%$ Resources:Resource,ButtonName %>">
The ButtonName must be accessed from the resourcedll.

Import the namespace into the aspx page using #Import page directive.
<%# Import Namespace = "MyProject.Resources" %>
Now to use the resource for setting the property of a Server control, you need to call DataBind() method at the page level on your Page_Load() event. (can be invoked for specific controls also).
Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataBind();
}
}
in your aspx page:
<asp:Button ID="Button1" runat="server" Text = '<%# ProjectResources.CmdBtn %>' />
make sure you make the resource class and the resource key property public, its internal by default.

Related

Why is Page.PreviousPage always null?

I am experimenting with cross-page posting by following this MSDN article. I have this code:
CrossPagePosting1.aspx
<form id="form1" runat="server">
<h1>Page 1</h1>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />
<asp:Button ID="Button1" runat="server" Text="Button" PostBackUrl="CrossPagePosting2.aspx"/>
</form>
CrossPagePosting2.aspx
<form id="form1" runat="server">
<h1>Page 2</h1>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</form>
CrossPagePosting2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
TextBox TextBox1 = (TextBox)Page.PreviousPage.FindControl("TextBox1");
Label1.Text = TextBox1.Text;
}
This code above produces a NullReferenceException at Page.PreviousPage. Why?
This is an ASP.Net 4.0 application.
It uses FriendlyUrls, which is the default.
NOTE: I do NOT want the previous page to be strongly-typed, e.g. using the PreviousPageType directive. According to the referenced article, this shouldn't be necessary.
I found that Friendly URLS might get you this problem. By default, the Web Forms template includes ASP.NET Friendly URLs.
When you use the default WebForm from visual Studio, the AutoRedirectMode is set to Permanent. This makes you request into a "GET" and since you are using Friendly URLS, you can’t evaluate the PreviousPage.
Workarounds:
If you want a "POST" action then set the AutoRedirectMode =
RedirectMode.Off (this will give you PreviousPage info but only from
non-Friendly-Url pages [ex: www.you.com/mypage.aspx], however this
will get you an error if you try to access the Friendly-Url page [ex:
www.you.com/mypage] << no .aspx).
If you want the PreviousPage information you will have to set the
previous post directive in you webpage <%# PreviousPageType
VirtualPath="~/Page1.aspx" %> OR maybe use the Server.Transfer in a
OnClick Method.
The problem here was being caused by FriendlyUrls, which were installed by default on the test site I was working in. I disabled FriendlyUrls, and it worked.
I think following article will helps you.
http://csharpdotnetfreak.blogspot.com/2009/08/cross-page-posting-in-aspnet.html
there are two method how to use Cross Page Posting PostBack
The reason this is happening is simply because you did not set the postbackurl property correctly.
If CrossPagePosting2.aspx is at root of your program change postbackurl to ~/CrossPagePosting1.aspx
You do not need to add the <%# PreviousPageType %> directive when using postbackurl property. using PreviousPage.FindControl(id) will search the form elements that are posted using postbackurl property
Try this
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack && PreviousPage != null)
{
Page page = PreviousPage;
Label1.Text = ((TextBox)page.FindControl("TextBox1")).Text;
}
}

Web Forms error message: "This is not scriptlet. Will be output as plain text"

In my ASP .NET Web Forms I have the following declarative code:
<asp:TextBox runat="server" ID="txtbox" CssClass='<%=TEXTBOX_CSS_CLASS%>' />
The constant TEXTBOX_CSS_CLASS is defined in a base class that the page's code-behind class inherits from:
public class MyPageBase : Page
{
protected internal const string TEXTBOX_CSS_CLASS = "myClass";
}
The edit-time compiler however warns me that "This is not scriptlet [sic]. Will output as plain text".
True to its word, the css class is rendered as literally "<%=TEXTBOX_CSS_CLASS%>".
What does this error message mean and is there a workaround so I can still use a constant in a base class?
You cannot use <%= ... %> to set properties of server-side controls.
Inline expressions <% %> can only be used at
aspx page or user control's top document level, but can not be embeded in
server control's tag attribute (such as <asp:Button... Text =<% %> ..>).
If your TextBox is inside a DataBound controls such as GridView, ListView .. you can use: <%# %> syntax. OR you can call explicitly DataBind() on the control from code-behind or inline server script.
<asp:TextBox runat="server" ID="txtbox" class='<%# TEXTBOX_CSS_CLASS %>' />
// code Behind file
protected void Page_Load(object sender, EventArgs e)
{
txtbox.DataBind();
}
ASP.NET includes few built-in expression builders that allows you to extract custom application settings and connection string information from the web.config file. Example:
Resources
ConnectionStrings
AppSettings
So, if you want to retrieve an application setting named className from the <appSettings> portion of the web.config file, you can use the following expression:
<asp:TextBox runat="server" Text="<%$ AppSettings:className %>" />
However, above snippet isn't a standard for reading classnames from Appsettings.
You can build and use either your own Custom ExpressionBuilders or Use code behind as:
txtbox.CssClass = TEXTBOX_CSS_CLASS;
Check this link on building Custom Expression builders.
Once you build your custom Expression you can display value like:
<asp:TextBox Text="<%$ SetValue:SomeParamName %>"
ID="setting"
runat="server" />
The problem is that you can't mix runat=server controls with <%= .. %>code blocks. The correct way would be to use code behind: txtbox.CssClass = TEXTBOX_CSS_CLASS;.
This will work.
Mark up
<asp:TextBox runat="server" ID="txtbox" class='<%# TEXTBOX_CSS_CLASS %>' />
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
txtbox.DataBind();
}
}
But its a lot cleaner to access the CssClass property of the asp:TextBox on Page_Load

Using same form on multiple pages?

I am writing an application, and I have a user form, which will be the same for the users and the administrators on different pages.
I want to only create the form once, and then be able to put it on two different aspx files.
I tried it with the "control", but it then gets really complicated trying to access fields on the control from the aspx page to do the calculation, etc.
is there another way to do this? creating a form in one place, be able to add it to any aspx page, and have easy access to it's controls?
It's not very difficult at all. You can provide an accessor method or make the control inside public.
Example: A page which displays the contents of a TextBox inside a control, when a button is pressed.
Control
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="WebApplication1.WebUserControl1" %>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
Page
<form runat="server">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<Test:Control ID="ctlTest" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</form>
Code (If TextBox1 is public)
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = ctlTest.TextBox1.Text;
}
Or you could have, in the code of the control
public string GetText()
{
return TextBox1.Text;
}
And in the aspx code page
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = ctlTest.GetText();
}
What is so difficult about that?!
you have to create MasterPage:
http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx
so that you can share common controls between pages. Master pages can be nested, too. You can access controls on master page from child page via Master.FindControl("abc")
EDIT: it seems that you want to reuse common piece of functionality, then you might want to use user control, like in this example:
http://msdn.microsoft.com/en-us/library/3457w616.aspx
you created the control, and do not use findControl() method to access the control that inside you UserControl, that is not feasible or proper solution.
Better to use Properies. Define Properties, so your control can be generalised and you can use that on multiple pages.

Set Custom ASP.NET UserControl variables when its in a Repeater

<%# Register Src="~/Controls/PressFileDownload.ascx" TagName="pfd" TagPrefix="uc1" %>
<asp:Repeater id="Repeater1" runat="Server" OnItemDataBound="RPTLayer_OnItemDataBound">
<ItemTemplate>
<asp:Label ID="LBLHeader" Runat="server" Visible="false"></asp:Label>
<asp:Image ID="IMGThumb" Runat="server" Visible="false"></asp:Image>
<asp:Label ID="LBLBody" Runat="server" class="layerBody"></asp:Label>
<uc1:pfd ID="pfd1" runat="server" ShowContainerName="false" ParentContentTypeId="55" />
<asp:Literal ID="litLayerLinks" runat="server"></asp:Literal>
</ItemTemplate>
</asp:Repeater>
System.Web.UI.WebControls.Label lbl;
System.Web.UI.WebControls.Literal lit;
System.Web.UI.WebControls.Image img;
System.Web.UI.WebControls.HyperLink hl;
System.Web.UI.UserControl uc;
I need to set the ParentItemID variable for the uc1:pdf listed inside the repeater.
I thought I should be able to find uc by looking in the e.Item and then setting it somehow. I think this is the part where I'm missing something.
uc = (UserControl)e.Item.FindControl("pfd1");
if (uc != null) { uc.Attributes["ParentItemID"] = i.ItemID.ToString(); }
Any thoughts would be appreciated.
Also tried this with similar results... when I debug inside my usercontrol (pfd1) the parameters I am trying to set have not been set.
uc = (UserControl)e.Item.FindControl("pfd1");
if (uc != null)
{
uc.Attributes.Add("ContainerID", _cid.ToString());
uc.Attributes.Add("ParentItemId", i.ItemID.ToString());
}
UPDATE: It looks like my controls are not connected by a namespace. I've wrapped by the parent control (Layer) and the PressFileDownlad control in a namespace "MyControls". Also updated their Inherits reference on the aspx to read "MyControls.xxxxx". I'm able to type "MyControls.Layer" inside the code on layer.aspx.cs but I'm not able to get "MyControls.PressFileDownload"
If you implement ParentItemID as a public property in your user control, then you should be able to set it declaratively, e.g:
<asp:Repeater id="Repeater1" ...>
<ItemTemplate>
<uc1:pfd ID="pfd1" runat="server" ParentItemId='<%# Eval("ItemID") %>' ... />
Martin is right you should be able to set it in declarative way (in case your property is public) .
But your way should also work (just cast it properly)
((PressFileDownload)e.Item.FindControl("pfd1")).ParentItemId = 0;
The best way is to implement the OnDataBinding event for the user control. I try to stay away from putting code inline in the aspx using webforms if possible.
When the repeater gets bound, for each item that is bound, the OnDataBinding will fire for your user control and your handler can do what it needs. You don't have to go searching for the controls.
Here is an example:
// in your aspx
<uc1:pfd ID="pfd1" runat="server" ShowContainerName="false" ParentContentTypeId="55"
OnDataBinding="pfd1_DataBinding" />
// in your codebehind implement the OnDataBinding event
protected void pfd1_DataBinding(object sender, System.EventArgs e)
{
pfd uc = (pfd)(sender);
uc.ContainerID = _containerID.ToString();
uc.ParentItemID = Eval("ItemID");
// Here you can do more like access other items like hidden fields
// or cached objects or even other controls etc... Skys the limit.
}
EDIT: Notice from your comment you require more data than what is found in the datasource. In this case what I usually do is just make private member variables in the .cs that I store data in. So when you have the container ID just store it in a variable that will be accessible.
Eg in your .cs for your page:
public partial class _TestPage : System.Web.UI.Page
{
private int _containerID { get; set; }
Then when you load the data just set the _containerID property and it will be accessible in the OnDataBinding event. Just make sure you are binding after you have set the _containerID.

ASP.net web server control

I have a question about wiring web server controls. From many of the examples that I have seen the event handler has been declared with a private access modifier. I tried doing so as shown:
<asp:Label runat="server" ID="lblMessage" Font-Names="Verdana" Text="Hello" />
<br />
<asp:Button runat="server" ID="btnSubmit" text="click me!" onClick="btnSubmit_Click" />
and in the code behind file:
private void btnSubmit_Click(object sender, EventArgs e)
{
lblMessage.Text = "Goodbye";
}
But the compiler is unable to locate the click handler unless i change the access to protected.
Should button event handlers ever be private, and if so, why did it not work in my instance?
Also, other than using the onClick property, are there any other methods for wiring event handlers to controls that are declaratively created in the .aspx file?
Thanks in advance,
Yong
What might be confusing here is that many people design their web forms visually. When they want to wire a click handler to a button server control, they typically either double click the button or select it in Visual Studio, press F4 to go to its properties and set its events within that window. Either of these approaches has the following effect:
A private handler is created in the code behind class. Its name is [control name]_[event]. In your case, this is btnSubmit_Click.
Also in the code-behind file, each web server control has a corresponding protected member of the code behind class. In the Init even, the newly created handler is associated to the Click event on the server control by the following code:
btnSubmit.Click += btnSubmit_Click;
With this approach, the handler can still be private. Where you are having an issue is when you try to set the handler in the ASPX file itself. In this case, you will have to update the event handler to be non-private, as you've indicated, or define the following in the ASPX page itself:
<script language="C#" runat="server">
public void btnSubmit_Click(object sender, EventArgs e)
{
..
}
</script>
Private methods/properties of a code-behind class are not visible to the ASPX page.
The event handler needs to be protected. The reason is that ASP.NET actually generates a new class that inherits from the class you define in your codebehind, rather than using the class itself.
As an alternative, you could write:
btnSubmit.Click += new EventHandler(btnSubmit_Click);
In the Page_Load handler, but I wouldn't recommend it. In VB.NET, I believe you could use the Handles keyword as well, but it's not available in C#.

Resources