ASP.NET 4.0 Route expression builder inside Listview control - asp.net

One of the features of ASP.NET 4.0 is Route Expression builder which allows you to set up hyperlinks like this:
<asp:HyperLink
runat="server"
NavigateUrl="<%$ RouteUrl:RouteName=productos,categoria=Cereales,id=2 %>" >Productos</asp:HyperLink>
Now I'm wondering if I can use this sort of syntax inside a ListView Control, I know is possible, but the tricky thing is that I want to genereate de route key value dynamically.
So instead to write id=2 I would like to write id=<%# Eval("CategoryID") %> .
Can I do that?, if so, how should I write it.
Thanks for your help!

I have searched and searched for an example did not find a way to handle building routes in an expression builder. I finally figured out a way to do this in a gridview, maybe you can adapt? See my post at the following address where I answered my own question: How to use routing in web forms and HyperLinkFields of a GridView
I think an asp hyperlink control will not work because the controls are built before the Eval() is called, but an anchor is just text so it works within a template field.

Not sure whether you can do it with the Route ExpressionBuilder. Instead you can give an ID to the Hyperlink object in the .aspx file:
<asp:HyperLink ID="productHyperLink" runat="server">Productos</asp:HyperLink>
And set the NavigateUrl property in the Page_Load method in the .cs file:
protected void Page_Load(object sender, EventArgs e)
{
int categoryId;
string categoryName;
// Get categoryId and categoryName from database
RouteValueDictionary values = new RouteValueDictionary {
{ "id", categoryId.ToString() },
{ "categoria", categoryName } };
VirtualPathData virtualPathData = RouteTable.Routes.GetVirtualPath(null, "productos", values);
productHyperLink.NavigateUrl = virtualPathData.VirtualPath;
}

Related

Can I use ViewBag in an .aspx page?

