• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1709
  • Last Modified:

xmldatasource on page load coding

Hi,
I presently have this on several pages:

  <asp:XmlDataSource id="XmlSource1" DataFile="/App_Data/nl.xml" runat="server" XPath="newsletters/backissues/newsletter[@date='March 2008']" />
  <asp:XmlDataSource id="XmlSource2" DataFile="/App_Data/nl.xml" runat="server" XPath="newsletters/backissues/newsletter[@date='March 2008']/content" />

I wanted to move it to move the datafile to my UC so the only thing on the newsletter page is the below and with the Xpath changing per page depending:

<asp:XmlDataSource id="XmlSource1" runat="server" XPath="newsletters/backissues/newsletter[@date='March 2008']" />
  <asp:XmlDataSource id="XmlSource2" runat="server" XPath="newsletters/backissues/newsletter[@date='March 2008']/content" />

This was my terrible attempt at writing the code which obviously doesnt work:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 dim XmlSource1 as XmlDataSource
 XmlSource1 = new XmlDataSource()
 XmlSource1.DataFile = (Server.MapPath("/App_Data/nl.xml"))
 XmlSource1.DataBind()
 
 dim XmlSource2 as XmlDataSource
 XmlSource2 = new XmlDataSource()
 XmlSource2.DataFile = (Server.MapPath("/App_Data/nl.xml"))
 XmlSource2.DataBind()
 End Sub
 
End Class
 
This just gets constant errors.  What is the correct way to reference the file which is used by 2 datasources and run it in the Page Load?
 
Thanks
Tania

Open in new window

0
Tania_Farmer
Asked:
Tania_Farmer
  • 7
  • 7
1 Solution
 
buraksaricaCommented:
Can you provide the exact error statement?
0
 
carlnorrbomCommented:
I guess what's going wrong is the actual Server.MapPath()?!? You're missing a tilde in the relative path string as far as can see, correct string would be:

XmlSource1.DataFile = Server.MapPath("~/App_Data/nl.xml")

Give that a go and see if it solves the issue.

/Carl.
0
 
Tania_FarmerAuthor Commented:
hi,
added the ~ but still get a null error.  

System.NullReferenceException: Object reference not set to an instance of an object.

When the link is in the asp:xmldatasource its ok.

T.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
carlnorrbomCommented:
Hi,

Are you instatiating the XmlDataSource both declaratively and programatically maybe? If You declare them in Your aspx page as <aps:XmlDataSource.../> then they should only be referenced in the code behind, i.e:

XmlSource1.DataFile = Server.MapPath("~/App_Data/nl.xml")
XmlSource1.Databind()

It should not be redimensioned in the code behind. If you are using master pages or similar and can't directly reference it in the code behind you can do a:

Dim XmlSource1 As XmlDataSource = CType(Me.FindControl("XmlSource1"), XmlDataSource)

/Carl.
0
 
Tania_FarmerAuthor Commented:
HI,
I tried this:
            Dim XmlSource1 As New XmlDataSource()
Me.Controls.Add(XmlSource1)
XmlSource1.DataFile = Server.MapPath("~/App_Data/nl.xml")
XmlSource1.DataBind()

            Dim XmlSource2 As New XmlDataSource()
Me.Controls.Add(XmlSource2)
XmlSource2.DataFile = Server.MapPath("~/App_Data/nl.xml")
XmlSource2.DataBind()

And its still a null error.  I am still referencing the <asp:XMLDatasource in the page as it defines the  main XPath="newsletters/backissues/newsletter[@date='March 2008']" />
and changes page to page.  The datafile however is the same.

In the control I have this:



 <asp:Repeater ID="Repeater_feature" DataSourceID="XmlSource1" runat="server">
 
  <ItemTemplate>
  <h1>Newsletter: <%# XPath ("@date") %></h1>
  <div class="feature">
    <p>Dear reader, <br />
      Just a quick notice to let you know our web site has been updated. </p>
      <%# XPath ("extracomments", "<p>{0}</p>") %>
    <asp:Repeater ID="Repeater_feature2" DataSource=<%# XPathSelect("content") %>  runat="server">
      <headerTemplate>        <ol>      </headerTemplate>
      <ItemTemplate>        <li><%# XPath ("@title") %> </li>      </ItemTemplate>
      <footerTemplate><li>Latest Training Schedule</li>    </ol>      </footerTemplate>
    </asp:Repeater>
   
  </div>
    </ItemTemplate>
    </asp:Repeater>

Open in new window

0
 
carlnorrbomCommented:
So, just to see if I get things here. You declare the XmlSource1 in Your aspx page using <asp:XmlDataSource ../>. And then in Your code behind You declare it again but programatically using "Dim XmlSource1 As New XmlDataSource"? You see, that won't work in my book. Either You delcare it in the aspx page OR programatically in your code behind, not both. It's just as easy to declare the Xpath info in the code behind as well, just do:

