Asp.net web forms control in asp.net mvc - asp.net

I'm trying to inject an asp.net classic web control to my asp.net mvc application. This control doesn't use view state or post back so it works fine.
But I can't plug a real-time provided value in its attribute. This code
<my:Control runat="server" Tag="<%: Model.ID %>" />
ends up with the tag value just set explicitly to "<%: Model.ID %>".
Is there a way to make it work?

I believe the syntax is as follows:
<my:Control runat="server" Tag="<%# Model.ID %>" />
The other gotcha is you must call .DataBind() on the Control at some point after the Control has been initialized. This probably means taping into the Page_Load or OnInit events of the Page.
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<script runat="server">
protected override void OnInit(EventArgs e)
{
this.Label1.DataBind();
base.OnInit(e);
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<asp:Label ID="Label1" runat="server" Text="<%# DateTime.Now %>" />
</asp:Content>
Or, if you have access to the source, you could add a call to .DataBind() somewhere before the final Render. You would have to experiment with that.
Hope this helps.

Well, seems like the only way to do this is injecting code the control renders to the page directly. In my case the control renders a silverlight object with some javascript so I put it at the page as is.

Related

UserControl not loading in ListView

I've create my own UserControl called 'ReevooBadge' and have placed it in my listview by registering my UserControl. However, my UserControl isn't visible in the ListView. Any sugestions for this problem?
This is my User Control
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ReevooBadge.ascx.cs" Inherits="KiaEurope2010.Website.controls.Addons.Widgets.ReevooBadge" %>
<a class="reevoomark <%= this.ClassName %>" href="//mark.reevoo.com/partner/<%= this.CountryCode %>/series:<%= this.SelectionIdentifier %>"><%= this.ReviewsTitle %></a>
I need to implement this in my ListView by the following code implementation
<asp:ListView ID="lvItemCarousel" ItemPlaceholderID="carrouselitems"OnItemDataBound="lvItemCarousel_ItemDataBound"
runat="server">
<layouttemplate>
<asp:PlaceHolder ID="carrouselitems" runat="server" />
</layouttemplate>
<itemtemplate>
<li>
<asp:HyperLink runat="server" ID="hlItem">
<asp:Image runat="server" ID="imItem" />
<div class="modelTitle">
<asp:PlaceHolder runat="server" ID="phReevoo" Visible="false">
<rhm:ReevooBadge runat="server" ID="ReevooBadge" />
</asp:PlaceHolder>
</div>
</asp:HyperLink>
</li>
</itemtemplate>
</asp:ListView>
Above I register my custom User Control
<%# Register Src="~/controls/Addons/Widgets/ReevooBadge.ascx" TagPrefix="rhm" TagName="ReevooBadge" %>
And in the Item Data Binding
protected void lvItemCarousel_ItemDataBound(object sender, ListViewItemEventArgs e)
{
//...
phReevoo.Visible = true;
ReevooBadge.ModelItem = this.Item;
ReevooBadge.CountryCode = KiaEurope.SitecoreLayer.Reevoo.Settings.GetReevooKey(LanguageCountryCultureHelper.CurrentCountryCode, Sitecore.Context.Language);
}
However, the user control isn't visible in the ListView.
I'm not sure how you're getting your code to compile because I couldn't reference phReevoo (the placeholder control) directly in the ItemDataBound event.
I needed to use the following:
e.Item.FindControl("phReevoo").Visible = true;
The same would apply if you tried to reference ReevooBadge.
To make the testing easier I created a web user control and used this as a substitute for your custom user control. After binding to a simple List<string>, the control showed without issue.
I would suggest checking if your user control is actually rendering outside of the ListView.

Intellisense not showing up for some controls in code behind

i'm kind of an asp.net beginner and i'm trying just to set the visible attribute dynamically but i can't access "TestLinkBox" nor the "TestLink" id in the code behind. Ive tried to rebuild the solution, to delete the designer.cs file and let it be recreated and tried a few solutions I found on stackOverflow as you can see in the code behind but i always get the "Object reference not set to an instance of an object." error. What am I doing wrong?
PART OF THE ASP.NET CODE
<%# Page Title="" Language="C#" MasterPageFile="~/Public/Main.Master"
AutoEventWireup="true" CodeBehind="SpecifikacijaDetails.aspx.cs" Inherits="web.Public.SpecifikacijaDetails"
%>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"></asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<mc:VijestiTraka ID="vijestitraka" runat="server"></mc:VijestiTraka>
<div class="middle_content_box">
<asp:ListView ID="ListView1" runat="server" DataKeyNames="SpecifikacijaID"
DataSourceID="SqlDataSource1">
<AlternatingItemTemplate>
<div class="details_title_box">
<p class="title"><strong><%# Eval("Brand") %></strong>
<%# Eval( "Model") %>
</p>
</div>
<div class="left_column">
<div class="pregled_modela_slika margb30">
<img src='<%# Eval("SlikaMobitela") %>' />
</div>
<div id="TestLinkBox" class="testLink" runat="server" visible="false">
<asp:HyperLink runat="server" ID="TestLink" NavigateUrl='<%#"~/Public/TestSpecifikacije.aspx?SpecifikacijaID=" + Eval("SpecifikacijaID")%>'
Text="Pogledajte kompletan test"></asp:HyperLink>
</div>
CODE BEHIND
using (MobBL temp = new MobBL())
{
if (temp.ProvjeriImalTest(Int32.Parse(Request.QueryString["SpecifikacijaID"])) > 0)
{
//ListView1.FindControl("link_za_test").Visible = true;
//HtmlControl htmlDivControl = (HtmlControl)Page.FindControl("link_za_tet");
//htmlDivControl.Visible = true;
}
}
The controls your are trying to access in code behind are inside an item template. For this reason, you cannot access them via intellisense because they are not actually on the form - they will be added when the parent control (ListView1) is bound.
Subscribe the the item databound event of the listview control. In there, you can access the child controls for each item in the listview. Something like this would get you the control:
e.Item.FindControl("TestLinkBox");

Repeater ItemCommand doesn't work when linked to the page

EDIT: I've found what's causing the issue, but I don't know why and I don't know how to fix it. I'm using JQuery Mobile to theme my site and when I remove this line:
<div data-role="page" data-theme="a">
I can get the repeater to work properly. Does anyone know how I can keep my theme and get this repeater to work?
Alright I have a repeater like this:
<asp:Repeater ID="Repeater1" runat="server" onitemcommand="Repeater1_ItemCommand" EnableViewState="true">
<ItemTemplate>
<li>
<asp:LinkButton ID="Button1" runat="server" Text='<%# Container.DataItem %>' CommandName="Redirect" />
</li>
</ItemTemplate>
</asp:Repeater>
And the code behind it looks like this
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Redirect")
{
Session["contact"] = ((LinkButton)e.CommandSource).Text;
Response.Redirect("Contact_Details.aspx");
}
}
And if I navigate directly to this page (without being linked to it from another page) the repeater will fire the ItemCommand. But, if I have my login page redirect back to this page or just click on a link to this page from another page, the itemcommand is never triggered when clicking on the link buttons. Any clues as to why this is?
EDIT: The full code for this page is:
<%# Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="Contacts.aspx.cs" Inherits="WebApplication3.Contacts" %>
<%# MasterType VirtualPath = "~/Site1.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:Repeater ID="Repeater1" runat="server" onitemcommand="Repeater1_ItemCommand" EnableViewState="true">
<HeaderTemplate> <ul data-role='listview' data-theme='c' data-inset='true'>
<li data-role="list-divider"><center><h1>Contacts</h1></center></li></HeaderTemplate>
<ItemTemplate>
<li>
<asp:LinkButton ID="Button1" runat="server" Text='<%# Container.DataItem %>' CommandName="Redirect" />
</li>
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
</asp:Content>
In page load I connect to a webservice that connects to exchange and returns an array out. I do a quick array conversion to an arraylist then the rest of the code is:
//Converts the array grabbed from the webservice to an arraylist
ArrayList testList = ArrayList.Adapter(contactsList);
Repeater1.DataSource = testList;
Repeater1.DataBind();
Repeater1.ItemCommand += new RepeaterCommandEventHandler(Repeater1_ItemCommand);
}
So I figured out the line that was giving me an issue.
In my master page I had:
<div data-role="page" data-theme="a">
This line is for my JQuery Mobile Theme. When I commented it out, it broke the theme but the repeater worked. So I took a look into the JQuery Mobile docs and found that I could put rel="external" as an attribute to the link that links to this page. This removes the AJAX transitions and forces the page to refresh when clicked.
Not sure exactly why this was an issue, any gurus have an idea?

