Tim Laughlin's Everything VB.NET Blog


Copying an instance of a class object

I recently had a need to copy the instance of a fairly complex class object.  More specifically what wanted was to load and instance of the object, from a data source.  The object had about 40 properties some of which where collections of other classes. 

So creating a new instance of the object then setting each property would be more time consuming and less elegant that I would like.  Doing as standard set would just set a reference to the first object.  So changes on the second object would made on the first instance.  This was not the behavior I wanted either. 

After doing a Google search and combining a few examples this what I cam up with.

    Public Sub CopyObject( _
        ByVal pObjectType As Type, _
        ByVal pOriginalObject As Object, _
        ByRef pNewObject As Object)

        Dim ArPoperties() As Reflection.PropertyInfo = _
        pObjectType.GetProperties(Reflection.BindingFlags.Public Or _
        Reflection.BindingFlags.Instance)
        Dim ObjPropItem As Reflection.PropertyInfo
        For Each ObjPropItem In ArPoperties
            If ObjPropItem.CanWrite Then
                ObjPropItem.SetValue(pNewObject, _
                ObjPropItem.GetValue(pOriginalObject, Nothing), Nothing)
            End If
        Next
    End Sub
As is the goal if this blog.  I hope you find this useful. 
Quick and Dirty ad rotation in Community Server 2007

I needed to setup ad rotation for a client in Community Server 2007.  The goal was to rotate through a pool of ads for internal events and content.  There was no need for tracking impressions and click through rates.  So something like adMentor seemed like over kill.

After consulting Google I found an old post on CommunityServer.org. It showed how to use the ASP.NET ad rotator control in CS 2.1.  So information here isn't original.  But, it adapted to cs2007.

My client is using a modified version of the Lean and Green theme.  So will use that as my example. 

Open the Themes\leanandgreen\Common\ad-top.ascx.

below <%-- Place ad mark-up here --%> enter.  Delete any other text that may be below this tag.

<div align="center">
<asp:AdRotator id="adRotator" 
runat="server" AdvertisementFile="ads.xml" Target="_top" /> </div>

This declares the ASP.NET AdRotator control, and obviously centers it.

repeat these steps for ad-bottom.ascx

Create a ads.xml file in the Themes\leanandgreen\Common\ directory.  The format of this file should be. (for more in depth explanation see MSDN)

<Advertisements>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/conferencebanner.jpg</ImageUrl>
        <NavigateUrl>http://www.albinism.org/noahevents.html?utm_source=AOC&amp;utm_medium=banner&amp;utm_content=conferencebanner&amp;utm_campaign=Conference2008</NavigateUrl>
        <AlternateText>Ad: NOAH National Conference Information</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>Conference</Keyword>
    </Ad>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/conferencebanner2.jpg</ImageUrl>
        <NavigateUrl>http://www.albinism.org/noahevents.html?utm_source=AOC&amp;utm_medium=banner&amp;utm_content=conferencebanner2&amp;utm_campaign=Conference2008</NavigateUrl>
        <AlternateText>Ad: NOAH National Conference Information</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>Conference</Keyword>
    </Ad>
        <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/newcity.jpg</ImageUrl>
        <NavigateUrl>http://www.albinism.org/noahevents.html?utm_source=AOC&amp;utm_medium=banner&amp;utm_content=newcity&amp;utm_campaign=Conference2008</NavigateUrl>
        <AlternateText>Ad: NOAH National Conference Information</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>Conference</Keyword>
    </Ad>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/giveback.jpg</ImageUrl>
        <NavigateUrl>http://www.albinism.org/contribute.html?utm_source=AOC&amp;utm_medium=banner&amp;utm_content=giveback&amp;utm_campaign=Funding</NavigateUrl>
        <AlternateText>Ad: Support NOAH Funding</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>Funding</Keyword>
    </Ad>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/purplebowlathonbanner.jpg</ImageUrl>
        <NavigateUrl>http://www.events.org/noah08/cpage.aspx?e=12334</NavigateUrl>
        <AlternateText>Ad: NOAH Bowl-A-Thon</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>BowlAThon</Keyword>
    </Ad>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/thingathon.jpg</ImageUrl>
        <NavigateUrl>http://www.events.org/noah08/cpage.aspx?e=12334</NavigateUrl>
        <AlternateText>Ad: NOAH Bowl-A-Thon</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>BowlAThon</Keyword>
    </Ad>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/puzzle.jpg</ImageUrl>
        <NavigateUrl>http://www.events.org/noah08/cpage.aspx?e=12334</NavigateUrl>
        <AlternateText>Ad: NOAH Bowl-A-Thon</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>BowlAThon</Keyword>
    </Ad>
    <Ad>
        <ImageUrl>http://www.albinism.org/bannerads/whatthingathon.jpg</ImageUrl>
        <NavigateUrl>http://www.events.org/noah08/cpage.aspx?e=12334</NavigateUrl>
        <AlternateText>Ad: NOAH Bowl-A-Thon</AlternateText>
        <Impressions>50</Impressions>
        <Keyword>BowlAThon</Keyword>
    </Ad>