XmlSource1.XPath = "newsletters/backissues/newsletter[@date='March 2008']"

The repeater code, is that in a user control? Are You declaring the xml data sources in the code behind for the user control? Just trying to get my thick head around what You're trying to get done =)

/Carl.
0
 
Tania_FarmerAuthor Commented:
yes - i am (was :-) ). was looking at the databind and asp:xmldatasource as an extension of one another like you get to do with xpath  - where you can declare a certain amount in the datasource and then filter more.

XmlSource1.XPath = "newsletters/backissues/newsletter[@date='March 2008']"  /and in the page <li><%# XPath ("@title") %> </li>

So it sounds like a bad thing!  So,

1.  can this be put in the page script? XmlSource1.XPath = "newsletters/backissues/newsletter[@date='March 2008']"  or how should i do this so it can be changed easily?

Basically I have 10 pages that all share a user control with the above repeater_feature and a listview.  The datafile is the same on all the 10pages.

What changes on each of the pages is the xpath:
Page: feb2008.aspx: XmlSource1.XPath = "newsletters/backissues/newsletter[@date='Feb 2008']"
Page: jan2008.aspx: XmlSource1.XPath = "newsletters/backissues/newsletter[@date='January 2008']"
etc.

The repeater and listview are in the control and the declaration is in the user code behind file.

Thanks.
T
 
 
0
 
carlnorrbomCommented:
Well,

Let's see. If the only variable is the XPath then You should probably try to keep all the logic in the user control, and preferably handle the databinding in the usercontrols code behind. The easiest implementation in order to avoid rewriting a lot of code all the time is to collect the datepart either through a querystring appended to the url or by examining the page name in code behind and use some logic to create the XPath based on that.

If You could attach the files (usercontrol.ascx, usercontrol.ascx.vb) I can have a go at implementing the needed logic for you.

/Carl.
0
 
Tania_FarmerAuthor Commented:
How do i do that?
Could you show an example.

T
0
 
Tania_FarmerAuthor Commented:
Sorry re-read - will put code in in a sec.
T
0
 
Tania_FarmerAuthor Commented:

page: newsletterSample.aspx
<%@ Page  MasterPageFile= "~/template/aspx/main.master"       %>
<asp:Content id="Content2" ContentPlaceholderID="mainContent" runat="server">
  <asp:XmlDataSource id="XmlSource1" runat="server" DataFile="/App_Data/nl.xml" XPath="newsletters/backissues/newsletter[@date='March 2008']" />
  <asp:XmlDataSource id="XmlSource2" runat="server" DataFile="/App_Data/nl.xml" XPath="newsletters/backissues/newsletter[@date='March 2008']/content" />
 <myxml:newsletterUC runat="server" />
</asp:Content>
 
newsletterUC.ascx
 
<%@ Control   CodeFile="newsletterUC.ascx.vb" Inherits="newsletterUC" %>
 
 <asp:Repeater ID="Repeater_feature" DataSourceID="XmlSource1" runat="server">
 
  <ItemTemplate>
  <h1>Newsletter: <%# XPath ("@date") %></h1>
  <div class="feature">
    <p>Dear reader, <br />
      Just a quick notice to let you know our web site has been updated. </p>
    <asp:Repeater ID="Repeater_feature2" DataSource=<%# XPathSelect("content") %>  runat="server">
      <headerTemplate>        <ol>      </headerTemplate>
      <ItemTemplate>        <li><%# XPath ("@title") %> </li>      </ItemTemplate>
      <footerTemplate>   </ol>      </footerTemplate>
    </asp:Repeater>
  </div>
    </ItemTemplate>
    </asp:Repeater>
    
    
<asp:ListView ID="ListView1" runat="server" DataSourceID="XmlSource2">
  <LayoutTemplate>
    <dl class="archive"  >
      <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
    </dl>
  </LayoutTemplate>
  <ItemTemplate>
    <%#getTitle()%> 
	<%#getSummary()%>
     </ItemTemplate>
</asp:ListView>
 
