Reputation: 1
I have a website where I am trying to change the main logo on the master page programmatically based on the holiday. On my master page I have the code:
<asp:Image ID="img_fp_logo" CssClass="img_fp_logo" runat="server" ImageUrl='<%# getHolidayLogo.get_Holiday_Logo(sql_utilities, sql_holiday_logo) %>' />
In my App_Code, I have the class:
Imports Microsoft.VisualBasic
Imports System.Data
Public Class getHolidayLogo
Public Function get_Holiday_Logo(sqlUtilities As SqlDataSource, sqlHolidayLogo As SqlDataSource) As String
Dim returnstring As String = ""
Dim dvUtilities As DataView = CType(sqlUtilities.Select(DataSourceSelectArguments.Empty), DataView)
If dvUtilities(0)("holiday") = 0 Then
returnstring = "iadb_v2_sys_graphics/iadb_v2_logos/logo_small.png"
Else
sqlHolidayLogo.SelectCommand = "Select logo from iad_holidays where id = " & dvUtilities(0)("holiday")
Dim dvHolidayLogo As DataView = CType(sqlHolidayLogo.Select(DataSourceSelectArguments.Empty), DataView)
returnstring = "iadb_v2_sys_graphics/iadb_v2_logos/" & dvHolidayLogo(0)("logo")
End If
Return returnstring
End Function
End Class
The website compiles with no errors, yet the function is either not being accessed or is returning a null since the logo is not showing up on the page. The code on the page at runtime is"
<img id="ctl00_img_fp_logo" class="img_fp_logo" />
There is probably a simple issue that I'm missing, but what's wrong?
Upvotes: 0
Views: 31
Reputation: 49264
First of all, to use code in a class, you first need to create an instance of that class.
Next up, you using "#", which is a data binding expression. I doubt that will work, unless you have in the master page load event a Page.DataBind() line of code. But then again, since you would have to add that to the master page load event, then why not just do this:
Assuming this control is in master page markup:
Then you code will look much like this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim cHoliday As New getHolidayLogo
Dim sResult = cHoliday.get_Holiday_Logo(MySqlDataSource, MySqlDataSourceJunk)
img_fp_logo.ImageUrl = sResult
End Sub
In other words, you can't use a class until such time you create an instance of the class, and THEN you can use or consume methods of that class.
Now, you could of course consider making the function inside of that class as what we call "static" and that would eliminate the issue of having to first create an instance of the class.
So, you could I suppose declare the function get holiday logo as "Shared". This then means you can write your code this way:
So, you would thus declare the function as:
Public Shared Function get_Holiday_Logo(sqlUtilities.......
Then our code (master page load event) becomes:
Dim sResult = getHolidayLogo.get_Holiday_Logo(MySqlDataSource, MySqlDataSourceJunk)
img_fp_logo.ImageUrl = sResult
As noted, I don't know where or how the 2 parameters you have are to be used, and I would actually not bother doing as such.
In fact, probably better is to just add a standard code module to the App_code folder, and thus you can then place inside all of your helper routines.
So, if we really wanted to use or have a server-side expression? Well, server controls DO NOT allow server-side expressions in the markup!!!
That means you would still have to execute a control.DataBind() expression, or NOT use a server side expression!
I am most happy to post working code for a image.
You would thus drop in a standard HTML image control, without the runat=server. Since in your case the control is "already" a server-side control? Then server-side expressions are not required, or even supported! This would thus give rise to having 2 places to setup code for a server control, and thus it not allowed.
However, "#" expressions and data binding, then yes, such controls when inside of a data bound control are allowed.
So, for a server side expression to work here, then you use a HTML image control for a "<%=" expression to work (not the asp.net image control).
Since you using a server-side control? Then just use the page load event of your master page to setup the URL for that image.
Hence, server-side controls in markup don't allow use of imbedded server-side expressions. Those are expressions with <%= %> in the markup. As noted, you can use a <%# %> (data binding expression) in such markup, but such server side expressions will not run unless you use code behind to trigger a data bind expression.
If you going to keep your existing code (which I'm not all that convinced that it works), then you need to create an instance of the class before you call the function (method) in that class.
And it is not clear why you are using a DataView here? Seems more practical to use a DataTable.
So, for a working code example?
Well, I don't use App_code anymore, and I strongly recommend you don't either (there are reasons for this - mostly do to code compiling).
I thus suggest you create a folder called MyCode, and add your class and code modules to that folder (set build action of each class and module you add to compile in the properties sheet).
So, a working example?
I would use this code, placed in a standard code module, not a class:
Public Function GetHolidayLogo() As String
Dim PicURL As String =
"~/Content/Holidays/default.png"
Dim strSQL As String =
"SELECT * FROM Holidays WHERE HolidayDate = @d"
Dim cmdSQL As New SqlCommand(strSQL)
cmdSQL.Parameters.Add("@d", SqlDbType.Date).Value = DateTime.Today
Dim dtHoliday As DataTable = MyRstP(cmdSQL)
If dtHoliday.Rows.Count > 0 Then
PicURL = dtHoliday.Rows(0)("PicturePath")
End If
Return PicURL
End Function
And then in page load of master, I would have this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
img_fp_logo.ImageUrl = GetHolidayLogo()
End Sub
And the markup for that image control would be:
<asp:Image ID="img_fp_logo"
CssClass="img_fp_logo" runat="server"
width="128px"
/>
And in my global general code module I have this helper routine to consume SQL statements and return a data table:
Public Function MyRstP(cmdSQL As SqlCommand) As DataTable
Dim strCon As String =
ConfigurationManager.ConnectionStrings("TEST4").ConnectionString)
Dim rstData As New DataTable
Using conn As New SqlConnection(strCon)
Using (cmdSQL)
cmdSQL.Connection = conn
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
Upvotes: 0