Access to MVC Models from standard ASCX UserControl

I've got a simple ASCX user control (non-MVC). The user control has a property on it (let's call it Title or something).
I've also got an MVC Partial View which contains the user control.
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeModel>" %>
<%# Register TagPrefix="tag" TagName="Control" Src="~/path/to/ascx/control.ascx" %>
... snip ...
<tag:Control ID="myControl" runat="server" />
What I'd like to be able to do is something like this:
<tag:Control ID="myControl" runat="server" Title="<%= Model.Title %>" />
... so that I can access some property of the model inside my Control.
Unfortunately this method doesn't work, as I get a message saying "This is not scriptlet. Will be output as plain text".
Is what I'm trying to do even possible? If so, does anyone have any ideas how I can try and do it?
If it's relevant, this is a .Net 4 project, with MVC 2 components.
Thanks!
Neil
Is what I'm trying to do even possible?
Yes but it would be extremely ugly and it involves using a code behind (in an ASP.NET MVC view!!!):
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="AppName.Views.Home.Index"
CodeBehind="Index.aspx.cs"
%>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:Label ID="Txt" runat="server" />
</asp:Content>
and in the corresponding code behind Index.aspx.cs (beurk..., I will vomit):
public partial class Index : System.Web.Mvc.ViewPage<AppName.Models.MyViewModel>
{
protected void Page_Load(object sender, EventArgs e)
{
Txt.Text = Model.Title;
}
}
which could be improved like this to avoid the code behind nonsense:
<%# Page
Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<AppName.Models.MyViewModel>"
%>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Txt.Text = Model.Title;
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:Label ID="Txt" runat="server" />
</asp:Content>
I wouldn't recommend you doing something like this if you intend to migrate to ASP.NET MVC 3 and the Razor view engine one day.
I found a solution that's a little cleaner. Still not to my liking, but good enough to wash my hands of this annoying issue.
<% ViewBag.Item = item; %>
<gc:Ribbon runat="server">
<Content>
<strong><%= ViewBag.Item.DataItem.Name %></strong>
</Content>
</gc:Ribbon>
Instead of passing an object into the user control to use within, assign it to the ViewBag (for each iteration if you're looping), and use it globally. If memory serves me right, I believe MVC 2 uses ViewData["loosely typed name"] instead of the dynamic ViewBag.

Page OnLoad not fireing changing query string

I have a problem that the OnLoad event is not fireing when I navigate to a page and just change the query string. If I do a postback it is called, then changing the query string ones more OnLoad gets called.
Here is how i try. I navigate to the page OnLoad fires -> then change the query string page updates (all bound elements get updated) OnLoad does not fire -> I do a postback using a button OnLoad fires -> then change the query string OnLoad fires.
I will try to explain in more detail.
The system has log in window when I log in I navigate to an other aspx page sending two query string messages the last query string is a number (page.aspx?key=text82&key2=2010). When I get to the page the first time PageLoad event gets called and all is fine, if I in the browser change the key2 to 2011 and press enter the PageLoad does not get called but all my bound elements get updated (GrivView etc..). If I then do a postback using a button the PageLoad gets called. If I now change the 2011 back to 2010 and press Enter PageLoad is called.
I try this is firefox the PageLoad get called every time.
I tired to write a test website but I do not get the same problem, but what i found out is that in IE 8 changing the query string to the same number and pressing enter the PageLoad is not called. But doing so in firefox makes the postback fire. Here is the test code
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Welcome to ASP.NET!
</h2>
<p>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default2.aspx?t=tt& tttttt=2010">HyperLink</asp:HyperLink>
</p>
<p>
You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&clcid=0x409"
title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
</p>
</asp:Content>
Navigates to
<%# Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.master" CodeFile="Default2.aspx.cs"
Inherits="Default2" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><asp:Button ID="Button1"
runat="server" Text="Button" />
</asp:Content>
OnLoad event Default2.aspx
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text += "Called " + DateTime.Now.ToString();
}
I found out the problem. Looks like the browser cache was giving me the problem. Press F12 and cleared the cache, it works.

Resources