</Advertisements>

Finally log into your control panel.  Then choose Administration / System Tools / Manage Ads.

Check Enable ads, check enable inline ad control, finally uncheck SystemAdminstrator if you want you admins to see ads as well.

Good luck, let me know if you found this helpful, or have any questions.

Graffiti Beta 1 - Come see my Sandbox

Telligent has released their long awaited CMS named Graffiti.  Since I am more into experimenting then writing.  I thought the best think to do would be to make my Graffiti Sandbox publicly available.  Then I can experiment and write in the same place.

So come on over the Tim Laughlin's Graffiti Sandbox.  Subscribe the sites RSS feed and watch my progress.  Or chuckle at my failures, as the case my be.

Step one a new skin.

image

Posted: Dec 09 2007, 10:53 AM by tlaughlin | with no comments
Filed under:
Consuming web services from AJAX, be careful.

As you are probably aware AJAX has made it very easy to consume web services asynchronously from the browser.  If you are not aware of how to do this here some great resources, on how to do it

Understanding ASP.NET AJAX Web Service Proxies - Dan Wahlin - A great introduction to how the technology works.
Consuming Web Service Using ASP.NET AJAX - Blpin Joshi - An example of how to do build a database crud application with client side calls to web services.

The later example I have converted to VB.NET and AJAX 1.0.  The original was in C# and a pre release of AJAX.  I will also use this example to illustrate some of the security issues that can be introduced unknowingly.

When you start the application it looks something like this:

Screen Shot

As you change the employee ID the First Name and Last Name are updated without a post back.  Work like you would hope an AJAX application would.

Now suppose you didn't want to give the public the ability to add or delete employees you could simply remove the buttons.  However, that would not remove the functionality.  If you where to look at the source of the page you might be surprised to find this reference:

<script src="EmployeeService.asmx/js" type="text/javascript"></script>
Look at that a reference to an .asmx file.  I know actually it's a reference to a javascript file.  However, the web service file name is pretty easy to identify.  So what happens if we point a web browser at that file? 
image

A nice WSDL of all our functions.  Including update and delete.  using just this file a person could easily compromise our system.  Hiding the Delete and Insert buttons would do little prevent them using the web service directly.

I'm not saying don't use these services.  But please be aware of the information that is being revealed.  Also make sure you secure your asmx files and disable the WSDL.

Finally, don't leave any functions in the asmx files that would want executed by the world.

Posted: Dec 05 2007, 09:47 AM by tlaughlin | with no comments
Filed under: ,
Modal View Controller (MVC) Framework - This looks Great!

ScottGu has been blogging about the MVC. This the first really cool thing that I have seen come out of VS 2008.  Don't get my wrong I am looking forward the VS 2008, but nothing huge until now.

Finally, a production quality URL writing system for data driven web sites.  With out all the query string stuff.  If this works as advertised out data driven sites should have reasonable human readable URLs with out have to do a ton of HttpHandler logic.  In ScottGu's  ASP.NET MVC Framework (Part 1) - ScottGu's Blog; he does an amazing job of detailing the usage of MVC.  I can't wait for Part 2.

