Solved

xmldatasource on page load coding

Posted on 2008-06-26
15
1,639 Views
Last Modified: 2013-11-07
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
Comment
Question by:Tania_Farmer
  • 7
  • 7
15 Comments
 
LVL 5

Expert Comment

by:buraksarica
ID: 21873874
Can you provide the exact error statement?
0
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 21873955
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
 

Author Comment

by:Tania_Farmer
ID: 21874061
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
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 21874173
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
 

Author Comment

by:Tania_Farmer
ID: 21874511
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
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 21874685
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
 

Author Comment

by:Tania_Farmer
ID: 21874825
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 18

Expert Comment

by:carlnorrbom
ID: 21877669
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
 

Author Comment

by:Tania_Farmer
ID: 21882261
How do i do that?
Could you show an example.

T
0
 

Author Comment

by:Tania_Farmer
ID: 21882623
Sorry re-read - will put code in in a sec.
T
0
 

Author Comment

by:Tania_Farmer
ID: 21882702

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
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 21883010
I will have a look at it and get back to you in a while.

/Carl.
0
 
LVL 18

Accepted Solution

by:
carlnorrbom earned 500 total points
ID: 21891460
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
 

Author Comment

by:Tania_Farmer
ID: 21898723
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
 
LVL 18

Expert Comment

by:carlnorrbom
ID: 21899184
Tania,

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

/Carl.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now