How to set property to Guid in aspx page - c#

I have the following code in one of my aspx pages:
<% foreach (Dependency dep in this.Common.GetDependencies(this.Request.QueryString["Name"]))
{ %>
<ctl:DependencyEditor DependencyKey='<%= dep.Key %>' runat="server" />
<% } %>
When I run it, I get the following error: Parser Error Message: Cannot create an object of type 'System.Guid' from its string representation '<%= dep.Key %>' for the 'DependencyKey' property.
Is there any way that I can create a control and pass in a Guid in the aspx page? I'd really hate to have to loop through and create these controls in the code behind just because of that...
NOTE: The Key property on the Dependency object is a Guid.

The key property of the Dependency object may be a Guid, but is the DependencyKey Property of the DependencyEditor a Guid too? If not it should be, otherwise the correct TypeConverter won't be invoked upon assignment.
If I'm not mistaken, you could also use dep.Key.ToString() also.

is your control taking the value and assuming its a GUID? Have you tried instantiating a GUID with the value? Looks like this is a cast problem

ok, here's the deal...try using the # symbol instead of the = symbol. I replicated your problem and that gets past the compile issue.
It should look like this "<%# dep.Key %>"
good luck!

Assuming dep.Key is a string representation of a guid... and DependencyKey is a property of type Guid
<ctl:DependencyEditor DependencyKey="<%= new Guid(dep.Key) %>" runat="server" />

Related

Customizing the ID value for asp:GridView

In my aspx page, I have the following code to generate a asp:Table
abc.aspx
<asp:Table id = "_tableTest" runat="server"></asp:Table>
When I render it on the page , I need the id to be prepend with a text , for example "Address"
<table id="Address_tableTest" > </table>
How can I customize the ID generation? I couldnt find relevant documentation.
What do you mean? If some 3rd party needs the table name, then you can't change it. I mean, either you type in Address_tableTest as the ID, or you don't.
The "id" is NOT generated for you, YOU the developer type it into the markup
You can change the "id" in the forms pre-render event.
In fact, you can even change it in the page on-load event.
this.GridView1.ID = "abc";
or
GridView1.ID = "Address_" + GridView1.ID.ToString();
The "id" in markup will now thus render and use "abc".
However, code behind will continue to use "this.GridView1" to reference the control.
You can append it.
<asp:Table id = '<%# Eval("Id") + "_TableName" %>' runat="server"></asp:Table>
what is the use of Eval() in asp.net
Yes #VDWWD is correct Id can not be set dynamically
The ID property of a control can only be set using the ID attribute in the tag and a simple value. Error Generated by webforms when I tried to set it dynamically.
It is explained here in this post Eval script for server side control's ID property

Asp.Net code block - how to use with a property

I've used code blocks before, but I'm having an issue in this instance.
I have a user control with a small number of properties. I don't want to set the properties in the parent control so I've resorted to doing it like this:
<uc2:ContactCard ID="ContactCard" runat="server"
Address="<% =CoAddressStack %>"
Email="<% =ContactEmail %>" />
The problem is that the properties are not being set with the value, instead they are set with the exact text inside the quotes.
The properties themselves come from an inherited base control.
I've been scratching my head for some time and seemingly tried every permutation. It could be I'm doing something wrong elsewhere - any advice?
The tag you're looking for is <%= ... %> not <% = ... %>
There is not a space before the =
Try writing this
Address="<%= 5 + 5 %>"
if it display 10, then its your property, in that case you can call a function like this
Address="<%= getValue() %>"
and in your codebehind something like
public string getValue()
{
return "hello world";
}
also try deleting the quotes: Address=<%= CoAddressStack %>
After further investigation, it seems it's not possible to embed a code block into a controls property directly without resorting to other measures. This for me makes the idea redundant as it's just as easy to set the controls properties from the code behind as it is to perform the extra measures.

Databound Value in href javascript link