newsletterUC.ascx.vb
Partial Class newsletterUC
    Inherits System.Web.UI.UserControl
	
	Public Function getTitle() As String    		
        Dim value As String = XPath("url")
	   	Return String.Concat("<dt><a href=""", value, """ title=""", XPath("@title"),"""  >", XPath("@title")," </a></dt>")		  
    End Function
	
    Public Function getSummary() As String
        Dim value As String = XPath("p")
      	Return String.Concat("<dd>", value, "<br class=""clearfloat"" /></dd>")
    End Function
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
				
	End Sub
 		
End Class
 
 
nl.xml
<?xml version="1.0" encoding="utf-8"?>
<newsletters>
  <backissues year="2008">
    <newsletter title="Newsletter - March 2008" date="March 2008" shortdate="08mar">
      <feature>yes</feature>
	  <comments>something</comments>
      <content title="City Tyres1 "   >
        <p>The countdown is on...get your 4x4 ready and forms in. .....</p>
        <url>/chimp4x4/</url>
      </content>
      <content title="City Tyres2"   >
        <p>The countdown is on...get your 4x4 ready and forms in. .....</p>
        <url>/chimp4x4/</url>
      </content>
      <content title="City Tyres3 "   >
        <p>The countdown is on...get your 4x4 ready and forms in. .....</p>
        <url>/chimp4x4/</url>
      </content>
    </newsletter>
   </backissues>
</newsletters>

Open in new window

0
 
carlnorrbomCommented:
I will have a look at it and get back to you in a while.

/Carl.
0
 
carlnorrbomCommented:
Hi again!

Sorry for taking a while to produce anything on this but I chose to spend some quality time with my 3 year old daughter rather than sitting on front of a computer.

Anyways, I reviewed your code and made some changes and additions:

1. Added som private declarations
2. Added four public properties for the UC: DataFilePath(), Month(), Year() and StaticXPath
3. Added logic to handle four different scenarios:

Scenario 1: You name the page which is to contain the UC according to your earlier abbreviation, i.e: /mmmyyyy.aspx for instance /feb2008.aspx

Scenario 2: You drop the UC into a completely different page (i.e: /Default.aspx) but provide a querystring in the format of ?Year=YYYY&Month=FullMonthName (i.e: /Default.aspx?Year=2008&Month=February).

Scenario 3: You drop the UC into a page but forget / don't provide a querystring. The logic will assign the current month and year to the private variables.

Scenario 4: You set the needed variables through the publically exposed properties from code behind at runtime.

All the logic is now built into the UC, You really don't have to do anything on the page that contains the UC, no data sources or anything. The ONLY thing You need to do is to drag and drop the UC on the page. If You have named the page accordingly or alternatively provide the querystring you should be in business. The different properties will provide You with a greater flexibility since you will be able to utilize different datafiles and also xml which is layed out differently, just change the StaticXPath and DataFile properties.

You will also get intellisense for all the public properties in VS so it should be easy to work out from code behind. I have tested it in my environment and everything checks out, so please go ahead and test it in Your own environment and let me know if you come across some issues. Since EE doesn't allow code files to be uploaded I have attached them as code snippets, let me know if you want me to send an email or so with the org files.

/Carl.
newsletterUC.aspx:
 
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="newsletterUC.ascx.vb" Inherits="newsletterUC" %>
 
<asp:Repeater ID="Repeater_feature" DataSourceID="repXmlSource" runat="server">
    <ItemTemplate>
        <h1>
            Newsletter:
            <%# XPath ("@date") %></h1>
        <div class="feature">
            <p>
                Dear reader,
                <br />
                Just a quick notice to let you know our web site has been updated.
            </p>
            <asp:Repeater ID="Repeater_feature2" DataSource='<%# XPathSelect("content") %>' runat="server">
                <HeaderTemplate>
                    <ol>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <%# XPath ("@title") %>
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    </ol>
                </FooterTemplate>
            </asp:Repeater>
        </div>
    </ItemTemplate>
</asp:Repeater>
<asp:XmlDataSource ID="repXmlSource" runat="server" />
<asp:ListView ID="ListView1" runat="server" DataSourceID="listXmlSource">
    <LayoutTemplate>
        <dl class="archive">
            <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
        </dl>
    </LayoutTemplate>
    <ItemTemplate>
        <%#getTitle()%>
        <%#getSummary()%>
    </ItemTemplate>
</asp:ListView>
<asp:XmlDataSource ID="listXmlSource" runat="server" />
 
newsletterUC.aspx.vb:
 
 
Partial Class newsletterUC
    Inherits System.Web.UI.UserControl
 
#Region "Private Declarations"
 
    Private _strDataFilePath As String = "~/App_Data/nl.xml"
    Private _strMonth As String = Nothing
    Private _strYear As String = Nothing
    Private _strStaticXPath As String = "newsletters/backissues/newsletter"
    Private _strRepeaterXPath As String = Nothing
    Private _strListViewXPath As String = Nothing
 
#End Region
 
#Region "Public Properties"
 
    Public Property DataFilePath() As String
        Get
            Return _strDataFilePath
        End Get
        Set(ByVal value As String)
            _strDataFilePath = value
        End Set
    End Property
 
    Public Property Month() As String
        Get
            Return _strMonth
        End Get
        Set(ByVal value As String)
            _strMonth = value
        End Set
    End Property
 
    Public Property Year() As String
        Get
            Return _strYear
        End Get
        Set(ByVal value As String)
            _strYear = value
        End Set
    End Property
 
    Public Property StaticXPath() As String
        Get
            Return _strStaticXPath
        End Get
        Set(ByVal value As String)
            _strStaticXPath = value
        End Set
    End Property
 
#End Region
 
#Region "Public Functions"
 
    Public Function getTitle() As String
        Dim value As String = XPath("url")
        Return String.Concat("<dt><a href=""", value, """ title=""", XPath("@title"), """  >", XPath("@title"), " </a></dt>")
    End Function
 
    Public Function getSummary() As String
        Dim value As String = XPath("p")
        Return String.Concat("<dd>", value, "<br class=""clearfloat"" /></dd>")
    End Function
 
#End Region
 
#Region "Page Events (UC loaded)"
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'Define the property values for Month and Year depending on either A) Page name or B) querystring parameters.
        Dim IsQueryString As Boolean = False
 
        If (Request.Url.ToString.IndexOf("?") > 0) Then 'Check to see if we can find a ? in the url which means we have querystring parameters passed to the page.
            IsQueryString = True
        End If
 
        If IsQueryString Then 'We have querystring parameters but we must check and see if they pass values for month and year.
 
            If Request.Url.ToString.Substring(Request.Url.ToString.IndexOf("?"), 6) = "?Month" Or Request.Url.ToString.Substring(Request.Url.ToString.IndexOf("?"), 5) = "?Year" Then
 
                _strMonth = Request.QueryString("Month").ToString
 
                If String.IsNullOrEmpty(_strMonth) Then 'If a null value is passed, set the current month
                    _strMonth = MonthName(DateTime.Now.Month).ToString
                End If
 
                _strYear = Request.QueryString("Year").ToString
 
                If String.IsNullOrEmpty(_strYear) Then 'If a null value is passed, set the current year
                    _strYear = DateTime.Now.Year.ToString
                End If
 
            End If
 
        End If
 
        Dim strPageName As String = Request.Url.ToString.Substring((Request.Url.ToString.LastIndexOf("/") + 1), (Request.Url.ToString.Length - (Request.Url.ToString.LastIndexOf("/") + 1)))
 
        If strPageName.ToString.Substring(3, 2) = "20" Then 'It's most probably a year in the page name and a 3 letter month abbreviation (i.e: /mmmyyyy.aspx)
 
            _strYear = strPageName.ToString.Substring(3, 4)
 
            Dim strMonth As String = strPageName.ToString.Substring(0, 3) 'Since the pages use an abbreviation for the monthname we circle through and assign the correct name.
 
            If strMonth = "jan" Then
                _strMonth = "January"
            ElseIf strMonth = "feb" Then
                _strMonth = "February"
            ElseIf strMonth = "mar" Then
                _strMonth = "March"
            ElseIf strMonth = "apr" Then
                _strMonth = "April"
            ElseIf strMonth = "may" Then
                _strMonth = "May"
            ElseIf strMonth = "jun" Then
                _strMonth = "June"
            ElseIf strMonth = "jul" Then
                _strMonth = "July"
            ElseIf strMonth = "aug" Then
                _strMonth = "August"
            ElseIf strMonth = "sep" Then
                _strMonth = "September"
            ElseIf strMonth = "oct" Then
                _strMonth = "October"
            ElseIf strMonth = "nov" Then
                _strMonth = "November"
            ElseIf strMonth = "dec" Then
                _strMonth = "December"
            End If
        End If
 
        If Not IsQueryString And Not strPageName.ToString.Substring(3, 2) = "20" Then 'All else failed, assign current month and Year
 
            If _strMonth Is Nothing Then
                _strMonth = MonthName(DateTime.Now.Month)
            End If
 
            If _strYear Is Nothing Then
                _strYear = DateTime.Now.Year
            End If
 
        End If
 
        _strRepeaterXPath = _strStaticXPath & "[@date='" & _strMonth.ToString & " " & _strYear.ToString & "']"
        _strListViewXPath = _strStaticXPath & "[@date='" & _strMonth.ToString & " " & _strYear.ToString & "']/content"
 
        repXmlSource.DataFile = _strDataFilePath
        repXmlSource.XPath = _strRepeaterXPath
        repXmlSource.DataBind()
 
        listXmlSource.DataFile = _strDataFilePath
        listXmlSource.XPath = _strListViewXPath
        listXmlSource.DataBind()
 
    End Sub
 
#End Region
 
End Class

Open in new window

0
 
Tania_FarmerAuthor Commented:
That is absolutely fantastic.

I can work through it to understand the structure and apply it to other sections I was running up to similiar problems.

Thanks for taking the time!
Cheers
Tanai
0
 
carlnorrbomCommented:
Tania,

You're welcome, just glad I could be of assistance. Happy coding!

/Carl.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now