I have to move my UI page from a .cshtml file to an .aspx file. Now I'm having a couple of compiling errors.
First is that 'ViewBag' does not exist in the current context. Can I not use it in .aspx? If not, what is a good substitute?
Second, the .cshtml page had a model declaration:
#model myProject.Models.Navigation
I changed it so that it would work in the .aspx page as follows:
<%# Import Namespace="myProject.Models" %>
I'm still not sure that's a correct substitute, because I could not include the word "Navigation" without getting an error. And now, in the code where I used to have:
#foreach (myProject.Models.Navigationitem item in Model.navigationItems){...
I've replaced it with:
<% foreach (myProject.Models.Navigationitem item in Model.navigationItems){...
And I get this error:
The name 'Model' does not exist in the current context
Apparently, I'm the only guy who has ever gone from razor to aspx, because there's exactly zilch about it online. Appreciate any help.
WebForms don't usually use a ViewBag, which is just a way to make data available to your View in ASP.Net MVC. With WebForms, a nice way to make data available to your "View" (the aspx page containing the HTML) is to expose a property containing that data.
The MVC way might be to set ViewBag.MyValue = "Some Value"; in your Controller, and reference it in your view with <h1>#ViewBag.MyValue</h1>. To do the equivalent in WebForms you would first define a property in your codebehind:
protected string MyValue { get; set; }
Then, set the value somewhere, perhaps in your Page_Load:
protected void Page_Load (object sender, EventArgs e)
{
this.MyValue = "Some Value";
}
And write the value on the page using WebForms syntax:
<h1><%= MyValue %></h1>
For your specific case, you don't seem to actually be using ViewBag. That's ok, you can make objects available as properties also:
protected MyProject.Models.Navigation Model { get; set; }
protected void Page_Load (object sender, EventArgs e)
{
this.Model = SomeMethodThatReturnsModel();
}
With the property defined and the value set, the code you have above for your ASPX should work just fine.
Your page should have
<%# Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of myProject.Models.Navigation)" %>
at the top to specify the model type.
Instead of ViewBag, you can use ViewState, as shown in the example below.
private List<TrimPackage> Packages
{
get
{
return (List<TrimPackage>)ViewState["Packages"];
}
set
{
ViewState["Packages"] = value;
}
}

Access dynamically generated control from code behind

I load a piece of html which contains something like:
<em> < input type="text" value="Untitled" name="ViewTitle" id="ViewTitle" runat="server"> </em>
into my control. The html is user defined, do please do not ask me to add them statically on the aspx page.
On my page, I have a placeholder and I can use
LiteralControl target = new LiteralControl ();
// html string contains user-defined controls
target.text = htmlstring
to render it property. My problem is, since its a html piece, even if i know the input box's id, i cannot access it using FindControl("ViewTitle") (it will just return null) because its rendered as a text into a Literal control and all the input controls were not added to the container's control collections. I definitely can use Request.Form["ViewTitle"] to access its value, but how can I set its value?
Jupaol's method is the prefer way of adding dynamic control to a page.
If you want to insert string, you can use ParseControl.
However, it doesn't cause compilation for some controls such as PlaceHolder.
Your process is wrong, you are rendering a control to the client with the attribute: runat="server"
This attribute only works if the control was processed by the server, you are just rendering as is
Since your goal is to add a TextBox (correct me if I'm wrong), then why don't you just add a new TextBox to the form's controls collection???
Something like this:
protected void Page_Init(object sender, EventArgs e)
{
var textbox = new TextBox { ID="myTextBoxID", Text="Some initial value" };
this.myPlaceHolder.Controls.Add(textbox);
}
And to retrieve it:
var myDynamicTextBox = this.FindControl("myTextBoxID") as TextBox;
I have created several working examples and they are online on my GitHub site, feel free to browse the code

How to find the HtmlInputCheckBox of a repeater control in code behind file without using runat ="server" tag

Inside repeater i have a html checkbox , now i want to access this checkbox in code behind file to check whether the checkbox is checked or not. but i dont want to user runat="server" tag , how can i do this my code as above
<input id="cbfdgroup" class="checkitem" type="checkbox" name="fd_cb_group[]" value='<%#Eval("FoodItemsUid") %>'>
in code behind file i am trying to access like this
foreach (RepeaterItem ri in rptMenu.Items)
{
if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem)
{
HtmlInputCheckBox chk = (HtmlInputCheckBox)ri.FindControl("cbfdgroup");
if (chk.Checked)
{
}
}
}
but this is giving error as object referrence is not set to instance of an object.. how should i get this control in code behind file without using runat = "server" tag
It is not possible. To clarify, the runat="server" portion is doing just what it says. It is saying that this control should be made available and accessible to the server.
Code which is in the code-behind is code which is running on/executed by the server. So logistically, if the control is not made available to the server, the it cannot be manipulated by code (hence when it will not show up in intellisense either.)
I don't believe what you are asking is possible. runat=server is what makes controls available to the code behind. If you remove that attribute, your code behind is simply not aware of the control in any way.
A little bit more explanation:
The codebehind executes on the server. Therefore, any control you want to access in your codebehind must have runat=server in order to be available. The two are inseparable.
you don't need to read the items from repeater
assuming that you are sending a postback to the server (http post)
you can read the selected checkbox by simply:
string x = Request["fd_cb_group[]"];
it is more than 1 it will separate by comma, just use split the get a list of string of selected values.
the whole thing would be something like that:
protected void Button1_Click(object sender, EventArgs e)
{
string x = Request["fd_cb_group[]"];
string[] allSelectedOnes = x.Split(',');
foreach(string item in allSelectedOnes)
{
//your custom code for the selected checkboxes
}
}

Adding custom valiadtion to ASP.NET controls

We're trying to build a simple asp control for some clients where they can just drop in a single block -
i.e.
<captcha:CaptchaControl ID="CaptchaControl1"
runat="server"
Server="http://localhost:51947/"
/>
and have it render the control. The catch is that I can't get this to include custom validation. Right now I'm using the RenderContents function to display the layout of the control itself as well as hook it up the to Javascript. The problem is that I don't know how to get custom validation to fire when used as part of a control.
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(#"
<script type=""text/javascript"" src=""http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js""></script>
<link rel=""stylesheet"" type=""text/css"" href=""/Layout/CaptchaLayout.css"" />
//etc
<asp:Textbox id=""text1"" runat=""server"" text=""""></asp:Textbox>
<asp:CustomValidator id=""CustomValidator2"" runat=""server""
ControlToValidate = ""text1""
ErrorMessage = ""You must enter at least 8 characters!""
ClientValidationFunction=""validateLength"" >
</asp:CustomValidator>"
);
}
Any suggestions for a better way to do this?
Oogh, I would definitely not recommend your approach. It's very brittle and difficult to maintain, and depending on how your control is used, I'm not even sure that you can output more asp tags and have them processed properly.
Why don't you just inherit your custom control from Panel, and then in the Init or Load event handlers, add the textbox and custom validator to it? Roughly:
public class MyControl : Panel
{
public MyControl()
{
}
protected override void OnInit(EventArgs e)
{
ScriptManager.RegisterScript( ... Google script, CSS, etc. ... );
TextBox txt = new TextBox();
txt.ID = "text1";
this.Controls.Add(txt);
CustomValidator vld = new CustomValidator();
vld.ControlToValidatre = "text1";
vld.ID = "validator1";
this.Controls.Add(vld);
}
}
Your CustomValidator doesn't work because ASP.NET has no idea it's there. You are basically just dumping that output to the response... ASP.NET is not interpreting it.
It seems to me that this is a perfect situation for a User Control rather than a Custom Control. Just drop that output string in its own .ASCX file.

asp.net use class object on form

I am creating an object at server side of an aspx (test.cs) page from a class (asp.net 2.0 C#)
public partial class Vendor_VendorUsedTicketsPopup : System.Web.UI.Page
{
ReportInvoice _objReportInvoice = new ReportInvoice();
protected void Page_Load(object sender, EventArgs e)
{
_objReportInvoice.ReportId = 1;
}
}
as you see above before Page Load I am creating a new ReportInvoice object and on page load I am setting property ReportId to 1
On test.aspx I want to use the ReportId value bu using the _objReportInvoice object like below
<div><% _objReportInvoice.ReportId; %></div>
But when I build the site I get the error
The name '_objReport' does not exist in the current context
I know that I can create a public integer for ReportId above Page_Load and use it on aspx page. That works fine , but I want to use class object properties on aspx page.
What is the way of doing sth like that ?
Thanks...
You need a = sign in there to print it to the page:
<div><%= _objReportInvoice.ReportId; %></div>
However, I would suggest just using a Literal or Label control there and then setting it's text to the ReportID property in the code behind. Inline code like that can make your HTML messy.
Remember that your .ASPX markup page inherits from the codebehind class.
This means that unless you declare your field as protected or public, the .aspx will not have access to your field.
You need to add an access modifier to your field to make it non-private.

Resources