Scott thanks for taking the time to demonstrate the MVC.  Your level of detail is greatly appreciated.

Posted: Nov 13 2007, 01:42 PM by tlaughlin | with no comments
Filed under:
Select Distinct on Datatable

I was trying to select some distinct rows from a DataSet datatable.  After consulting Google and finding very little I finally found Erik Porter's blog entry.  Which a great resource if you are using .NET 1.0 or .NET 1.1 which makes sense since he wrote back in 2005.

He also added a small note that is key if you are using .NET 2.0 and above.  the reads.

"UPDATE 2: Jackie Goldstein sent me an e-mail pointing out that .NET 2.0's DataView has a ToTable Method that will build a DataTable based off of the current DataView and also allow you to specify which columns you want in the DataTable as all as being able to say Distinct rows only.  I had totally forgotten about this feature and didn't even know it did distinct rows.  Thanks, Jackie!  :) "

The .ToTable method is awesome but hard find information on.  So here is how I used to create a distinct datatable to populate a drop down list.

    Public Function GetDepartureAirlines() As DataTable
        Dim ObjDV As New DataView
        Dim StrARCols(1) As String
        StrARCols(0) = "AirlineID"
        StrARCols(1) = "AirlineName"
        ObjDV.Table = mObjFlightDS.Flights
        ObjDV.Sort = "AirlineName asc"
        ObjDV.RowFilter = "FlightType = 'D'"
        Return ObjDV.ToTable("Airlines", True, StrARCols)

    End Function

This greatly simplifies the select distinct requirement.  The key is the second parameter in the .ToTable method.  The boolean true lets the ADO.NET deal with the distinct requirement based on the columns you choose to include in your new datatable

Erik, thanks for the quick note and the original post.  As you comments indicate your post was of great help.  I can only hope this one is half as affective for the ADO.NET 2.0 crowd.

Posted: Oct 31 2007, 12:37 PM by tlaughlin | with no comments
Filed under: ,
Missed the CSDC - Why I'll never fly US Airways again!

I didn't make it to the Community Server Developers Conference, thanks to US Airways new software. 

There was weather in North East on Friday that had air travel backed up.  However, US Airways was worse off than most.  Seems they have a new computer system that either works horribly or they failed to train people on.  None the less, the customers are paying the price.

I stood in line a the gate for 40 minutes, in that time the rerouted 1 passenger.  I was number four in line.  Then the decided those who are going to miss their connection should leave security and go to the check in  counter to be rerouted.

Another 30 minute wait - 2 customers.  Then they couldn't get me to Dallas until after noon on the following day.  I asked to be booked on one the other alliance carriers and even offered to drive to Boston if need be.   They couldn't figure out how to find any other flights on partner airlines.  In the end I decided to I just wanted my money back and would cut my looses. 

To which, I got we can't do that, this is a weather related problem.  After holding up everyone for another 20 minutes explaining that their inability to operate their computer was not a weather issue. 

Long story short I was given my money back for the airline tickets.  Or so I have been told.  They couldn't even print a confirmation, couldn't load paper in to the printer; if you can believe that!

This was a amazing failure on US Airways part and will be why I will never book another flight on this carrier. 

Heading to the CSDC

I am heading to the Community Server Developers Conference at the end of the week.  I am totally unprepared! I was hoping to have played a lot more with Community Server 2007 and learned more about Chameleon, but the paying customers have been keeping me busy.

Oh, well I am sure it will still be an interesting event.  The agenda looks good and many areas I am interested in.   Especially a sneak at Community Server 2008. 

I'm hoping Telligent will let us see Graffiti!  Maybe get the beta, please.....

AdSense Video Units

Okay so Google has released Video Units for AdSense.  So I thought I would give it a try.  Why, because I want to see if they actually match video content to blog content.

Early indications are not promising.  The videos, though entertaining don't have anything to do with the technical content of this blog.  That is when there is any content. 

