<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3238249693371150356</id><updated>2011-12-29T03:34:43.889-08:00</updated><category term='single sign-on'/><category term='welcome'/><category term='javascript'/><category term='bug'/><category term='rss'/><category term='tutorial'/><category term='custom part'/><category term='store'/><category term='shop'/><category term='raiser&apos;s edge'/><category term='blackbaud'/><category term='api'/><category term='netcommunity'/><category term='upgrade'/><category term='test environment'/><category term='misc'/><title type='text'>Learning Netcommunity</title><subtitle type='html'>A blog about using and customising Blackbaud Netcommunity. Customising Netcommunity, custom parts, the Netcommunity API, and general web development stuff.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-7956267737927762599</id><published>2011-02-14T01:41:00.000-08:00</published><updated>2011-02-14T01:43:58.904-08:00</updated><title type='text'>Bye bye</title><content type='html'>I've got a new job, which no longer involves working with Netcommunity - so I think it's time to stop updating this blog. I leave this job in a few weeks but I will be busy between now and then sorting everything out, so this will probably be the last update.&lt;br /&gt;&lt;br /&gt;I'll leave the blog online, for reference. Hopefully some people will find it helpful.&lt;br /&gt;&lt;br /&gt;Thanks for reading!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-7956267737927762599?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/7956267737927762599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2011/02/bye-bye.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7956267737927762599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7956267737927762599'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2011/02/bye-bye.html' title='Bye bye'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-4999444617916432360</id><published>2011-01-20T07:09:00.000-08:00</published><updated>2011-01-20T07:25:36.985-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Custom Donation Form</title><content type='html'>There is a good example on &lt;a href="http://labs.blackbaud.com/NetCommunity/article?artid=654"&gt;Blackbaud Labs&lt;/a&gt; of a custom donation form for Netcommunity. It's a good example that you can build on and use to create (for example) a shop feature for Netcommunity, or some other kind of custom part that can take payment.&lt;br /&gt;&lt;br /&gt;A while ago I converted the code to C#. It worked really nicely - payment would be taken from a card, and the transaction sent into the Netcommunity plug-in in Raiser's Edge.&lt;br /&gt;&lt;br /&gt;However, I noticed that if an invalid card number was entered and submitted, the 'Thank you for donating' message would still come up, even though the transaction was not processed and the money was not taken. This is the bit of code that deals with it:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;                BBNCExtensions.API.Transactions.Donations.RecordDonationReply oReply = this.API.Transactions.RecordDonation(oArgs);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are a series of catch statements following this that are intended to catch any problems that might arise. None of them seem to catch an invalid card number or anything like that, though. This means that any code in the try statement will be executed, irrespective of whether or not the card has been approved, as no error appears to be thrown.&lt;br /&gt;&lt;br /&gt;One way of checking whether the transaction has been authorised and it's OK to go on is by including this just after &lt;span style="font-style: italic;"&gt;RecordDonation&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;if (oReply.CreditCardAuthorizationResponse.ResultCode.ToString() == "Approved")&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If 'Approved' is returned, you're good to carry on.&lt;br /&gt;&lt;br /&gt;I'm not sure whether this problem is unique to us and our merchant (IATS), but this solution seems to have solved the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-4999444617916432360?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/4999444617916432360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2011/01/custom-donation-form.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4999444617916432360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4999444617916432360'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2011/01/custom-donation-form.html' title='Custom Donation Form'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-7066085006398265020</id><published>2011-01-12T03:18:00.000-08:00</published><updated>2011-01-12T03:22:32.716-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='raiser&apos;s edge'/><category scheme='http://www.blogger.com/atom/ns#' term='blackbaud'/><title type='text'>Raiser's Edge Admin crash on Windows 7</title><content type='html'>Not Netcommunity-related, but it might be of help to anyone who encountered the same problem I did.&lt;br /&gt;&lt;br /&gt;Since upgrading my workstation to Windows 7, Raiser's Edge 7.91 had started crashing every time I tried to open the Admin tab.&lt;br /&gt;&lt;br /&gt;I tried running it in various different compatibility modes, as I assumed that the problem was being caused by Windows 7. What I forgot was that after installing Windows 7, I also installed the beta of Internet Explorer 9.&lt;br /&gt;&lt;br /&gt;I ran a debugger on the Raiser's Edge crash and noticed that MSHTML.DLL was causing the crash - so I uninstalled IE9 and reverted back to IE8. That fixed the problem.&lt;br /&gt;&lt;br /&gt;IE9 is a great browser, but it's not compatible with Netcommunity (particularly the text editor) and it also breaks Raiser's Edge on Windows 7. For now, keep IE9 away from Blackbaud software until they sort this out.&lt;br /&gt;&lt;br /&gt;It's a shame, as it's a great browser, but clearly MSHTML has changed significantly enough to break Raiser's Edge.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-7066085006398265020?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/7066085006398265020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2011/01/raisers-edge-admin-crash-on-windows-7.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7066085006398265020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7066085006398265020'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2011/01/raisers-edge-admin-crash-on-windows-7.html' title='Raiser&apos;s Edge Admin crash on Windows 7'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-8388609882170241389</id><published>2010-12-22T03:35:00.001-08:00</published><updated>2010-12-22T03:35:56.156-08:00</updated><title type='text'>Happy Christmas!</title><content type='html'>Just a quick one to say have a great Christmas and New Year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-8388609882170241389?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/8388609882170241389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/12/happy-christmas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/8388609882170241389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/8388609882170241389'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/12/happy-christmas.html' title='Happy Christmas!'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-8289055119137534613</id><published>2010-11-24T03:28:00.000-08:00</published><updated>2010-11-24T03:39:10.825-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='store'/><category scheme='http://www.blogger.com/atom/ns#' term='shop'/><title type='text'>Blackbaud Netcommunity store / shop</title><content type='html'>I know that some people have the Blackbaud Netcommunity e-store / shop module installed that Blackbaud created themselves. We asked about this a while ago, and were told it's soon going to be a free part of Netcommunity and no longer charged for.&lt;br /&gt;&lt;br /&gt;That was nearly a year ago, with no shop in sight as yet.&lt;br /&gt;&lt;br /&gt;My next tutorial, hopefully in the next few weeks, will go through how to create your own online shop by using the Netcommunity API.&lt;br /&gt;&lt;br /&gt;I've created a shop module of my own that allows you to list items, take payment, and manage stock levels. It also sends all the details through to Raiser's Edge to be processed in the Netcommunity plugin.&lt;br /&gt;&lt;br /&gt;Making your own shop can be as complicated as you want it to be - for the purposes of the tutorial I will focus on creating a simple online shopping basket, with a checkout that takes payment and sends the transaction through to RE. The best thing is, the Netcommunity API does all the tricky bits for you in terms of card processing and transaction processing - the rest of the shop's functionality is entirely up to you to create using ASP.NET.&lt;br /&gt;&lt;a href="http://labs.blackbaud.com"&gt;&lt;br /&gt;Blackbaud Labs&lt;/a&gt; has an example of how to create a custom donation form that can easily be adapted to function as a checkout for a shop. If you take a look at that example it should give you plenty of ideas - it is in VB, however.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-8289055119137534613?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/8289055119137534613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/blackbaud-netcommunity-store-shop.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/8289055119137534613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/8289055119137534613'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/blackbaud-netcommunity-store-shop.html' title='Blackbaud Netcommunity store / shop'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-6276757833086730118</id><published>2010-11-18T03:12:00.000-08:00</published><updated>2010-11-18T03:13:21.420-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><title type='text'>Most wanted custom parts</title><content type='html'>If you could create a custom part that could do anything, what would it be? What is your most wanted feature that BBNC doesn't have?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-6276757833086730118?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/6276757833086730118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/most-wanted-custom-parts.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/6276757833086730118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/6276757833086730118'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/most-wanted-custom-parts.html' title='Most wanted custom parts'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-3653798598193988493</id><published>2010-11-16T07:19:00.000-08:00</published><updated>2010-11-17T06:28:08.547-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='blackbaud'/><title type='text'>Blackbaud Netcommunity says no to IE9</title><content type='html'>&lt;div&gt;Irritatingly, the &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;Netcommunity&lt;/span&gt; built-in text editor doesn't appear to get on with Internet Explorer 9.&lt;br /&gt;&lt;br /&gt;More specifically, every single time you click on anything within the text editor box it throws a Javascript error. Disabling Javascript is no good, as everything is so AJAX-&lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;ified&lt;/span&gt; it won't even let you save changes without &lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;JS&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This appears to be an issue with the text editor (Tiny &lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;MCE&lt;/span&gt;) rather than &lt;span id="SPELLING_ERROR_4" class="blsp-spelling-error"&gt;Netcommunity&lt;/span&gt; itself, but as a customer, that's irrelevant.&lt;br /&gt;&lt;br /&gt;Please fix this &lt;span id="SPELLING_ERROR_5" class="blsp-spelling-error"&gt;Blackbaud&lt;/span&gt;. IE9 will be out of Beta before you know it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The only reason I'm commenting on this is because installing the IE9 beta automatically removes all previous version of Internet Explorer - therefore it's the only IE I have.&lt;br /&gt;&lt;br /&gt;Blackbaud's CTO Shaun Sullivan commented on Twitter that he will look into it - thanks very much.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-3653798598193988493?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/3653798598193988493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/blackbaud-netcommunity-says-no-to-ie9.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3653798598193988493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3653798598193988493'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/blackbaud-netcommunity-says-no-to-ie9.html' title='Blackbaud Netcommunity says no to IE9'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-4017609498195760076</id><published>2010-11-04T02:49:00.000-07:00</published><updated>2010-11-04T03:58:06.046-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Tutorial: Role Redirect</title><content type='html'>This will be a long post. By the end of it you should be able to create a custom part that allows you to redirect members of certain Netcommunity roles automatically when they land on a certain page. &lt;strong&gt;Important: &lt;/strong&gt;remove asterisks before copy &amp;amp; pasting code.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Create a skeleton custom part&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Go back to earlier posts if you're not familiar with how to set up a bare-bones custom part - you'll need an Editor web user control and a Display web user control, along with references to BBNCExtensions in the appropriate places.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Add a new code file&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Right-click on the project name and add a new C# code file. In this new file, create a new class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class rr_data {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public int pid;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public string roles;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This class will be saved in the Netcommunity data store, and will hold the page that you want to redirect users to, and the roles that the redirect applies to. A string is not the best format to hold the roles in, but I don't think the Netcommunity API will allow you to save more complex data types.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Design the Editor part&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Open up the design part of the Editor control. Add this below the first ASP.NET statement at the top:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*%@ Register TagPrefix="bbnc" Namespace="BBNCExtensions.ServerControls" Assembly="BBNCExtensions" %&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This allows you to use some of the Netcommunity server controls that are built-in to the API - in this case, we are going to use the PageLink control to hook into the link selecting functionality in BBNC.&lt;br /&gt;&lt;br /&gt;Somewhere on the page, add this in:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*bbnc:pagelink id="_pid" runat="server"&gt; &lt;*/bbnc:pagelink&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will create a PageLink server control that allows the user to link to a BBNC page, document etc. Very useful. You might get 'unknown' errors but ignore them - this should work on the server.&lt;br /&gt;&lt;br /&gt;Next, drag a CheckBoxList from the toolbox onto the page. Give it an ID of 'role_list'. This element will eventually be populated with all the roles that exist in the BBNC database, so the user can tick which ones they want the redirect to apply to.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Editor code&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Now it's time for the Editor code-behind. Add a using statement at the top to &lt;span style="font-family:courier new;"&gt;System.Data.SqlClient&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;In the OnLoadContent() method, add the following - you should be able to copy &amp;amp; paste it in:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;// Fetch the data (if any):&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;rr_data get_data = base.Content.GetContent(typeof(rr_data)) as rr_data;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;string[] _roles = null;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (get_data!=null)&lt;/span&gt;&lt;br /&gt;// Get the page ID from the BBNC data store&lt;br /&gt;// and use it to pre-select the page in the PageLink control&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;_pid.PageID = get_data.pid;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// The roles are stored as a string, seperated&lt;br /&gt;// by the ^ character - split up the string.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;_roles = get_data.roles.Split('^');&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;try {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Create a new SQL connection to the BBNC database&lt;br /&gt;// You will need your own connection string -&lt;br /&gt;// look in the web.config file in the Netcommunity folder&lt;br /&gt;// on your web server for clues&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SqlConnection sql = new SqlConnection("CONNECTION STRING HERE");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Open the connection&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;sql.Open();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Select the names of roles from the database&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SqlCommand cmd = new SqlCommand("SELECT Name FROM dbo.ClientRoles", sql);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Read the data in&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SqlDataReader data = cmd.ExecuteReader();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Create a new list item collection for the roles&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ListItemCollection item_list = new ListItemCollection();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Add each role to the collection&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;while (data.Read()) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;item_list.Add(data.GetValue(0).ToString());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Close the connections&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;data.Close();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;sql.Close();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// Add the roles to the CheckBoxList&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for (int i = 0; i &lt;* item_list.Count; i++) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;role_list.Items.Add(item_list[i]);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// If there are pre-selected roles in the data store&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;if (get_data.roles.Length &gt; 1)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Loop through each role and check for matches against&lt;br /&gt;// the loaded data&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for (int j = 0; j &lt;* role_list.Items.Count; j++) &lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for (int k = 0; k &lt;* _roles.Length; k++ ) &lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (role_list.Items[j].Text == _roles[k])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;role_list.Items[j].Selected = true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;} catch {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Error checking etc goes here&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;strong&gt;In the OnSaveContent() method, add the following:&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Create new data object for the part&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;rr_data save_data = new rr_data();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Save selected page from PageLink control to object&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;save_data.pid = _pid.PageID&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Loop through the list of available roles&lt;br /&gt;// Stitch selected roles together with the ^ character&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;string selected_roles = "";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for (int i = 0; i &lt;* role_list.Items.Count; i++)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;{&lt;br /&gt;if (role_list.Items[i].Selected)&lt;br /&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;selected_roles += (role_list.Items[i].Text)+"^";&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Save ^ seperated string to object&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;save_data.roles = selected_roles;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-family:georgia;"&gt;// Save the object to the data store&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;base.Content.SaveContent(save_data);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;return true;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;strong&gt;In the Page_Load() method of the Display part code-behind, add the following:&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Load data from the store&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;rr_data get_data = base.Content.GetContent(typeof(rr_data)) as rr_data;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (get_data!=null) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Split roles&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;string[] _roles = get_data.roles.Split('^');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int pid = get_data.pid;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;bool _roles_match = false;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Check for any role match&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for (int i = 0; i &lt;* _roles.Length; i++)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (API.Users.CurrentUser.IsInRole(_roles[i]))&lt;br /&gt;{&lt;br /&gt;_roles_match = true;&lt;br /&gt;}&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// If match found&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (_roles_match)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;// Redirect to specified page&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;string link = API.Navigation.GetPageURL(pid, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Response.Redirect(link);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;get_data = null;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;strong&gt;That's it. &lt;/strong&gt;Bit of a long post - even if the part is useless to you, hopefully there will be some stuff in there that will be useful to you.&lt;br /&gt;&lt;br /&gt;Bear in mind that this is just an example - you should go through it yourself and ensure that all errors are being captured and dealt with properly, especially if you are hooking into the main BBNC database via SQL. It may be worth creating a new SQL user that only has access to the Roles table, for extra security.&lt;br /&gt;&lt;br /&gt;If anyone tries any of the above then please post a comment!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-4017609498195760076?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/4017609498195760076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/tutorial-role-redirect.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4017609498195760076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4017609498195760076'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/tutorial-role-redirect.html' title='Tutorial: Role Redirect'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-2857426014391192676</id><published>2010-11-03T10:17:00.001-07:00</published><updated>2010-11-03T10:25:48.883-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Role Redirect</title><content type='html'>Recently I needed to redirect all users with certain roles as soon as they landed on a specific page - in other words, if a user in X role landed on this page, they would be redirected immedately; everyone else (from all other roles) would see the page normally.&lt;br /&gt;&lt;br /&gt;The targeted content part built-in to Netcommunity allows you to target roles specifically with different content, but it doesn't allow you to perform redirects. So I built a custom part to do the job instead. In this post I'll explain what it does - in the next post, I will upload the code so you can see it all.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Role Redirect&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The first problem was that Netcommunity doesn't appear to expose the list of roles via the API. It allows you to check whether a user is in a particular role (API.Users.CurrentUser.IsInRole), but that's only useful if you already know the name of the role.&lt;br /&gt;&lt;br /&gt;To get around this, my custom part hooks straight into the BBNC database - the Roles table is very simple. When you edit the part, it fetches the list of Roles from the database - you can then select one (or more ) roles that you want to redirect when they land on a page with the part on it.&lt;br /&gt;&lt;br /&gt;You then choose the page you want to redirect them to by using the PageLink server control - I don't think I've posted about server controls before, so I'll explain it in more detail in the next post. They are built-in bits of functionality that Blackbaud kindly provide as part of the API - there's &lt;a href="http://labs.blackbaud.com/NetCommunity/Page.aspx?pid=223&amp;amp;artid=591"&gt;more information on them here&lt;/a&gt;. They allow you to use some of the built-in Netcommunity parts, like the query picker, HTML editor, link picker, and more.&lt;br /&gt;&lt;br /&gt;Once you've picked your page and picked the roles you want to redirect - that's it. You save, and put the part on a page.&lt;br /&gt;&lt;br /&gt;The next post will be quite long as this is a more complicated custom part than I've posted before - it'll be up this week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-2857426014391192676?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/2857426014391192676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/role-redirect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/2857426014391192676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/2857426014391192676'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/11/role-redirect.html' title='Role Redirect'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-2345720672628151543</id><published>2010-09-30T02:52:00.000-07:00</published><updated>2010-09-30T03:04:07.782-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='raiser&apos;s edge'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><title type='text'>Netcommunity upgrade: update</title><content type='html'>I managed to upgrade Netcommunity &amp;amp; Raiser's Edge successfully on our test server. It's not particularly tricky, it just takes a long time. Staying on Windows Server 2003 slightly complicates things, but not much.&lt;br /&gt;&lt;br /&gt;I'd definitely recommend doing it in a test environment first, though, as it did take a little while to go through and sort everything out.&lt;br /&gt;&lt;br /&gt;I've documented everything I did, which I'll upload soon - right now I am busy preparing for the live upgrade, which is happening next week.&lt;br /&gt;&lt;br /&gt;For now, here are some tips for if you're upgrading in a test environment - they should save you a bit of hassle:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Back everything up (obv)&lt;/li&gt;&lt;li&gt;Upgrade Netcommunity before Raiser's Edge&lt;/li&gt;&lt;li&gt;Be prepared to wait for ages whilst BBNC updates&lt;/li&gt;&lt;li&gt;If you're using Windows Server 2003, once BBNC is upgraded, run the AppFx config utility (in the Blackbaud program files folder). Select the Add Users function, and add NT AUTHORITY\NETWORK SERVICE as a database administrator user. Otherwise you will get permissions errors.&lt;/li&gt;&lt;li&gt;Use the testconfig.aspx page - if everything on there has a green light, there shouldn't be much more to do. &lt;a href="http://localhost/netcommunity/testconfig.aspx"&gt;http://localhost/netcommunity/testconfig.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Check the web.config files in BBNC root folder, AppFx\vroot folder, and the various web service / plugin folders in the Blackbaud program files folder if you're getting errors.&lt;/li&gt;&lt;li&gt;When you set up a default site, BBNC requires a URL to a 'valid Netcommunity installation'. Putting in the IP address or hostname of your test server won't work - instead, edit the Windows HOSTS file (Start &gt; Run &gt; "drivers" &gt; etc &gt; hosts) and put the following on a new line:&lt;br /&gt;&lt;br /&gt;127.0.0.1 &lt;a href="http://www.bbnctest.com/"&gt;http://www.bbnctest.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enter &lt;a href="http://www.bbnctest.com/netcommunity/"&gt;http://www.bbnctest.com/netcommunity/&lt;/a&gt; as your valid URL.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-2345720672628151543?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/2345720672628151543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/09/netcommunity-upgrade-update_30.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/2345720672628151543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/2345720672628151543'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/09/netcommunity-upgrade-update_30.html' title='Netcommunity upgrade: update'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-1066332845386159210</id><published>2010-09-15T07:53:00.001-07:00</published><updated>2010-09-15T07:55:22.736-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><title type='text'>Netcommunity upgrade: update</title><content type='html'>I'm currently upgrading Netcommunity &amp;amp; Raiser's Edge on our test server. It's taking absolutely bloody ages.&lt;br /&gt;&lt;br /&gt;I imagine it'll take even longer on our live servers... the site will be down for the entire day at least, I reckon.&lt;br /&gt;&lt;br /&gt;If you're one of those people who is rushing to upgrade to Blackbaud Netcommunity 6.10 / 6.15 before October 31st then I recommend making sure you have at least a whole day set aside just to let the upgrade run, let alone if anything goes wrong!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-1066332845386159210?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/1066332845386159210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/09/netcommunity-upgrade-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/1066332845386159210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/1066332845386159210'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/09/netcommunity-upgrade-update.html' title='Netcommunity upgrade: update'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-4646475847442650130</id><published>2010-09-14T02:16:00.000-07:00</published><updated>2010-09-14T02:30:33.189-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><category scheme='http://www.blogger.com/atom/ns#' term='blackbaud'/><title type='text'>Netcommunity upgrade deadline</title><content type='html'>We got an email at the end of August from Blackbaud telling us that we have until October 31st this year to upgrade to Blackbaud Netcommunity 6.10 (at least), or we will no longer be able to take payment via our website.&lt;br /&gt;&lt;br /&gt;The first issue with this is the ridiculously small amount of notice we've been given - 2 months is not a generous amount of time, for reasons I'll explain in a second. Blackbaud really need to sort out their communication with customers. No call from our account manager, no heads-up email - just a one-off mailshot at the end of August from some bloke I've never heard of. Not acceptable.&lt;br /&gt;&lt;br /&gt;I understand the reasons behind the upgrade - there are some new credit card regulations (PCI DSS) that Blackbaud want to stay on the right side of, and only BBNC 6.10 and above handle transactions in a way that is compliant. It's just the way Blackbaud have gone about it that has narked me off, and it's just another annoyance that makes me wonder whether we'd be better off using open-source tools to build our website. One of the main benefits of BBNC is the supposed integration with Raiser's Edge - whilst it is handy, it still requires an element of human intervention to process transactions, and I'm not convinced whether the convenience of partial integration outweighs all the negatives that BBNC brings along.&lt;br /&gt;&lt;br /&gt;Whilst I've grown to really like using ASP.NET, having never used it before, the nature of BBNC means that it really is quite a pain in the backside to make the kind of changes to how it works that wouldn't be a problem with an open source CMS like (for example) Joomla. With Joomla, any bugs or annoyances get solved by the community, and quickly - Blackbaud have shown themselves to not be particularly speedy when it comes to implementing even the most basic of features that have been requested by the community.&lt;br /&gt;&lt;br /&gt;It would be possible to import transactions from Joomla in a partially-automated fashion, in much the same way BBNC works - without the extensive costs of BBNC and the hassle of development.&lt;br /&gt;&lt;br /&gt;BBNC has lots of great features, but it's lacking in so many of the most simple areas that when things like this happen I start to wonder whether it's worth the hassle for a minimal amount of extra convenience on the database side.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Upgrade&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;At the moment however, I can't think too much about the above, as the impending deadline&lt;br /&gt;means that I just have to get on with upgrading Netcommunity and Raiser's Edge so that we can continue to take online payments. We're currently running BBNC 5.6 and RE 7.85 - we need to be running at least BBNC 6.10 and RE 7.91.&lt;br /&gt;&lt;br /&gt;This means we need to upgrade our Netcommunity SQL Server from 2005 to 2008 (which may possibly break some of the other web applications we have running on that server), upgrade Netcommunity, and then upgrade Raiser's Edge and roll it out to the workstations.&lt;br /&gt;&lt;br /&gt;The scary bit for me is upgrading Netcommunity - a lot of our custom parts were created before I started here, and many of them use parts of the API that they shouldn't. My concern is that upgrading may break some (or all) of these parts, and I'll have to figure out how to fix them.&lt;br /&gt;&lt;br /&gt;For example, our entire site navigation is generated using a custom part that hooks in to parts of BBNC that it shouldn't - the Menu part in Netcommunity was found to be unfit for purpose at the time, so being sneaky was the only viable choice. If the custom menu breaks, I'll either have to fix it or convert the site navigation over to Menu 2.0. A lot of hassle with not a lot of time.&lt;br /&gt;&lt;br /&gt;Anyone else in this position?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-4646475847442650130?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/4646475847442650130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/09/netcommunity-upgrade-deadline.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4646475847442650130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4646475847442650130'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/09/netcommunity-upgrade-deadline.html' title='Netcommunity upgrade deadline'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-3581679004018510455</id><published>2010-08-31T08:09:00.000-07:00</published><updated>2010-10-18T05:18:23.108-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='raiser&apos;s edge'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><title type='text'>Tutorial: Fetching constituent data from Raiser's Edge in Netcommunity</title><content type='html'>Previous posts have illustrated how to make simple, custom forms that allow you to capture data from your users and then use that data for your own purposes.&lt;br /&gt;&lt;br /&gt;Assuming you can identify the user who is filling in your form, however, you can also fetch data on that person from Raiser's Edge and use it in Netcommunity. There's a number of uses for this - the most obvious is that you could pre-fill certain bits of the form (in the same way that the built-in Blackbaud parts often do). This will make life easier for your website visitors, particularly if you've got a lot of forms.&lt;br /&gt;&lt;br /&gt;Once you have a form set up (see previous posts for explanations on how to do this), then first of all you need to check if the current user viewing your form is logged in (and therefore identifiable):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (!API.Users.CurrentUser.IsAnonymous)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Assuming they are not anonymous, you can then use the API to create an object containing any available data held on that user:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BBNCExtensions.API.Transactions.PaymentArgs p = this.API.Transactions.CreatePaymentArgs(true);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The 'true' argument loads the default set of data. To have a peek at what that contains, open up your references in Visual Studio (top right, usually) and double-click on BBNCExtensions and browse to BBNCExtensions.API.Transactions &gt; PaymentArgs.&lt;br /&gt;&lt;br /&gt;So now you have an object you can use in your form - for example, if you have a text box called 'box_name', you can pre-fill it with data assuming that the data exists in Raiser's Edge:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (p.FirstName!=null) box_name.Text = p.FirstName;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Or, if you have a text box called 'box_address':&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;box_address.Text = (p.DonorAddress.StreetAddress + System.Environment.NewLine + p.DonorAddress.City);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The same goes for email address, telephone number, and all sorts of other things. Wahey!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-3581679004018510455?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/3581679004018510455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/08/fetching-constituent-data-from-raisers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3581679004018510455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3581679004018510455'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/08/fetching-constituent-data-from-raisers.html' title='Tutorial: Fetching constituent data from Raiser&apos;s Edge in Netcommunity'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-6243968908639703472</id><published>2010-08-27T04:00:00.000-07:00</published><updated>2010-10-18T05:19:10.429-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='misc'/><title type='text'>Web security</title><content type='html'>If you're reading this then hopefully you will have at least a partial interest in keeping websites and web applications as secure as possible.&lt;br /&gt;&lt;br /&gt;Google created something a while ago that might be useful, or at least interesting: &lt;a href="http://google-gruyere.appspot.com/"&gt;Google Gruyere&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's a website they have developed to be deliberately insecure, and you are encouraged to try and attack and exploit it as much as you can, in order to learn a bit more about the common tricks that can be used against your website if you haven't secured it properly.&lt;br /&gt;&lt;br /&gt;It's good fun. To some extent, a lot of the security holes in Gruyere are unlikely to apply to Blackbaud Netcommunity (or ASP.NET websites in general), as Microsoft have done a pretty decent job at covering your backside if you forget something (unlike PHP), but it's definitely worth looking at for educational purposes. Especially if you have third party code running on your server.&lt;br /&gt;&lt;br /&gt;See how many holes you can find.&lt;br /&gt;&lt;br /&gt;Speaking of PHP, does anyone use it on a day-to-day basis? I've been using it a bit recently, and I've really been missing the convenience of Visual Studio and the general nice-ness of C#. PHP feels very clumsy and awkward to me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-6243968908639703472?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/6243968908639703472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/08/web-security.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/6243968908639703472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/6243968908639703472'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/08/web-security.html' title='Web security'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-740801488617594788</id><published>2010-07-02T07:24:00.000-07:00</published><updated>2010-08-31T08:30:03.196-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><title type='text'>Tutorial: Including Javascript in Blackbaud Netcommunity pages</title><content type='html'>Someone commented on one of the previous blog posts that they wanted to know how to include external Javascript files into a Netcommunity page properly, so I thought I'd write a post about it.&lt;br /&gt;&lt;br /&gt;Depending on the Javascript you want to include, it can be quite easy - just put some script tags in the HTML of a Formatted Text part. For example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*script type="text/javascript"&gt;&lt;br /&gt;function doStuff() {&lt;br /&gt;alert("Do some stuff");&lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*/script&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Don't include the asterisks.&lt;/strong&gt; Or, if you want to load an external JS file:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*script type="text/javascript" src="javascript_file.js"&gt;&lt;*/script&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Bear in mind that, depending on where you place it, your Javascript is likely to be loaded before the page (and the &lt;a href="http://en.wikipedia.org/wiki/Document_Object_Model"&gt;DOM&lt;/a&gt;) has finished loading, so you won't be able to access elements with Javascript that are after the place where you have included the Javascript. In other words, something like this probably wouldn't work (ignore the asterisks):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*script type="text/javascript"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// this will probably throw an error&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;var get_paragraph = document.getElementById("my_paragraph");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;*/script&gt;&lt;br /&gt;&lt;*p id="my_paragraph"&gt;Hello&lt;*/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above probably won't work, because the Javascript is executing immediately and attempting to access an element of the page that may not have been loaded into the DOM yet. I say maybe, because... just try it, and see if it works.&lt;br /&gt;&lt;br /&gt;Assuming you have some Javascript that needs to be loaded in the &lt;*head&gt; of the page - that's a problem, because Netcommunity gives you no access to that. Luckily, you can do it with a custom part.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Adding Javascript (or anything else) to the page HEAD of a Netcommunity page&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In order to be able to do this, you'll need to be able to create and publish a custom part to Netcommunity. If you can't do that, then look at some of the earlier blog posts.&lt;br /&gt;&lt;br /&gt;First you need a skeleton custom part put together in Visual Studio / Visual Web Developer (i.e. An Editor ascx and Display ascx file, with corresponding code-behinds, with links to BBNCExtensions).&lt;br /&gt;&lt;br /&gt;Once you've got that, then add an ASP.NET placeholder to the Display ASCX file. Stick whatever you want to be included in the page head inside that - Javascript files, CSS, or whatever else you might want. Give the placeholder an ID - you'll need it in a second.&lt;br /&gt;&lt;br /&gt;With that done, open up the code-behind for the Display part, and enter something resembling this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// assuming the ID of the placeholder is 'my_place'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.Page.Header.Controls.Add(this.my_place);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you don't want it to happen when the page is in design mode, or if you want something different to be included, just check for design mode as per previous posts:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (this.Content.InDesignMode) { }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Give it a try, it'd be good to know how you get on!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-740801488617594788?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/740801488617594788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/07/including-javascript-in-blackbaud.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/740801488617594788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/740801488617594788'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/07/including-javascript-in-blackbaud.html' title='Tutorial: Including Javascript in Blackbaud Netcommunity pages'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-3499501261414408204</id><published>2010-06-11T06:55:00.000-07:00</published><updated>2010-08-31T08:30:38.285-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Auto-publish custom parts to Blackbaud Netcommunity</title><content type='html'>I always found it to be a bit of a pain to publish custom parts to Netcommunity - build the project, publish it, move the .dll file to the \bin folder and the .ascx files to the Custom folder etc. So I've made a little tool that will hopefully make it a bit easier.&lt;br /&gt;&lt;br /&gt;It's a C# console application - the first time you run it, it asks for the paths to your Netcommunity \bin and \custom folders, and the path to your Visual Studio projects folder. Once you've done that once, it will store them for next time you run it.&lt;br /&gt;&lt;br /&gt;It then asks you for the name of your Project - it searches for that project, and if it finds it the files (including .dll) are copied to the right places in the Netcommunity folder.&lt;br /&gt;&lt;br /&gt;The best thing is that you can set up Visual Studio to run the program automatically every time you build a project - the program recognises that it is being called from Visual Studio, and does everything without asking for confirmation, automating the whole process.&lt;br /&gt;&lt;br /&gt;As long as you run the file once by hand to set up the paths it needs, from then on you can get Visual Studio to run it automatically - here's how:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Adding Build Events to Visual Studio&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;In Visual Studio, go to 'Project' then '[Project Name] Properties'.&lt;br /&gt;Click the Build Events tab.&lt;br /&gt;In the 'Post Build Events' box, type the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cmd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cd C:\BBNC_Pub&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BBNC_Copy_Data $(ProjectName)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The one bit you'll need to change is "C:\BBNC_Pub" - put in whatever directory you've stored the program in.&lt;br /&gt;&lt;br /&gt;The above simply opens a command line, changes to the folder where the copying program lives, and then runs it with the name of your project as an argument. This causes the program to automatically find and copy the project files to the Netcommunity folder.&lt;br /&gt;&lt;br /&gt;Do that for every project you create, and you're good.&lt;br /&gt;&lt;br /&gt;Disclaimer - the program was quickly hacked out, probably has lots of bugs, etc etc. If it wrecks your computer, then that's too bad.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.media-uk.net/BBNC_Copy_Data.exe"&gt;You can download it here&lt;/a&gt; - it's an .exe file. Save it to somewhere like C:\BBNC_Pub\, then run it and enter in the relevant paths. Once you've done that, you can either open the program manually and search for a Project, or get Visual Studio to run it automatically for you.&lt;br /&gt;&lt;br /&gt;Let me know if you try it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-3499501261414408204?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/3499501261414408204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/06/auto-publish-custom-parts-to-blackbaud.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3499501261414408204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3499501261414408204'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/06/auto-publish-custom-parts-to-blackbaud.html' title='Auto-publish custom parts to Blackbaud Netcommunity'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-343320800077352085</id><published>2010-06-04T07:43:00.000-07:00</published><updated>2010-09-10T06:06:19.697-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='test environment'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><title type='text'>Setting up a Blackbaud Netcommunity / Raiser's Edge test environment</title><content type='html'>In steps, how we went about setting up a test environment for Blackbaud Netcommunity &amp;amp; Raiser's Edge, that duplicated (as close as possible) our live setup.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Get the hardware to run it on&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Our live setup is three servers - a Netcommunity application server (holding the application &amp;amp; web services), a Netcommunity database server, and a Raiser's Edge server. We're still running Netcommunity 5.6, so all three of those servers are running Windows Server 2003.&lt;/p&gt;&lt;p&gt;For the test environment, we decided to go down the route of using Virtual Machines - 3 VMs that are running Windows Server 2003, running on the host server which is a powerful Windows Server 2008 R2 server. The VM software we are using (Hyper-V, which is built into Server 2008) is great, you can easily take snapshots of the state of the servers and restore to them later, and make all sorts of changes.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Install the operating systems onto the hardware&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As above, we are currently still on BBNC 5.6, so we're using Windows Server 2003. We're going to use this test environment to upgrade to the latest version soon, and see how it goes - that's the great thing about virtualisation. If it doesn't work out, we just restore the old VMs.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Install Raiser's Edge onto RE server&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Once all the server OSs have been patched up fully, install Raiser's Edge onto the RE VM. This was relatively painless, but took a little while. We did have problems with the installation detecting our existing Raiser's Edge installation (the live one) and confusing itself (the VMs are on the same network as our live setup) - we then had to uninstall it and run the process again. Blackbaud support were helpful with that.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Install Raiser's Edge client onto Netcommunity application server&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This needs to be present in order for the web services to work properly - pretty straightforward to install, we didn't really have any problems.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Install Netcommunity database onto Netcommunity database server&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This was also pretty straightforward - installing the BBNC DB is simply a case of running the BBNC installation file and choosing 'custom' to just install the database.&lt;/p&gt;&lt;p&gt;We did have to do some messing around with the database later on, once the Netcommunity application was installed properly - the recovery mode of the database needs to be set to 'simple' and a backup needs to be performed. Other minor configuration tweaks might be needed, but the best thing to do is either check Blackbaud's knowledge base or give them a ring.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Install the rest of Netcommunity onto the application server&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Next, we installed the rest of Netcommunity onto the application server - the application itself, the web services, etc. Once that was done, I tried to open the Netcommunity admin page. It failed straight away. Eek.&lt;/p&gt;&lt;p&gt;In order to get it to work, we needed to grant permissions to various files &amp;amp; folders to an account named (I think) NETWORK SERVICE or similar. We also had to change the recovery model of the database (as above), and we had a few problems with the Netcommunity installation package not working properly - uninstalling Netcommunity, removing all the temporary files it leaves behind, and trying again seemed to sort that one out.&lt;/p&gt;&lt;p&gt;Once the admin page came up successfully, I loaded the testconfig.aspx page (your-url.net/netcommunity/testconfig.aspx) to see if anything else was awry. During the application installation process it asks you for Blackbaud Services login details - we didn't need to use this, so we just put gibberish in instead. I understand that installing a more recent version of Netcommunity requires you to enter Blackbaud Payment Service info - I guess you may have to put the live info into there for it to work. We also had a few problems with the web.config file that needed to be adjusted, but again, the knowledge base was very helpful with sorting it out.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Restore the live databases to the servers&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The next, and optional step is to backup the live databases for both Raiser's Edge and Netcommunity, and restore them to the databases in the test environment. That way you will have a relatively recent version of your live setup, duplicated onto your test servers.&lt;/p&gt;&lt;p&gt;Bear in mind that things like customisations are not stored in the database and will therefore need to be copied across manually.&lt;/p&gt;&lt;p&gt;Our next step is to trial out the latest version of Netcommunity, and see how we get on - we have a lot of custom parts that could potentially get broken. Hopefully not.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-343320800077352085?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/343320800077352085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/06/setting-up-blackbaud-netcommunity.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/343320800077352085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/343320800077352085'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/06/setting-up-blackbaud-netcommunity.html' title='Setting up a Blackbaud Netcommunity / Raiser&apos;s Edge test environment'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-605087397613508843</id><published>2010-05-25T02:29:00.000-07:00</published><updated>2010-05-25T02:30:40.761-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='test environment'/><title type='text'>Test environment: update</title><content type='html'>We have the test server, at last - now in the process of putting software onto it (including Raiser's Edge and Netcommunity).&lt;br /&gt;&lt;br /&gt;We've got 3 virtual machines running on the server, a Netcommunity VM, a Netcommunity database VM, and a Raiser's Edge VM (this mirrors our live website environment). Pretty impressed with the server so far - it's a quad core with 10gb of RAM and it seems to be pretty damn fast.&lt;br /&gt;&lt;br /&gt;Should come in useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-605087397613508843?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/605087397613508843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/05/test-environment-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/605087397613508843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/605087397613508843'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/05/test-environment-update.html' title='Test environment: update'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-802592630942036778</id><published>2010-04-15T03:46:00.001-07:00</published><updated>2010-04-15T03:50:36.719-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='test environment'/><title type='text'>Netcommunity test environment</title><content type='html'>We haven't got a Netcommunity test environment - I do all development on my workstation PC, and then transfer all the files over to the live server to see if they work. Which is pretty stupid, as I have no idea whether anything works until I publish it to the live server - coding blind, in effect.&lt;br /&gt;&lt;br /&gt;Most of the time it's ok, mainly because I'm not doing anything particularly complicated, but occasionally I really get it wrong and knock out the whole site - like the other day, when I managed to trigger a stack overflow and we had to restart the web server. Oops.&lt;br /&gt;&lt;br /&gt;Thankfully, we are going to be getting a test environment in the near future, which will mean I'll be able to do a lot more without having to worry about wrecking anything. I can't believe we didn't have one anyway.&lt;br /&gt;&lt;br /&gt;Does anyone have a test environment themselves?&lt;br /&gt;&lt;br /&gt;I'm going to document how I get on with setting ours up and so on, on the offchance that anyone is interested / is trying to do it themselves.&lt;br /&gt;&lt;br /&gt;Bonza.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-802592630942036778?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/802592630942036778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/04/netcommunity-test-environment.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/802592630942036778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/802592630942036778'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/04/netcommunity-test-environment.html' title='Netcommunity test environment'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-4830170479155729223</id><published>2010-04-06T06:00:00.000-07:00</published><updated>2010-10-18T05:19:01.094-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='misc'/><title type='text'>Internet Explorer is scary</title><content type='html'>If you're running IE6 or above, &lt;strong&gt;copy and paste&lt;/strong&gt; this into your address bar and press enter (you must copy and paste or it won't work):&lt;br /&gt;&lt;br /&gt;http://www.google.com/%appdata%&lt;br /&gt;&lt;br /&gt;Or even this:&lt;br /&gt;&lt;br /&gt;http://www.google.com/%computername%&lt;br /&gt;&lt;br /&gt;The mind boggles. Apparently this is pretty old stuff but I've only just stumbled across it and couldn't believe it.&lt;br /&gt;&lt;br /&gt;Post a comment if you get why this is quite sloppy from Microsoft.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-4830170479155729223?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/4830170479155729223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/04/internet-explorer-is-scary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4830170479155729223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4830170479155729223'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/04/internet-explorer-is-scary.html' title='Internet Explorer is scary'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-4945191492085698914</id><published>2010-03-30T06:19:00.000-07:00</published><updated>2010-10-18T05:19:17.209-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='misc'/><title type='text'>Blackbus.org hacked!</title><content type='html'>I logged on this morning to check &lt;a href="http://www.blackbus.org/"&gt;Blackbus.org&lt;/a&gt; (a useful site for users of Raiser's Edge / Netcommunity / other Blackbaud products), and discovered that it seems to have been hacked.&lt;br /&gt;&lt;br /&gt;I'm hoping that everyone else who logs on spots the problem - our firewall / anti-virus intercepted the nastiness before it got to us.&lt;br /&gt;&lt;br /&gt;An iframe is being injected into every page on the site, after the closing HTML tag, linking to "ramualdo.com/lib/index.php" (don't go there).&lt;br /&gt;&lt;br /&gt;What does it do? I have no idea, as it's being blocked here at work. I'm going to have a peek when I get home, but I would advise anyone reading this &lt;strong&gt;not&lt;/strong&gt; to go to Blackbus, especially if they are using IE6/7/8 or a version of Chrome or Firefox that isn't up to date.&lt;br /&gt;&lt;br /&gt;There's lots of nasty IE bugs around at the moment that it might be trying to exploit, and countless other exploits with third party software like Adobe Reader / Flash. So I'd stay away for a little while unless you're confident you're not going to get infected.&lt;br /&gt;&lt;br /&gt;Hopefully Blackbus will sort it out soon.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update&lt;/strong&gt;: It's fixed!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-4945191492085698914?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/4945191492085698914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/03/blackbusorg-hacked.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4945191492085698914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/4945191492085698914'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/03/blackbusorg-hacked.html' title='Blackbus.org hacked!'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-1208443213472384306</id><published>2010-03-23T08:31:00.000-07:00</published><updated>2010-10-18T05:19:24.877-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Javascript setTimeout function parameters</title><content type='html'>Not really related to Netcommunity, but this might be useful to anyone struggling with Javascript timers, and more specifically calling a function with arguments from a timer.&lt;br /&gt;&lt;br /&gt;Calling a function from a Javascript timer usually goes something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;timer = setTimeout('myfunction()',10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Call myfunction() after 10 milliseconds. But what if you want to include some arguments in the function call? Surely this would work - x is a string:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;timer = setTimeout('myfunction(x)',10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For some irritating reason it doesn't. So I did some poking around to try and find a solution, and there are some, including using closures - but then I found this solution that seems to work nicely:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;timer = setTimeout('myfunction("' + x + '"),10);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My particular use of this is as follows:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;box = function(id,x,y) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.id = id;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.x = x;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.y = y;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.timer = function() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;timer = setTimeout('animate("'+this.id+'")',10);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.prepare = function() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;moveto(this.id, this.x, this.y);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;boxone = new box("myid",50,50);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;boxone.prepare();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;boxone.timer();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I created a constructor function for a box; I then created a new box and then called the prepare function to put the box somewhere and the timer function to fire off a timer that starts an animation. It was that timer, contained within the constructor, that I was having trouble with - I couldn't pass arguments through to the next function.&lt;br /&gt;&lt;br /&gt;I think that for some reason Javascript can't evaluate function arguments that are being called from a setTimeout in that way - so therefore you have to evaluate them before passing them into the function. That is why breaking up the string and sticking it all together with + works - it's asking Javascript to work out what your argument actually is before calling the function.&lt;br /&gt;&lt;br /&gt;Does that make any sense? Probably not. I felt like writing it down anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-1208443213472384306?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/1208443213472384306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/03/javascript-settimeout-function.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/1208443213472384306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/1208443213472384306'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/03/javascript-settimeout-function.html' title='Javascript setTimeout function parameters'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-7353349928522338775</id><published>2010-03-01T06:31:00.001-08:00</published><updated>2010-10-18T05:19:34.059-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='raiser&apos;s edge'/><title type='text'>Netcommunity to Raiser's Edge</title><content type='html'>I've been half-heartedly attempting to send stuff from Netcommunity to Raiser's Edge today. There's an example on &lt;a href="http://labs.blackbaud.com/"&gt;Blackbaud Labs&lt;/a&gt; that shows you how to update someone's Raiser's Edge record from Netcommunity. That particular example is a form that collects a couple of details from a user, and saves them as a Custom Transaction. The Custom Transaction is then processed by a Raiser's Edge plugin written especially for the task.&lt;br /&gt;&lt;br /&gt;That all sounds a bit tricky and complicated to me, and I assumed (foolishly) that there would be some kind of in-built method in Netcommunity that would allow you to do stuff like that without having to go to all the hassle of writing a plugin. If there is, I can't get it to work though.&lt;br /&gt;&lt;br /&gt;I've been trying to make use of this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BBNCExtensions.API.Transactions.Profiles.ProfileUpdateArgs p = new BBNCExtensions.API.Transactions.Profiles.ProfileUpdateArgs();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It looks pretty good - if you create an object of the type above, it has some methods and properties that look perfect for what I want to do, for example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// get the id of a custom attribute in raiser's edge&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int att_id = p.Data.Attributes.GetAttributeTypeIdFromName("my attribute");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// set the value of the attribute to something&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;p.Data.Attributes.SetValue(att_id, "my value");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// fire it off to raiser's edge... please?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;this.API.Transactions.RecordProfileUpdate(p)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Or not, as it doesn't work. Hmmm. Any ideas?&lt;br /&gt;&lt;br /&gt;I read somewhere on Labs that at the moment Blackbaud only support Donations in this manner, and not Profile Updates or anything like that, but if the methods are there then why not? Or am I just being rubbish and not understanding how this works?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-7353349928522338775?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/7353349928522338775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/03/netcommunity-to-raisers-edge.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7353349928522338775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7353349928522338775'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/03/netcommunity-to-raisers-edge.html' title='Netcommunity to Raiser&apos;s Edge'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-1932337857836478271</id><published>2010-02-18T02:40:00.001-08:00</published><updated>2010-10-18T05:19:48.969-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><title type='text'>Tutorial: Netcommunity design mode, and Javascript</title><content type='html'>Not sure if anyone else has encountered this, but occasionally when I am editing a page and include a custom part, I'm unable to rearrange other parts on that page or add new ones.&lt;br /&gt;&lt;br /&gt;Normally, you can move parts up or down, insert existing parts, or create new parts when you're editing a Netcommunity page. However, quite frequently I'm unable to do this after including a custom part.&lt;br /&gt;&lt;br /&gt;I'm not quite sure why, I have a suspicion it's because a lot of my custom parts are forms that have validators in them (to check form fields have been filled in), and I think the validators might somehow be interfering with how Netcommunity's design mode works (lots of &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;AJAX jiggery pokery&lt;/a&gt;, from the look of it). That's just a guess though.&lt;br /&gt;&lt;br /&gt;Thankfully there's a simple way to get around it - instruct your custom part to check if it's being viewed in Design Mode, and if it is, don't bother displaying your part properly. Pop this into your page_load event in the Display control of your custom part:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (this.Content.InDesignMode)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If that returns true, you can display a simple message or a dummy form, as it's not necessary to do all the legwork as the user is viewing the page from the Netcommunity admin. Remember you don't need to explicitly check if a bool returns as true - merely including a method that returns a bool in the conditional part of an if statement (the brackets) is enough. No need for "if (this.Content.InDesignMode == true)".&lt;br /&gt;&lt;br /&gt;Bear in mind though, that the above isn't always the case - methods that return an int, for example, will cause Visual Studio to squeak at you if you try to evaluate them as a bool.&lt;br /&gt;&lt;br /&gt;That's why Javascript is so lovely - because it does its best to evaluate everything as a bool:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;javascript:if(document){ alert('true'); }else{ alert('false'); }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If the document object is present, the first block is executed. If it isn't the second block is executed. That's why Javascript is so well suited to &lt;a href="http://www.quirksmode.org/js/support.html"&gt;checking if certain features are enabled in any particular browser&lt;/a&gt; - rather than the old practice of browser sniffing.&lt;br /&gt;&lt;br /&gt;Because Javascript is &lt;a href="http://en.wikipedia.org/wiki/Weak_typing"&gt;weakly typed&lt;/a&gt;, you can do the same with an int:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;javascript:if(1){alert('true');}else{alert('this will not be alerted');}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;javascript:if(0){alert('this will not be alerted');}else{alert('false');}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I like Javascript.&lt;br /&gt;&lt;br /&gt;Does anyone else like Javascript?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-1932337857836478271?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/1932337857836478271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/02/netcommunity-design-mode-and-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/1932337857836478271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/1932337857836478271'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/02/netcommunity-design-mode-and-javascript.html' title='Tutorial: Netcommunity design mode, and Javascript'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-2003587819147515000</id><published>2010-02-11T01:43:00.001-08:00</published><updated>2010-10-18T05:20:00.223-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><title type='text'>Tutorial: Custom RSS reader for Netcommunity</title><content type='html'>Hello, it's been a while - sorry about that. Will try and post more regularly.&lt;br /&gt;&lt;br /&gt;One thing I wanted to do recently was display some RSS on our intranet (powered by Netcommunity) - however, as you might know, the built-in RSS reader is a bit rubbish and quite inflexible in terms of displaying content. All I wanted was very simple - fetch the weather from the &lt;a href="http://www.bbc.co.uk/weather"&gt;BBC&lt;/a&gt;, and display the forecast for the next 3 days in brief text format. Netcommunity's RSS reader is way too overcomplicated to accomplish something like that, so I built a very simple custom part to do the job instead.&lt;br /&gt;&lt;br /&gt;I'll post up the full source code later on, but for now here's some snippets.&lt;br /&gt;&lt;br /&gt;Firstly, I created a new Xml document object:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;System.Xml.XmlDocument doc = new System.Xml.XmlDocument();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Load in an RSS feed from wherever you choose:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;doc.Load(&lt;/span&gt;&lt;a href="http://www.myrss.com/rss.xml"&gt;&lt;span style="font-family:courier new;"&gt;http://www.myrss.com/rss.xml&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:courier new;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This bit is quite specific to what I wanted to do - fetch all of the 'item' tags:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;XmlNodeList getitems = doc.GetElementsByTagName("item");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Loop over all the item tags and display them:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for (typical loop stuff) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;displaylabel.Text = displaylabel.Text + getitems.Item(i).FirstChild.InnerText;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Obviously depending on the XML you're dealing with, you'd need to parse it in different ways, but for this particular example (BBC weather 3-day forecast), the above is enough to print out 3 days of weather. You can then go on to customise how the text looks, by splitting the XML strings into chunks and dealing with them that way.&lt;br /&gt;&lt;br /&gt;You can do this in any Netcommunity custom part - so for example, if you have a forum, you could create a custom part that grabs an RSS from the forum (latest posts, for example), and displays it on your homepage. Nifty.&lt;br /&gt;&lt;br /&gt;Will post full sourcecode soon, but it will be very specific to the BBC Weather 3-day forecast - using the above, why not try it yourself? Let me know if you manage to get something working, or if you know of a better / more efficient way of fetching an RSS feed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-2003587819147515000?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/2003587819147515000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/02/custom-rss-reader.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/2003587819147515000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/2003587819147515000'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2010/02/custom-rss-reader.html' title='Tutorial: Custom RSS reader for Netcommunity'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-433662734072975425</id><published>2009-09-18T05:33:00.000-07:00</published><updated>2010-10-18T05:20:09.209-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='single sign-on'/><title type='text'>Netcommunity single sign-on</title><content type='html'>I wittered on last time about Netcommunity's Single sign-on feature, so this post will talk about one way of implementing it, along with some code at the end. To get this to work I looked at the very helpful sample code on &lt;a href="http://labs.blackbaud.com/"&gt;Blackbaud Labs&lt;/a&gt; (alas, in VB.net).&lt;br /&gt;&lt;br /&gt;We have an intranet here that is hosted by Netcommunity, and only logged in users with a certain role (staff) can view it. However, staff were finding it a pain to have to log in to the website to be able to view the intranet. Therefore, after our recent upgrade to a newer version of Netcommunity that supports single sign-on (SSO), I thought I'd try and save them the work.&lt;br /&gt;&lt;br /&gt;In Netcommunity configuration, there's a section where you can set up SSO - you need to specify a 'shared key', a bit of text that only you and Netcommunity know. You'll be using it in your code. The principle behind SSO is that you use this shared key, along with the username of the person you want to log in and a couple of other bits of information, to generate a special URL that signs them in automatically without requiring a password. It's very cunning and very helpful.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How I did it&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The approach I took was this - I hosted an ASP.NET page on a server on our internal network (not exposed to the internet). This page identified the user (by fetching their active directory / windows username), and then matched that username to a BBNC username (held in a database).&lt;br /&gt;&lt;br /&gt;Once it had done that and figured out their BBNC username, the page went through the necessary steps of generating the URL to sign them in. It redirects the user to that URL, and bang - they're signed in. Really easy.&lt;br /&gt;&lt;br /&gt;We set the homepage of staff to the URL of the internal server, which then does all the hard work identifying them and forwarding them on to the URL, all quite quickly, which means they get logged in to the website and can happily browse without ever having to type anything in.&lt;br /&gt;&lt;br /&gt;This doesn't require any reference to BBNCExtensions, however it does require a couple of inclusions in the code-behind (System.Cryptography for example). Have a look through the sample code and give it a try - make sure you go through the code and add in your shared key and a couple of other bits you need to change. It's all commented so it shouldn't be hard to work out.&lt;br /&gt;&lt;br /&gt;As always, if anyone knows of a better way of doing this... let me know about it. I'm still learning.&lt;br /&gt;The link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wii-uk.net/media/sso.zip"&gt;http://www.wii-uk.net/media/sso.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There's just a text file with the c# for the code-behind in there. Let me know via a comment if you have any problems.&lt;br /&gt;&lt;br /&gt;Cheers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-433662734072975425?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/433662734072975425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/09/netcommunity-single-sign-on_18.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/433662734072975425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/433662734072975425'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/09/netcommunity-single-sign-on_18.html' title='Netcommunity single sign-on'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-6112341966510154008</id><published>2009-09-04T03:04:00.000-07:00</published><updated>2010-10-18T05:20:16.040-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='single sign-on'/><title type='text'>Netcommunity single sign-on</title><content type='html'>Been a bit busy lately and as such haven't had much time to work on custom parts. Out of interest, has anyone tried the sample code from the last post, or found anything I've posted remotely helpful in terms of figuring out Netcommunity customisations? Please let me know, it'd be interesting to hear about!&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Single sign-on&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The most recent thing I've been working on relates to Netcommunity - it uses the single sign-on feature that versions of BBNC newer than 5.5 have.&lt;br /&gt;&lt;br /&gt;Single sign-on allows you to automatically sign someone into your Netcommunity website, as long you know their username and a 'secret key' (that you define in the Netcommunity admin). If you have those bits of information, you can generate a special URL that (when entered) signs the user in without requiring a password or any interaction on their part. (it is a bit more complicated than that, but I'll go into it in more detail in another post)&lt;br /&gt;&lt;br /&gt;A good example that illustrates this system is what I've been working on. We have an Extranet where I work, that is hosted by Netcommunity. It's a set of pages that only users within a certain role can see. However, because only logged in users within a certain role can access the Extranet, staff have to log in each time they want to view the pages.&lt;br /&gt;&lt;br /&gt;Therefore I've developed a page that identifies the current user (by fetching their username from Windows), and then queries a database to match their Windows username to their Netcommunity username. Once it's found their Netcommunity username, it builds the special URL required by the single sign-on system and redirects them to it. They get signed in, everyone is happy because they don't have to remember their password.&lt;br /&gt;&lt;br /&gt;I'll post up the code &amp;amp; an explanation of how to do it in a subsequent post. There's actually a good tutorial over at &lt;a href="http://labs.blackbaud.com/"&gt;Blackbaud Labs&lt;/a&gt;, but it's in VB.NET rather than C#. My code is all in C#.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-6112341966510154008?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/6112341966510154008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/09/netcommunity-single-sign-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/6112341966510154008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/6112341966510154008'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/09/netcommunity-single-sign-on.html' title='Netcommunity single sign-on'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-8912780761917562734</id><published>2009-08-14T05:39:00.000-07:00</published><updated>2010-10-18T05:21:04.681-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Project: Custom Form (source code) for Netcommunity</title><content type='html'>You can download the source code for the form I've been describing in the past few posts by following the link at the end of this post. You'll need to make some changes, though - inside the zip are a series of text files. You can put them into Visual Studio and compile them yourself by doing the following:&lt;br /&gt;&lt;br /&gt;Firstly, create a new web application in VS. Then delete 'default.aspx' and the accompanying code-behind file. Then, add 2 new Web User Controls to your project (read previous posts for an explanation of how to do that if you're not sure) - name them 'MyPartEditor' and 'MyPartDisplay' or similar.&lt;br /&gt;&lt;br /&gt;Copy and paste the code from the text files into the relevant visual studio files. For example, 'editor-codebehind.txt' should be pasted into the code-behind of the 'MyPartEditor' control. I haven't included everything in the text files in terms of headers, so you'll have to add a reference to and include BBNCExtensions (see previous posts for an example). Use common sense and refer back to the previous posts if you get stuck - if you still can't do it, leave a comment.&lt;br /&gt;&lt;br /&gt;One file - 'mailvars-codefile.txt' - needs to be placed somewhere special. Add a new item to your project, and select 'C# codefile'. Paste the contents of the text file into that. It's a standalone class declaration that both your editor part and display part can use to create instances of the 'mailvars' object, an object I've created to house certain properties such as the email address the form will use. Read through all the code and hopefully you'll understand how it all links together.&lt;br /&gt;&lt;br /&gt;Once you're happy with how it works, you'll need to go through and change a couple of bits - for example, in the part of the display control that gets and sets a cookie, you'll need to change the name of the cookie to something a bit more meaningful. You'll also need to change the url that visitors are redirected to, as in the text files it points them to 'www.yoursite.org/netcommunity' etc.&lt;br /&gt;&lt;br /&gt;Do all that, and you're ready to build and then deploy the project. Again, there are instructions for that in previous posts.&lt;br /&gt;&lt;br /&gt;If anyone can be bothered to deploy this I'd love to hear about it.&lt;br /&gt;&lt;br /&gt;Oh, and bear in mind that if you're running BBNC 5.1 you might have problems, as some of the calls reference parts of the API that weren't available in that version of Netcommunity. It's easy to get it to work with 5.1, though - find statements that look like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (CurrentUser.IsInRole('Registered users')) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And change them to this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (Netcommunity.CurrentUser.IsInRole('Registered users')) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That should do the trick. (I think, the above is from memory, so if not let me know)&lt;br /&gt;&lt;br /&gt;Oh, and the link. Download the source code here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wii-uk.net/media/display-acsx.zip"&gt;http://www.wii-uk.net/media/display-acsx.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-8912780761917562734?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/8912780761917562734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/08/project-custom-form-source-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/8912780761917562734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/8912780761917562734'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/08/project-custom-form-source-code.html' title='Project: Custom Form (source code) for Netcommunity'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-7251933850783297597</id><published>2009-08-13T06:21:00.001-07:00</published><updated>2010-10-18T05:20:39.242-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Project: Custom Form for Netcommunity</title><content type='html'>Well, I've pretty much finished off the form I was talking about in the last post. The purpose of the form is to ensure that we capture details from people who are interested in downloading our publications. It's been delayed a bit due to other things, but the final functionality is this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It checks to see if the user is logged in - if they are, it redirects them straight to the document (registered users will already have submitted their details once).&lt;/li&gt;&lt;li&gt;If they aren't logged in, it checks for a cookie left behind when the form is submitted. If it finds a cookie, it redirects them to the document (as they must have filled in the form previously).&lt;/li&gt;&lt;li&gt;If it can't find a cookie, it displays a form for them to fill in. Once they submit the form, a thank you message and a link to the relevant document is displayed.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The custom part uses querystring parameters to determine which document the user is trying to download. This means that instead of linking directly to documents on a page, like this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.mywebsite.com/netcommunity/Document.doc?id=560"&gt;www.mywebsite.com/netcommunity/Document.doc?id=560&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We instead route the user to the URL of the page housing the custom part, with some parameters so the part knows where to direct the user:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.mywebsite.com/netcommunity/Page.aspx?id=10&amp;amp;docid=1&amp;amp;doctitle=My%20Doc"&gt;www.mywebsite.com/netcommunity/Page.aspx?id=10&amp;amp;docid=1&amp;amp;doctitle=My%20Doc&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This URL can be changed to point to whatever document is necessary - it extracts the document ID from the querystring (docid=1) and uses it to forward the user to that document once the form has been filled in / they have been identified. The 'doctitle=My Doc' parameter is purely for display - when the form comes up, it says 'Ah, you're trying to download My Doc - you need to fill in this form' (or words to that effect).&lt;/p&gt;&lt;p&gt;However, some content editors without much html experience might have trouble building a URL with parameters like this, so the next step is to create another custom part that will build the URL for them and include it on a page. Bonza.&lt;/p&gt;&lt;p&gt;Source code for the form and other stuff soon.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-7251933850783297597?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/7251933850783297597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/08/project-custom-form.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7251933850783297597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/7251933850783297597'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/08/project-custom-form.html' title='Project: Custom Form for Netcommunity'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-3772672832912920366</id><published>2009-07-23T06:41:00.000-07:00</published><updated>2010-10-18T05:20:54.537-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Project: Custom Form for Netcommunity</title><content type='html'>I've been asked to make a form for our website that will capture the details of the person who filled it in, send their details to us, and then display a link to a downloadable document - the idea being that they only get the download if they allow us to capture their details. Additionally, if a box on the form is ticked, the form needs to email another part of the organisation to instruct them to post out a hard copy of the document.&lt;br /&gt;&lt;br /&gt;This is exactly the kind of thing that would be pretty much impossible to do with Netcommunity out of the box, but it should be pretty straightforward to do with a custom part.&lt;br /&gt;&lt;br /&gt;My plan is to create a standard asp.net form within a custom part, with validation for the form fields. When the form is posted back to the server, the server will double-check all of the values in the form fields, send us the details, and then check to see if the tickbox has been checked. If it has, a request for a hard copy of the document will be sent to us also. The server will then display the link to download the document. All of that will occur in the display part.&lt;br /&gt;&lt;br /&gt;The editor part will allow the Administrator / Content Editor to change some settings, such as the SMTP server name (for the mail), the subject title of the email, the from address, and so on. It would be possible to extend this to allow the editor to customise form fields, but that's not necessary in this case as the form has a very specific purpose. All of these settings will be saved in the BBNC database, and retrieved by the display part and used accordingly when the form is posted back to the server.&lt;br /&gt;&lt;br /&gt;I'm going to try to get the form pre-filled with details from Netcommunity, such as name and so on - however, as we're currently running BBNC 5.1, I don't think the API will allow me to retrieve much more than the username of the person on the page without talking to Raiser's Edge (&lt;a href="http://labs.blackbaud.com/netcommunity/article?artid=591"&gt;the 5.5 API seems to have a few more options with regards to getting user information&lt;/a&gt;). I haven't yet learnt how to talk to Raiser's Edge in a Custom Part (I haven't yet needed to), so I think I might give that one a go and see how I get on.&lt;br /&gt;&lt;br /&gt;I'll post up the source code if I can get it all to work. Either way we're upgrading to BBNC 5.6 in a few weeks.&lt;br /&gt;&lt;br /&gt;This must seem pretty basic and simple to a 'proper' developer but I'm having fun figuring it all out nonetheless.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-3772672832912920366?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/3772672832912920366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/project-custom-form.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3772672832912920366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/3772672832912920366'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/project-custom-form.html' title='Project: Custom Form for Netcommunity'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-733644761037768843</id><published>2009-07-22T05:19:00.000-07:00</published><updated>2010-08-31T08:33:47.264-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='custom part'/><title type='text'>Tutorial: Creating a Netcommunity custom part #1</title><content type='html'>Once you've got Visual Studio (or similar - see below blog post) installed, you can begin creating a custom part. Open VS and create a new ASP.NET Web Application project. If the option to use 'code-behind' is available, make sure that you do.&lt;br /&gt;&lt;br /&gt;You can also select the language you'd like to use to program your application - I use C#, you can use whatever you like. I simply prefer the syntax of C# as it's more similar to 'classic' programming languages like C/C++ and less classic but more familiar scripting languages like Javascript (Javascript is awesome). VB.NET doesn't look right somehow. I like &lt;a href="http://en.wikipedia.org/wiki/Bracket"&gt;curly braces&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you're not familiar with the VS environment, go and &lt;a href="http://www.dotnetspider.com/tutorials/VisualStudio-Tutorials.aspx"&gt;find some tutorials&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Assuming that you know your way around VS, you should see that a Default.aspx page and accompanying code-behind page (Default.aspx.cs) has been created. Delete those - you won't need them.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Add a reference to the BBNC API&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;First thing to do is add a reference to the BBNCExtensions DLL. This lives in the 'bin' folder of your Netcommunity installation. If you're developing on the web server where BBNC lives, then you can reference it directly. If not, copy the DLL from the 'bin' folder to your development environment and reference it from there. (to add a reference, right click on 'References' in the Solution Explorer on the right hand side of VS, and click 'Add new Reference')&lt;br /&gt;&lt;br /&gt;Depending on the version of BBNC you're developing for, you might also need to alter the version of the &lt;a href="http://en.wikipedia.org/wiki/.NET_Framework"&gt;.NET framework&lt;/a&gt; that your custom part uses. For example, Netcommunity 5.1 uses version 2.0 of the .NET framework. By default, recent versions of Visual Studio will reference a more recent version of the framework. This shouldn't present a problem if you're on a more recent version of BBNC, like 5.6, but if not - change the framework for your application by clicking on 'Project' and then '[nameofyourapp] Properties'. Simples.&lt;br /&gt;&lt;br /&gt;(bear in mind that if you do change the .net version to 2.0, you'll need to delete some of the references to newer classes that VS automatically puts in to your application - click the 'References' tab on the right of the VS window and delete any that have a little warning sign next to them. you might also have to remove some of the 'using' statements from the top of your code-behind pages when you create them. if that doesn't make sense &lt;a href="http://msdn.microsoft.com/en-us/library/bb398791.aspx"&gt;read this article from Microsoft&lt;/a&gt; )&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Create some web user controls&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Once all that's been done, click on 'Project' then 'Add new item'. Add a Web User Control and name it 'DisplayTest.ascx'. This user control will be added to your Solution Explorer on the right of the VS window. Double click 'DisplayTest.ascx' and the accompanying code-behind to open them up. If you're not familiar with what you see, there'll be another blog post explaining it all. For now, click on 'design' - it's underneath the main display window in VS when you're looking at DisplayTest.ascx. Type "Hello, this is DisplayTest" or whatever you'd like to say. This is what will (hopefully) appear to users looking at a page containing your custom part.&lt;br /&gt;&lt;br /&gt;Don't worry about the code-behind, for now - the code-behind is where you can do all the clever stuff with C#. For now simply displaying some HTML should suffice. The design mode in VS is essentially a WYSIWYG editor - it'll convert whatever you type into HTML.&lt;br /&gt;&lt;br /&gt;Next, create another Web User Control and name it 'EditorTest.ascx'. Follow the same steps as before, but this time enter different text such as "Hello, this is EditorTest".&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Add some code to the EditorTest code-behind&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Sadly, for the EditorTest section of our custom part, we will need to add some C# to the code-behind. To go over what we've done so far, the DisplayTest control is what the end user will see on a page. The EditorTest control is what a Content Editor or Admin using the BBNC Administration will see when they click 'Edit'. BBNC needs to know what to do when an Editor / Admin clicks 'Save' after editing any part, even a custom part, so you need to fill in some code to tell it what to do.&lt;br /&gt;&lt;br /&gt;Firstly, open up the code-behind for EditorTest. You'll need to add another 'using' statement - add it underneath the others:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;using BBNCExtensions;&lt;br /&gt;using BBNCExtensions.Parts;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This allows you to use the classes defined in the BBNCExtensions DLL that you added a reference to earlier.&lt;/p&gt;&lt;p&gt;You next need to set the main class for your Control to inherit from the CustomPartEditorBase - that sounds horrendous, doesn't it? Look in the code-behind - there'll be a namespace declaration containing the name of your project (ie. namespace MyTestProject) and then underneath there will be a class containing the name of the Control you're working on - it should say something like this:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;public partial class EditorTest : System.UI ETC ETC ETC&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;Change this so that it inherits from something else instead, namely this:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;public partial class EditorTest : BBNCExtensions.Parts.CustomPartEditorBase&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;That colon means 'inherit from'. You need to add a similar bit of code to the code-behind for your Display part also, except that it will instead inherit from 'BBNCExtensions.Parts.CustomPartDisplaybase'. It will also need a 'using' statement. So go and do that.&lt;/p&gt;&lt;p&gt;Once you've done that, go back to the EditorTest code-behind file. You need to add a couple of new methods to override the default behaviour of the page when it loads. This is where the intellisense comes in handy -VS guesses what you're typing and tries to help. Underneath the Page_Load method, add another one that says this (intellisense might try to help you out with it):&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;public override void OnLoadContent() {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It doesn't need to contain anything right now, but for future reference this is the area where you can ask your application to interface with the BBNC database and grab data to present to whoever might be editing the custom part.&lt;/p&gt;&lt;p&gt;You also need to add this, to tell the program what to do when a user clicks 'Save':&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;public override bool OnSaveContent(bool bDialogIsClosing){&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;return true;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Again, we don't need our program to save anything or do anything at the moment, but this method requires a 'boolean' (yes or no) value to be returned anyway. We return true, and therefore the Editor window will close nicely. If you don't include this method, when a user tries to leave the Editor window they will encounter a server error.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Build your project&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Now you need to build your project and check it for errors - click 'Build' and then 'Build [myprojectname]'. The compiler will let you know if there have been any errors that need to be rectified.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Deploy your project&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If you're confident that everything is ok, you next need to deploy the files to the Netcommunity installation. If you're developing on the web server where your Netcommunity installation lives, you can publish directly to the relevant folders. If not (and I'll assume not), you'll need to FTP or RDC them to the right place. The two .ascx files (DisplayTest.ascx and EditorTest.ascx) need to be deployed into the 'custom' folder in your Netcommunity folder. Another file, which will be inside the 'bin' folder of your project and will be called '[myprojectname].dll', needs to be deployed into the 'bin' folder in your Netcommunity folder.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Let Netcommunity know&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Once you've done that, you need to let Netcommunity know that you've deployed a new custom part. Login as an Administrator / Supervisor and click on 'Administration' then 'Custom Parts'. This is the Custom Parts gallery. Click on 'New custom part'.&lt;/p&gt;&lt;p&gt;You'll need to enter a name, and a description, and then you'll need to enter the path to where your custom part files are. The only files BBNC is interested in are the .ascx files - it can find the .dll on its own.&lt;/p&gt;&lt;p&gt;In the 'Display Control Source' box enter the relative path to the DisplayTest.ascx file - it might be something like:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;~\custom\DisplayTest.ascx&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In the 'Editor Control Source' box enter the relative path to the EditorTest.ascx file - it might be something like:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;~\custom\EditorTest.ascx&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;Click on 'Save', and bang. Almost done. Now you need to create an instance of your part using Netcommunity and test that it works. Go to a test page you've created before, and click 'New part' somewhere in your layout where you'll be able to see it. On the list of available parts, you'll now see whatever you decided to call your Custom Part. Select it, and click next. The Editor text you typed in earlier should appear. Click Save, and then preview the page to see if it works.&lt;/p&gt;&lt;p&gt;It should do. So there's a very lengthy but hopefully relatively thorough introduction to how to create a simple custom part. If it looks horrendously complicated, I guess it kind of is, but you soon get into the swing of it.&lt;/p&gt;&lt;p&gt;Any experienced Netcommunity developers feel free to point out any mistakes I've made!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-733644761037768843?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/733644761037768843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/creating-custom-part-1.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/733644761037768843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/733644761037768843'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/creating-custom-part-1.html' title='Tutorial: Creating a Netcommunity custom part #1'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-5277779497513166888</id><published>2009-07-22T03:35:00.000-07:00</published><updated>2010-10-18T05:21:19.485-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><title type='text'>Netcommunity custom parts &amp; helpful links</title><content type='html'>Customising Netcommunity is all based around 'custom parts' - these are custom web controls that you create, that then get integrated into the CMS. For example, you could create a custom part that just prints some text to a page - "Hello World" or whatever. Once you've created the custom part, you push it onto the web server where Netcommunity lives, and then tell Netcommunity where it is. After that, it can be used and reused like any other Netcommunity part - it becomes fully integrated.&lt;br /&gt;&lt;br /&gt;It's up to you to decide the level of complexity of the custom part you've created. If you just want to include some HTML or Javascript into the page (something you can't always do with the formatted text part that comes with Netcommunity), it's very simple to do. However, if you want to make the custom part resemble an application, with settings that can be changed by your content editors / web editors, and with data that gets stored in the Netcommunity database, it's a bit more complicated.&lt;br /&gt;&lt;br /&gt;I'll start with what I first tried - creating a custom part that, when included into a Netcommunity page, printed out a line of text. Sounds simple, eh. First, you'll need a few things if you haven't got them already:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Visual Studio&lt;br /&gt;&lt;/strong&gt;Full version of Visual Studio would be nice, if not, grab this one (it's free):&lt;br /&gt;&lt;a href="http://www.microsoft.com/express/vwd/"&gt;http://www.microsoft.com/express/vwd/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Access to the BBNC server&lt;br /&gt;&lt;/strong&gt;You'll need access to the server that your Netcommunity installation sits on. It'll probably live somewhere like C:\Program Files\Blackbaud\Netcommunity - in there is a folder called 'bin', and another folder named 'custom'. Those two folders are where you place the various files related to your custom part. If you don't have access to these folders (if you're hosted by Blackbaud for example), then you're not going to be able to deploy your custom parts.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Other useful links:&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Blackbaud Labs - &lt;a href="http://labs.blackbaud.com/NetCommunity/Page.aspx?pid=211"&gt;http://labs.blackbaud.com/NetCommunity/Page.aspx?pid=211&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a fairly helpful resource, albeit brief when it comes to helping beginners. There's some downloadable samples of custom parts Blackbaud have made. The first example just prints some text to the page. The last one is far more complicated. All the code examples are in VB.NET.&lt;br /&gt;&lt;br /&gt;Blackbus - &lt;a href="http://www.blackbus.org/forum/netcommunity-bbnc"&gt;http://www.blackbus.org/forum/netcommunity-bbnc&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Forum for users of Blackbaud products, there's a Netcommunity section. Lots of knowledgeable people there, with plenty of questions answered that you might find helpful.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Next&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;I'll explain how to create and deploy a simple custom part.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-5277779497513166888?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/5277779497513166888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/custom-parts-helpful-links.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/5277779497513166888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/5277779497513166888'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/custom-parts-helpful-links.html' title='Netcommunity custom parts &amp; helpful links'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3238249693371150356.post-914738425350827489</id><published>2009-07-22T03:24:00.000-07:00</published><updated>2010-02-18T06:48:05.222-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netcommunity'/><category scheme='http://www.blogger.com/atom/ns#' term='welcome'/><title type='text'>Welcome</title><content type='html'>Hello, welcome - this blog will serve as a manual of sorts for me to keep track of how I'm getting on with using the Blackbaud Netcommunity API. It might be helpful for you if (like me) you're fairly new to ASP.NET and all the associated malarky.&lt;br /&gt;&lt;br /&gt;Blackbaud Netcommunity (BBNC) is a content management system for websites, aimed at non-profit organisations - see &lt;a href="http://www.blackbaud.com/"&gt;http://www.blackbaud.com/&lt;/a&gt; for an overview. Out of the box, it's quite inflexible in terms of what you can achieve, but luckily there's an API that is exposed to developers that allows them to customise the CMS quite heavily. Less luckily, it's not very well documented and fairly alien to anyone that isn't quite familiar with ASP.NET programming and that sort of stuff.&lt;br /&gt;&lt;br /&gt;I haven't let that put me off though, so I've been learning C# and wading through the sparse examples provided by Blackbaud to try and figure out how they work. I've also reverse-engineered some other samples I've found. All of this means that I'm slowly starting to get it. Bonza.&lt;br /&gt;&lt;br /&gt;Since starting to look at all this stuff, I've been able to do a number of things that would previously have been outsourced to web development company at great expense. With relatively little effort, I can now create custom web forms exactly how I would like them, that submit data to a database or fire off emails to receipients; I can customise previously inaccessible sections of the website such as the page head; and I can include custom HTML and Javascript easily and painlessly.&lt;br /&gt;&lt;br /&gt;The most recent customisation I've made is a fully-functioning 'notice board', that allows users to post up notices and advertisements. It interfaces with a simple database, and uses Javascript to allow the user to customise how it looks. I also created a 'widget' for the homepage that grabs the last 10 items and lists them. All of this is fully integrated into the website as if it was a part of Netcommunity itself. However, there's a lot more for me to learn, especially when it comes to using the BBNC database and interfacing with Raiser's Edge, another Blackbaud application (a database).&lt;br /&gt;&lt;br /&gt;Most of the examples you'll find floating around on the web related to BBNC customisation are written in Visual Basic.NET (VB.NET) - I really don't like the syntax of VB, so I've opted to use C# instead. Unfortunately, it appears that I'm pretty much on my own with that decision - however, it's not too difficult to convert VB to C#, especially if you use a number of nifty tools that are out there. One particular tool I've found very handy allows you to disassemble compiled .DLL assemblies - in other words, you can poke through existing customisations and convert them into the source language of your choice, VB or C#. I'll talk about that one in a subsequent post.&lt;br /&gt;&lt;br /&gt;I'll just reiterate that I'm not a programmer, so I imagine I'll frequently use the wrong words, explain things entirely incorrectly, and quite possibly only ever come out with badly-optimised and stupid code. However, there's a small chance it might all be alright, and either way - I'm learning. Hopefully you might find some of it helpful.&lt;br /&gt;&lt;br /&gt;Cheers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3238249693371150356-914738425350827489?l=learningnetcommunity.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://learningnetcommunity.blogspot.com/feeds/914738425350827489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/welcome.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/914738425350827489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3238249693371150356/posts/default/914738425350827489'/><link rel='alternate' type='text/html' href='http://learningnetcommunity.blogspot.com/2009/07/welcome.html' title='Welcome'/><author><name>jayp</name><uri>http://www.blogger.com/profile/03124812090309337937</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