I've trawled the net looking for the syntax to get this working and i'm hoping this is a quick fix else i'll go mad. Basically I have a nested repeater and the button below hides another nested repeater.
((location_details)((RepeaterItem)Container.Parent.Parent).DataItem).tbl_location.location_id evaluates perfectly well (3824 in the case i'm testing), but when I try to pass it so that its a string parameter for the javascript function it fails everytime.
<asp:Linkbutton ID="lb_showhide_oloc_gnotes" runat="server" Text="Expand/Close"
href='javascript:sltoggle('" + <%# ((location_details)((RepeaterItem)Container.Parent.Parent).DataItem).tbl_location.location_id %> +" '); return false;' />
Any ideas what i'm missing (I know the above syntax is wrong I must have changed it 100 times already but you get the idea).
thanks!
Have you tried asp:HyperLink and NavigateUrl?
I think asp:LinkButton renders to an anchor tag and its href attribute should be generated by ASP (so it results in a postback) and that's why it won't bind to it.
I can't test this right now so this might be wrong, but you don't need to concatenate the value of href together.
<asp:Linkbutton ID="lb_showhide_oloc_gnotes" runat="server" Text="Expand/Close"
href='javascript:sltoggle("<%# ((location_details)((RepeaterItem)Container.Parent.Parent).DataItem).tbl_location.location_id %>"); return false;' />

ASP.net How to output cache a webusercontrol on controls public properties

I have a web user control, it serves some potentially intensive data calculations and I would like it to be output cached so that each page view doesn't recalculate the data. It resides on very frequently viewed pages so it's quite important I get it working right!
For context, it's used on our arcade:
http://www.scirra.com/arcade/action/93/8-bits-runner
Click on stats, the data for the graphs and stats are generated from this webusercontrol.
The start of the control is as follows:
public partial class Controls_Arcade_Data_ArcadeChartData : System.Web.UI.UserControl
{
public int GameID { get; set; }
public Arcade.ChartDataType.ChartType Type { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
Now the difficulty I'm having is the output cache needs to be dependant on both the GamID and the ChartType.
This control is re-used with many different combinations of GameID's and Types, I need it to create a cache for each of these but am struggling to find out how to do this.
For example, one arcade game might pass in GameID = 93 and Type = GraphData, another might be GameID = 41 and Type = TotalPlaysData and another might be GameID = 93 but Type = TotalPlaysData. These should all return different data and have different output caches.
The control is used on the games page sort of like this (the parameters are actually set in the codebehind)
<div>Total Plays:</div>
<div class="count"><Scirra:ArcadeChartData runat="server" GameID="93" Type="TotalPlays" /></div>
<br /><br />
<div>Total Guest Plays:</div>
<div class="count"><Scirra:ArcadeChartData runat="server" GameID="93" Type="TotalGuestPlays" /></div>
etc.
Any help appreciated! I've spent a while looking online and it's kept coming up as something I need to solve but can't figure this one out.
Edit
Edit: I've tried adding this line to my control:
<%# OutputCache Duration="20" VaryByControl="GameID;Type" %>
But it just throws the error Object reference not set to an instance of an object. on the line where GameID is being set for the first time on the ASPX page using the control.
When a Control is retrieved from the output cache, it's not instantiated as an instance that you can manipulate; you just get the output the Control generated, not the Control itself. For example, you can't set properties on a cached Control from code behind, as you said in your question. The vary-by properties should be set declaratively (using an ExpressionBuilder might also work, though I haven't tried it).
To see in code behind whether a control has been retrieved from the output cache, check for null:
if (this.YourControlID != null) // true if not from cache
{
// do stuff
}
Even with that caveat, Control output caching is a bit quirky.
Try this:
<%# OutputCache Duration="20" VaryByControl="GameID;Type" Shared="true" %>
The output of the Control is stored in the output cache by associating it with a certain key. With Shared="true", the cache key is the value of all specified properties, together with the Control's ID. Without Shared="true", the cache key also includes the Page type, so the output would vary by Page -- which doesn't sound like what you want.
If you use the Control on more than one page, be sure to use the same ID on each page if you can, since the ID is included as part of the key for the output cache. If you can't or don't use different IDs, you will get a new copy of the Control's output in the cache for each unique ID. If the Controls with different IDs always have different property values anyway, that may not be an issue.
As an alternative to the OutputCache directive, you can set an attribute on the class declaration:
[PartialCaching(20, null, "GameID;Type", null, true)]
public partial class Controls_Arcade_Data_ArcadeChartData : UserControl
You need to take the following steps:
1) Add the following output cache directive to the page:
<%# OutputCache Duration="21600" VaryByParam="None" VaryByCustom="FullURL" %>
2) Add the following to global.asax:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg.Equals("FullURL", StringComparison.InvariantCultureIgnoreCase)
{
// Retrieves the page
Page oPage = context.Handler as Page;
int gameId;
// If the GameID is not in the page, you can use the Controls
// collection of the page to find the specific usercontrol and
// extract the GameID from that.
// Otherwise, get the GameID from the page
// You could also cast above
gameId = (MyGamePage)oPage.GameID;
// Generate a unique cache string based on the GameID
return "GameID" + gameId.ToString();
}
else
{
return string.Empty;
}
}
You can get more information on the GetVaryByCustomString method from MSDN and also review some of the other caching options here.
create a cache object in the code
HttpRuntime.Cache.Insert("ArcadeChartData" + GameID + Type, <object to cache>, null, System.Web.Caching.Cache.NoAbsoluteExpiration,new TimeSpan(0, 0, secondsToCache),CacheItemPriority.Normal, null);
above cache item will be enough to your work, but if you really want to use output cache as well try following code in the code behind,
Response.AddCacheItemDependency("ArcadeChartData" + GameID + Type);
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
Setting values for the page output cache is the same as manipulating
the SetExpires and SetCacheability methods through the Cache property.
I know that my solution may look very simple and possibly weird but I tried it and it works.
You simply have to add this line in your UserControl.
<%# OutputCache Duration="10" VaryByParam="none" %>
Note : I have only tested the Framework 4.0. Also if ever you have to change the value of the property in the UserControl (MyInt, My String in this example) do it in the Page_Init event.
Here is all my code :
Page :
<%# Page Title="Home Page" Language="vb" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="MyWebApp._Default" %>
<%# Register Src="~/UserControl/MyUserControl.ascx" TagPrefix="uc" TagName="MyUserControl" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<uc:MyUserControl ID="uc1" MyInt="1" MyString="Test" runat="server" />
<hr />
<uc:MyUserControl ID="uc2" MyInt="3" MyString="Test" runat="server" />
<hr />
<uc:MyUserControl ID="uc3" MyInt="1" MyString="Testing" runat="server" />
</asp:Content>
User Control:
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="MyUserControl.ascx.vb" Inherits="MyWebApp.MyUserControl" %>
<%# OutputCache Duration="10" VaryByParam="none" %>
<div style="background-color:Red;">
Test<br />
<asp:Label ID="lblTime" ForeColor="White" runat="server" />
</div>
User Control Code:
Public Class MyUserControl
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Debug.Write("Page_Load of {0}", Me.ID)
Dim oStrBldr As New StringBuilder()
For i As Integer = 1 To Me.MyInt
oStrBldr.AppendFormat("{0}: {1} - {2} at {3}<br />{4}", Me.ID, i, Me.MyString, Date.Now.ToLongTimeString(), System.Environment.NewLine)
Next
Me.lblTime.Text = oStrBldr.ToString()
End Sub
Public Property MyInt As Integer
Public Property MyString As String
End Class
Please keep me posted, I have other solutions if ever you wish but they are more complex. I may also post with C#
One easy trick is to put all the graphics in a new page receiving GameId and Type as querystring parameters, use the out-of-the-box output cache for querystring parameters and the put an iframe in your page. Also you can make use of the browser's cache and never get the server hit for a while.
Ok, well the reason why this so hard to make OutputCache work in this case is because it wasn’t design to be use with Property’s, however it works very well with QueryString parameters. So my next solution isn’t the most professional and probably not the best, but it is definitely the fastest and the one that requires less code changing.
Since it works best QueryString, I recommend you putting your UserControl in one blank page, and wend ever you want to use your UserControl make an iframe that links to your page with the UserControl with QueryString.
Where you want to use your UserControl:
<iframe src="/MyArcadeChartData.aspx?GameID=93&Type=TotalPlays"></iframe>
Full page markup, MyArcadeChartData.aspx
<%# Page ... %>
<%# OutputCache Duration="20" VaryByParam="GameID;Type" %>
<Scirra:ArcadeChartData ID="MyUserControlID" runat="server />
Full page code, MyArcadeChartData.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
//TODO: Put validation here
MyUserControlID.GameID = (int)Request.QueryString["GameID"];
MyUserControlID.Type = (YourEnum)Request.QueryString["Type"];
}
Please not that values in the QueryString can be seen by the user, please do not put sensitive data.
Also I’m aware that this isn’t the most professional solution, but it is the easiest to implement, from what I know.
Regards and happy holidays
If I understand right, the caching isn't working correctly because of the way you have the properties supplying the values to the control, which probably has to do, in part, with the calculations that are being done.
You could create an HttpHandlerFactory that takes the request, does your calculations if they're not in the cache (inserting into the cache afterwards), handles the expiration of values, and then passes the request on to the page. It wouldn't be control-specific at all. That way you could use these calculated values in any control or page, and wouldn't have to implement caching policies that worry about their own calculations.
If this isn't data intensive, have you considered storing it in the Session as apposed to caching it? Just a thought...
Arcade.ChartDataType.ChartType Type;
string GameKey = GameId + Type.toString();
storedData = callCalculation(GameId,Type);
Session[GameKey] = storedData;
I realize this isn't in the cache, I am just trying to be constructive.

Creating binding in codebehind

I have this type of code in aspx but wish to generate it in code behind. What would be the equivalent?
<uc1:editformcontrol ID="EditFormControl1" runat="server" CategoryID=' <%#Bind("CategoryID") %>' />
The question pertains mainly to the binding
It's difficult to say without knowing your data model. What kind of data source are you using? You could try adding this line to the Page_Load method:
int categoryId;
categoryId = WHEREEVER YOU'RE STORING THIS VALUE...
EditFormControl1.CategoryID = categoryId;
Usually, you override the OnDataBound event on your control and bind the data there.
See here one example.

Categories

Resources