The ads displayed have very little to do with this blog either.  I am going to leave it up for while see what happens.  Maybe it will get better.  If nothing else we can all get our fill of Chad Vader. 

Posted: Oct 11 2007, 10:36 AM by tlaughlin | with no comments
Filed under:
CS 2007.1 Released - and worth the install!

Telligent has just released Community Server 2007.1.  The is a point release to Community Server 2007.  I have installed it and then fired up Live Writer to see if I could find any differences.

In Live Writer I went to Weblogs/ Edit weblog settings.  Then choose Editing and pressed Update Editing Style.  My theme style was downloaded and is now showing in Live Writer.

This makes blogging much nicer.  So if only for this reason I would update Community Server 2007.  Though there are many more good reasons to do so.  Here is the list of changes.

Install was flawless by the way.

Community Server blogs and code inclusion

So now that I am back to blogging on a more regular basis, I wanted to find an easy way to include formatted code in my blog entries.  I think I could the solution for me.  It is a plug in for Windows Live Writer called Code Insert.  There is also a web based interface for those of you who don't want to use Live Writer.

One problem I had was in trying to embed the styles in to the code. Community Server 2007 displayed the style section rather than using it as style.  The work around was quite easy. 

  1. Copy the provided style sheet to notepad.
  2. In your Community Server 2007 /themes/blogs/[yourthemeanme]/styles/ folder save new style sheet as CodeInsert.css
  3. in your Community Server 2007 /themes/blogs/[yourthemeanme]/ folder edit theme.master and add the following line with all the other stylesheets.
<CSBlog:ThemeStyle Href="~/style/CodeInsert.css" Media="screen" runat="server" />
Once you install the plug-in you should see Insert Code in the Insert List.  It will open a window like this.
image 
Make sure you uncheck the Embed StyleSheet checkbox. 
Here come Examples:
HTML/asp.net
<head runat="server">
<CSControl:Head ID="Head1" runat="Server" >
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <CSBlog:ThemeStyle Href="~/style/style.css" Media="screen" runat="server" />
    <CSBlog:ThemeStyle Href="~/style/print.css" Media="print" runat="server" />
    <CSBlog:ThemeStyle Href="~/style/CodeInsert.css" Media="screen" runat="server" />
    <CSControl:SectionThemeConfigurationDataStyle StyleUrlProperty="secondaryCssUrl" Media="screen" runat="server" />
    <CSBlog:ThemeStyle Href="~/style/DynamicStyle.aspx" Media="screen" runat="server" EnsureNotCachedOnPreview="true" />
</CSControl:Head>
</head>
VB.NET
Private Sub LookupSite()
        Dim StrSiteName As String
        Dim ObjSite As EntityClasses.SiteEntity

        StrSiteName = Request.Cookies("site").Value

        mStrSiteName = StrSiteName
        ObjSite = New EntityClasses.SiteEntity(mStrSiteName)
        LitSiteName.Text = ObjSite.DisplayName
        Select Case Request.QueryString("type")
            Case "cr"
                mStrDocType = "c"
                Page.Title = "Creative Review - " & ObjSite.DisplayName
        End Select

End Sub
C#
public override void WriteAttribute(string name, string value, bool fEncode)
{
   if (name == "action")
      {
         if (HttpContext.Current.Items["RewriteFormHtmlTextWriter.ActionWritten"] == null)
            {
               value = CSContext.Current.RawUrl;
               HttpContext.Current.Items["RewriteFormHtmlTextWriter.ActionWritten"] = true;
             }
          }

     base.WriteAttribute(name, value, fEncode);
}
 
Chameleon - A practical experience

As I have blogged before how about I am teaching myself how to use Community Server 2007 theme engine, Chameleon.  I will continue my series on build my first theme.  However today I decided I wanted to tweak a couple things on the NOAH community site. 

The site is using the the Lean and Green theme and running Community Server 2007. Of course we made some color changes to lean and green,  So we are now lean and purple.  But up until today there have been no changes to the Chameleon parts of the site. 

Today I had two goals.

  1. Reduce the over all length of the right sidebar in the forum section.  The sidebar always exceeds the length of the content and is not very visually appealing.  As well the Active Users side bar displayed 10 people, out community is small enough that only about 5 people are active on any given day. 
  2. The next goal was to draw attention to the fact that we recently added blogging to the site.  To accomplish this I wanted to add a list of recent blog entries to the right sidebar in forum section.

Goal 1

So with my limited Chameleon jumped into the /themes/leanandgreen and looked for a place to begin.  Forums sound like the sound like the place, then forum.master looked like the next logical step.  I opened the file and was amazed at how little markup there is actually in the file, only 135 lines.  Okay now what can I find that looks like something I need; scroll down and find:

   1:          <CSForum:ThreadList runat="server">
   2:              <DisplayConditions><CSControl:UserInRoleCondition Role="Registered Users" UseAccessingUser="true" runat="server" /></DisplayConditions>
   3:              <QueryOverrides UserFilter="ShowTopicsParticipatedIn" GroupID="-1" ForumID="-1" PageSize="10" />
   4:              <HeaderTemplate>
   5:                  <div class="CommonSidebarArea">
   6:                  <div class="CommonSidebarTopRound"><div class="t1"></div><div class="t2"></div><div class="t3"></div><div class="t4"></div></div>
   7:                  <CSControl:SiteUrl UrlName="user_MyForums" ResourceName="Utility_ForumAnchorType_MenuMyForums" Tag="H4" CssClass="CommonSidebarHeader" runat="server" />
   8:                  <div class="CommonSidebarContent">
   9:                  <ul class="CommonSidebarList">
  10:              </HeaderTemplate>
  11:              <ItemTemplate>
  12:                      <CSForum:ThreadData runat="server" LinkTo="Thread" Property="Subject" TruncateAt="22" Tag="Li" />
  13:              </ItemTemplate>
  14:              <FooterTemplate>
  15:                  </ul>
  16:                  </div>
  17:                  </div>
  18:              </FooterTemplate>
  19:          </CSForum:ThreadList>

This looks promising, looks like an ASP.NET repeater syntax with some extra stuff.  Let take it a part and see what we find.:

Line 2: Display condition: Must be in role Registered Users, makes sense. Use Accessing user, remember that from theme attempt. So this will display if the current user is in the registered users group.  Basically will not display to anonymous users. 

Line 3: QueryOverrides - UserFilter attribute = ShowTopicsParticipatedIn makes sense.  All the way on the right low and be hold PageSize = 10.  Well, that must be what I want to change. change to 5, reload. Yahoo, it worked.  As Staples says "That was easy".

Scanning down the page change some a few more PageSize="10" to PageSize="5" and I am done with Goal One. Quick sip of coffee and off to goal two.

Goal 2

Now to the more complicated task.  Getting a list of recent blog entries to show up in the forum side bar.  Given the experience above I determined the key areas I needed to change are:

<CSForum:ThreadList runat="server">
<
QueryOverrides UserFilter="ShowTopicsParticipatedIn" GroupID="-1" ForumID="-1" PageSize="10" />
<
CSForum:ThreadData runat="server" LinkTo="Thread" Property="Subject" TruncateAt="22" Tag="Li" />

So in my true programing style I ask, where can I copy and paste some code from to accomplish this task.  Only made sense to find a list of blog entries some where and copy out the elements I need.  So went into the /themes/leanandgreen/blogs folder and found postlist.aspx.  There where some examples there.  After cutting a pasting them together and a few trial and error rounds here is what I came up with.

   1:      <CSBlog:WeblogPostList ID="WeblogPostList1" runat="Server" >
   2:          <QueryOverrides SortBy="MostRecent" SortOrder="Descending" PageSize="5" IsAggregate="true" />
   3:          <HeaderTemplate>
   4:                  <div class="CommonSidebarArea">
   5:                  <div class="CommonSidebarTopRound"><div class="t1"></div><div class="t2"></div><div class="t3"></div><div class="t4"></div></div>
   6:                  <CSControl:SiteUrl ID="SiteUrl1" UrlName="webloghome" Parameter1="-1" ResourceName="Weblog_RecentPostsFromForum"  Tag="H4" CssClass="CommonSidebarHeader" runat="server" />
   7:                  <div class="CommonSidebarContent">
   8:                  <ul class="CommonSidebarList">
   9:          </HeaderTemplate>
  10:          <ItemTemplate>
  11:                  <CSBlog:WeblogPostData ID="WeblogPostData5" Property="Subject" LinkTo="Post" TruncateAt="22" Tag="Li" runat="server" />
  12:          </ItemTemplate>
  13:          <FooterTemplate>
  14:                  </ul>
  15:                  </div>
  16:                  </div>
  17:          </FooterTemplate>
  18:          </CSBlog:WeblogPostList>

Some of these lessons learned here quick worth knowing.

Line 6 - SiteURL control is pretty cool.  It basically constructs a URL from the SiteUrls.config file.  The UrlName attribute must match a name attribute from the Url elements.  This basically derives a URL the include the anchor tag.  The second attribute of interest is ResourceName.  Since I had done no localization in ASP.NET this concept through me.  The long and short of it is the must match a name attribute from the resource element in the resources.xml file.  By the that file can be found in /Languages/en-US.  Obviously if your doing localization an other language may need to be edited.  I needed to add my own resource element since I wanted a different title.  The final element is Tag, what HTML do you want this wrapped in.  Wow, this is a great control and just make so much sense once you take it apart.

Line 11: Straight forward, links to a post, TruncateAt="22" truncates long titles to 22 Characters, way cool idea.  Again The Tag attribute makes bullet lists quick!

In closing, this little exercise was great for me.  It opened my eyes to a lot of the concepts of Chameleon.  The more I work with Chameleon the more impressed I get. And yes this blog post took me way longer to write than the actual work. 

Hope you find this information helpful and it makes your work in Chameleon that much easier.  Please don't hesitate to give feedback or ask a question.

Chameleon Control Documentation

 

Community Server Documentation Chameleon Control Documentation -This documentation was posted today!  Timing is everything life.  I was looking for this last night while start my first theme, and was getting very frustrated!.  

Thanks Telligent please keeps the docs coming.  I do RTFM.

First CS 2007 Theme - First Impressions

I have started working on my first Community Server 2007 theme. So this my first exposure to actually developing with Chameleon.  Here where my steps:

  • download the documentation.
  • Download the updated basic theme.
  • Install the theme with these steps.  Note this article assumes you are copying the default theme.  You will need to use Basic in place of Default as you work your way through.  I tried to use default, but the complexity of it was a big hurdle.  Thus Basic is much easier place to start.

At this point I am still editing the Master.master file, but making progress.  I started by adding my style sheet to run after the CS style sheets so allow my styles to override on conflicts. 

    <CSControl:Head runat="Server" >
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<CSControl:Style ID="Style1" runat="server" Href="~/themes/grumpfish/style/DynamicStyle.aspx" EnsureNotCachedOnPreview="true" />
<CSControl:ThemeStyle runat="server" Href="~/style/layout4_setup.css" media="screen" />
<CSControl:ThemeStyle runat="server" Href="~/style/layout4_text.css" media="screen" />
<CSControl:ThemeStyle runat="server" Href="~/style/screen.css" media="screen" />
<CSControl:ThemeStyle runat="server" Href="~/style/print.css" media="print" />
<asp:ContentPlaceHolder runat="server" id="headerRegion" />
</CSControl:Head>

Then I started adding my page headers.  I kept the original theme headers so I could use them to copy paste from as went.  When I have my headers more or less working I will obviously remove the basic theme headers.  Not much to look at, but is starting to morph into my design.

image

I will try post more as I proceed. 

Telligent - Graffiti

So for a month or two the Telligent folks have been hinting at their new product Graffiti.  This appear to be a venture into the CMS world which would great!  The video was released today.  Worth the watch, not much detail, but the little you do see looks cool.

A CMS and Community Server would be a great combination.  Add to that they cool stuff in Community Server 2008 and social networking and Telligent is some one to watch.  When are you guys going public?

More Posts Next page »