posts - 374, comments - 606, trackbacks - 112,
Dan Bartels online engineering logbook... Items that I find useful organized for my use, and indexed by google for yours. Here you can find information about Microsoft C# programming, SQL SERVER 2005, Telligent Systems CommunityServer, Dot Net Nuke, Windows Vista / Longhorn, and just about anything else that would compel me to type.

News

What I am Reading:


Professional Community Server

Past books can be viewed on:

Post Categories

Archives

Coding Techniques

Coding Tools

Community Sites

Deal Finders

Friends Businesses

Microsofties

Smartphones

Utilities

my blogmap

CS Membership for the Membershipless

From time to time I find myself pulling down a live Community Server database for testing.  When the database also has a remote membership system it can be very time consuming to try to download and configure both a CS database and a Membership system and keeping those databases in sync.

I have created a SQL script which can create simple membership data for all the membership in a CS database.  You set the application name, and script allows you to specify the name of one user which will be added to the system administrator role.  It will create the asp.net membership tables and entries as necessary, it auto assigns all other users to the everyone role; and sets any user passwords to "password" (obviously this is just for local testing).

This script builds an ASP.NET 2.0 Membership system, for use by CS2007 and CS2008 databases.

Dan


Attachment(s): Generate Local Membership.SQL

Integrating Graffiti Logins with an asp.net datastore (like CommunityServer)

As announced way back at CSDC 07 (http://kevinharder.com/blog/live-blogging-the-csdc-part-3/) graffiti was designed to be able to integrate directly with an existing asp.net membership store...  the key is in the configuration....

So first thing is to get the membership set up...  this requires several changes to your web.config on your graffiti site...

You will need a connection string in the <ConnectionStrings> section pointing to the database which has your asp.net auth tables.. it will look something like this...

<add name="Graffiti_ASPNetMembership" connectionString="server=(local);uid=;pwd=;Trusted_Connection=yes;database=CommunityServer" />

Since I am using an active community, I will go to the CS site and create the default graffiti roles...  (gAdmin, gManager, and gContributor, and add you current admin to the gAdmin role)... Otherwise you need to run the script "Graffiti_ASPNet_Membership_Provider_Data.sql"; this script will try to create a new application so you really only want to run portions of it, ensuring the correct applicationid guid in order to have all logins under a single aspnet forms auth "application".

Next you need to update the "User Provider".

<add key="Graffiti::Users::IGraffitiUserController" value ="Graffiti.Core.ASPNetGraffitiUserController, Graffiti.Core"/>

and finally uncomment the included <membership />, <roleManager /> and <profile /> sections of the web.config; be sure to update the applicationName property of each by default graffiti uses "/graffiti" for the application name, by default cs uses "dev"  if you want to use existing cs users, you will need the application name that exists in your aspnet_Applicaitons table.

Thats it...  you should be able to log into graffiti using your existing cs users...  but wait, theres more...  we can now do shared authentication / single signon with a few more steps...

First, you will need to specify validation and decryption keys for all the applications you want to share logins... this goes in the web.config under <system.web> (edit the guids a bit for security)

<machineKey
validationKey="F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B4
AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B
"
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F"
validation="SHA1"
decryption="AES"
/>

*Note: if you are updating an existing applicaitons machine keys, you should really change the name of the "auth cookie" to prevent existing persisted logins from getting a decryption exception.  This will also force all users to re-login...

As infered by the note above, we have to use the same cookie names for our applications... this is done by editing the <authentication> section of the web.config (I typically just link to the existing communityserver cookie, by changing the graffiti web.config as below)

<authentication mode="Forms">
<
forms name=".CommunityServer" protection="All" timeout="60000" loginUrl="~/login/" slidingExpiration="true"/>
</
authentication>

*Note: you could redirect all users to the cs login page by providing an absolute path to the login url, the page will redirect back to the graffiti site properly; this also has the advantage of leveraging the CS registration forms and process.

and finally we need to use the same cookie name for the <roleManager> by editing the cookieName property...  again I set the property in graffiti equal to the default cs value ".CSRoles" (without this step, your username will show in graffiti, but if you didn't use the graffiti login form, you would not have any more permissions on the site than anonymous, until you re-logged in).

A few items of interest...  at this time it appears that graffiti lowercases all the user names, and uses that for the "ProperName" so CS users without an extended attribute "ProperName" will only see their lowercased user names, a CSModule would be a good way to keep display name in sync with this "ProperName" field.  Of course you will have to use the CS membership system to edit your users; but it appears that graffitis "people" page can only be used to edit users in the local graffiti database anyways (likely the only user you will see in graffiti is admin).

Dan

CS REST in Javascript

CS Rest Endpoints return XML, but JSON is much cooler for working with the data in javascript, you can get the results back in JSON and actually iterate through collections and such...  To convert the data to JSON, in leu of server calls to do this, Thomas Frank has posted a nice JS library to pull this off...

http://www.thomasfrank.se/xml_to_json.html

Dan

Color outside the lines with the CS API

With the release of CS2008, we have released the REST webservice code for the first time...  This webservice has a client API which is used by the server, and actually is in the bin folder of your CS site...  CommunityServer.WebServices.dll.  Referencing this file in a project will allow you to do things like.

Service rest = new Service("http://localhost/cs");
List<BlogGroup> blogGroups = rest.Blogs.GetBlogGroups();

This is all being documented here at http://api.communityserver.org

There are some places however, where the client api might not yet have an implementation for accessing endpoints on the server.  For those cases I wrapped and exposed the communications calls in the dll.  Allowing for calls like.

ManualRequest rest = new ManualRequest("http://localhost/cs");
BlogGroupListSerialized blogGroupListSerialized =
rest.Get(rest.Urls.BlogGroupsUrl()).GetResponseObject<BlogGroupListSerialized>();

The methods return strings, which are XML..  So you can use the GetResponseObject to get the related Type, or just use XPath and open the doc as native XML.

A place where we are missing some client api methods for example are things like post extedned attributes or ratings...

RatingListSerialized ratingListSerialized = rest.Get(rest.Urls.BlogPostRatingUrl(blogId, blogPostId));

or

//rate a post with 4 stars
int responseRating = rest.Put(rest.Urls.BlogPostRatingUrl(blogId, blogPostId, username), "<int>4</int>");

Extended attributes are availabe for "Section" objects, "Post" objects and "User" objects (except for posts in a group / hub)

endpoint urls would be like

/api/blogs.ashx/blogs/{blogid}/attributes returns an ExtendedAttributeListSerialized object which is a list of ExtendedAttributeSerialized objects (Supports GET HEAD and POST)

ExtendedAttributeListSerialized attributeListSerialized = rest.Get("http://localhost/cs/api/blogs.ashx/blogs/10/attributes");

or

/api/blogs.ashx/blogs/{blogid}/attributes/{attribute name} which returns a <string> (Supports GET HEAD PUT and DELETE)

string attribute = rest.Get("http://localhost/cs/api/blogs.ashx/blogs/10/attributes/abouttitle");

Only site admins can access extended attribute urls. You PUT and POST XML encoded strings...  like <string>Hello World</string>

A compiled DLL (DanBartels.CS.REST.Dll) is included as well as the source and some basic unit tests...  Assuming you have your CS install available with the sample data at http://localhost/cs

Dan


Attachment(s): DanBartels.CS.REST_5.0.30430.zip

Online Music - Great Free Service - Pandora.com

I have enjoyed streaming a vast variety of Internet music for some time...  I like the ability to discover new artists and music as well as a nearly infinite selection of styles and artists to suit my mood. 

I have to say of all of the services I have tried, Yahoo music did the best.  They had a decent selection of downloadable music, but even more content they could stream to you, and I made great use of their "Artist Fan Station" Feature...  which let you browse to an artist, and hear similar music, either by that artists or by other artists which were rated highly by people who liked that artist.  They made extensive use of their music and artist rating systems to datamine information, the result was very good;  Their client software, Vista, and then X64 support was terrible...  and left me searching for a new music service..

So I tried URGE, Microsoft's answer... well it worked in X64 and supported plays for sure; even used the same back end data of Yahoo music for the library, but their client was dumb, dumb, dumb...  a few celebrity raido stations, bad "similar artist" selections, no access to music that wasn't downloadable; which cut the artist and song selection way down for me...  and ultimately I couldn't find any music I wanted to listen to that I didn't already own.

Then came Zune...  Well its better, but again their UI is frustrating, you cant really discover anything, unless its new and advertised to you "Clear Channel Style"...  So much for broadening your music tastes, or discovering new artists..  and they seemed to do away with the idea of radio stations all together....  And ratings, well I guess I wast sophisticated enough to rate my own music...  So there were starts, but I don't know where they came from...  The future ui, got worse not better, it got even harder to make your own playlists, apparently if they weren't going to do "stations" then neither should you...  If this wasn't pretty much the only way to manage music on my mp3 player, it would be so uninstalled. (just waiting for the USB Mass Storage Driver for the Zune, so it will show up as a drive letter, no wonder why Microsoft doesn't want one out there)...

Then relief finally came my way...  A really nice radio station only type of service...  Pandora.com...  O and its free...  You set up your own stations based on artists or songs you like, and it streams away; the music index is based off the Music Genome Project a database of music based on musical styles and characteristic (not marketing and advertising departments)...  their client is flash based, and so it runs in your browser...  if you find a new song or artist, you can just bookmark it, and head over to Amazon and pickup the Mp3's ... no drm, no hassle, no subscription, and off you go... 

If you haven't tried Pandora, I strongly recommend you check it out.

Thanks for the tip Wyatt

Dan

Improve Vista Performance

Ran across these couple of tips on the Internet the other day, and thought I would pass them along...

First, my own tip, make sure you have the latest video driver installed...  chances are pretty good that your video card is the lowest  ranked item in your preformance index, its amazing what a new driver can do for the performance and stability of your system (not always a good thing, but in general its a good idea to keep your driver updated).

Second, disk performance...  Vista has advanced output caching support for SATA drives...  if you have a batter backup, or are on a laptop...  Go into device manager, and right click on your disks, select properties, then on the policies tab, mark the "Enable Write Caching" and "Enable Advanced Performance" options.

Lastly, I would recommend disabling the network "auto tuning" feature, its supposed to dynamically adjust the packet size for network performance, but lets face it, our home networks are not what this was targeted at.  Its actually hurting your network performance, by trying to tune it...  Open an administrative command prompt, and type....   "netsh int tcp set global autotuninglevel=normal"

The attached article also talks about how to disable UAP, the popup asking for administrative permission when you do a task that requires it...  I run with UAP enabled, but I realize most people despise it...  There is a nice tool out there...  Tweak UAC to help kill the feature, if you are in need of that, this should help you get it done (http://www.tweak-uac.com/)

Dan

http://vista.blorge.com/2008/02/25/how-to-fix-three-broken-features-of-vista/

ScriptResource.axd Time Sensative

In CS 2008 we have our javascript files linked through the scriptresource.axd handler.  This is very similar to the webresource.axd handler in that it serves content from within a dll.  The gotcha is that the scriptresource handler will throw an exception if the timestamp of the assembly is newer than the current server time...  This is not timezone aware.

The result...  Your in central time, you compile CS, and deploy it to your server in say pacific time, and vola...  you get javascript errors....  why?  well the scriptresource.axd will throw an exception because it thinks the dll is invalid because its timestamp is newer than the server time....  the error magically goes away in two hours, because now the server thinks the dll time is ok...

Its important to note, this is not a CS bug, but rather how the Microsoft script handler scriptresource.axd is coded. 

To work around the issue, set the time on your development workstation to the same time as your server, before you build.

Dan

Windows Vista SP1 RC1 Released

Microsoft has made the current release of Vista RC1 available to early adoptors via Windows Update or as a stand alone download (~850mb).

http://www.microsoft.com/downloads/details.aspx?FamilyID=9de6260e-4275-482d-9524-de850c4dd91c&DisplayLang=en

Dan

You may also note a Office 2007 Sp1 was released today

http://office.microsoft.com/en-us/downloads/default.aspx?ofcresset=1

The Vista SP1 Download is a small Zip file with some documentation and a registry script to make it so you can see the SP in Windows Update

reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\VistaSp1 /f > NUL 2>&1
reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\WindowsUpdate\VistaSP1 /f > NUL 2>&1

reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\VistaSp1 /v Beta1 /t REG_SZ /d c92ef077-adc4-46ef-b96b-02a42d60ede5 /f

Further, you can get the stand-alone installers at

32 bit - http://www.microsoft.com/downloads/details.aspx?FamilyID=be34577a-e925-48fb-9d6d-50fe9461f808&DisplayLang=en

64 bit - http://www.microsoft.com/downloads/details.aspx?FamilyID=c21c3978-3b7d-4d64-873b-3c9d26982d7a&DisplayLang=en

 

 

 

Kevin Harder Live Blogging the CSDC

We are having an awesome time at the Community Server Developers conference, developers from around the country world have converged to hear about the future and direction of Telligent development.

Kevin Harder has been blogging the event for those who can only attend in spirit.  We have been recording all of the presentations; and hopefully our video blogging champion Ado, will have some downloads soon...

Dan

Check out the live blog at

http://kevinharder.com/blog/archive/2007/10/20/live-blogging-the-csdc.aspx

http://kevinharder.com/blog/archive/2007/10/20/live-blogging-the-csdc-part-2.aspx

http://kevinharder.com/blog/archive/2007/10/21/live-blogging-the-csdc-part-3.aspx

Win2008 RC0 install fails x8007045d

The current installer locks access to the disk open, so if you did something, like asked it to "format" your disk prior to installing Windows Server 2008, the format process will silently fail, the copy files will silently fail, and you will get a x8007045d during the expanding files portion of the install. 

You will need to reboot, choose repair instead of install, click next on the choose OS dialog, then command prompt, and manually format your drive (format c:).  You should then be able to continue the installation.

Dan

Amazon Mp3 has arrived (public beta)

As I speculated based on internet rumors nearly a year ago (http://blog.danbartels.com/archive/2006/12/26/good-bye-yahoo-music-hello-zune.aspx)  Amazon has jumped into the online music sales foray...  Now you didn't need to be psychic to guess this, it seems to be a natural fit for the e-tailer.  While the .89 and .99 cent 256 kbit Mp3 tracks are arguably more expensive that Russian site (AllOfMp3.com and their derivatives) its nice to have a DRM free music choice in the popular Mp3 format.

Check out their selection Amazon.com Mp3

I just hope that now that they have built the marketplace, they find ways to play nice with the independent music scene,  I would also love to see a subscription option! 

Dan

Extracting ExtendedAttributes via SQL

In Community Server, several of our classes derive from the ExtendedAttributes class.  This class creates a list of name value pairs on the class, and is picked off by our data layer and stored into two NTEXT columns in the table, PropertyNames, and PropertyValues.  This pattern is derived directly from the way that the ASPNET membership system implements this capability in the ASPNET_PROFILE table.  It allows you to define, and persist custom key value data with an item in the database without need to make schema changes.  Whats good about this, is its easy for a developer to save and retrieve custom pieces of information about the object, whats bad is its stored in an unfriendly way in the database and is very difficult to query against.

SELECT PropertyNames, PropertyValues FROM cs_Sections WHERE ApplicationKey = 'sample'

yieds a result of

PropertyNames
--------------------------------------------------------------------------------------------------------
SectionOwners:S:0:5:CategorizationType:S:5:1:aboutTitle:S:6:12:

PropertyValues
--------------------------------------------------------------------------------------------------------
admin1About Sample

In recently working with this, I wrote a bit of SQL to help extract a value from the PropertyValues column where you know the specific key.  I use this in a SQL script to populate a temp table which I can then join against; In this case I am trying to extract the section owner, which happens to be at the beginning of this property value collection, but doesnt need to be... 

This SQL will extract the Owner Name and the Primary Key which in this case is a column called SectionID

DECLARE @PropertyString NVARCHAR(50)
DECLARE @PropertyDelimiter NVARCHAR(50)

SET @PropertyString = '%SectionOwners:S:%'
SET @PropertyDelimiter = '%:%'

SELECT
SectionID,

SUBSTRING(PropertyValues,

CONVERT(int, SUBSTRING(SUBSTRING(PropertyNames, PATINDEX(@PropertyString, PropertyNames) + LEN(@PropertyString)-2, 100),0,PATINDEX(@PropertyDelimiter, SUBSTRING(PropertyNames, PATINDEX(@PropertyString, PropertyNames) + LEN(@PropertyString)-2, 100))))+1,

CONVERT(int, SUBSTRING(SUBSTRING(SUBSTRING(PropertyNames, PATINDEX(@PropertyString, PropertyNames) + LEN(@PropertyString)-2, 100),PATINDEX(@PropertyDelimiter, SUBSTRING(PropertyNames, PATINDEX(@PropertyString, PropertyNames) + LEN(@PropertyString)-2, 100))+1,100),0, PATINDEX(@PropertyDelimiter, SUBSTRING(SUBSTRING(PropertyNames, PATINDEX(@PropertyString, PropertyNames) + LEN(@PropertyString)-2, 100),PATINDEX(@PropertyDelimiter, SUBSTRING(PropertyNames, PATINDEX(@PropertyString, PropertyNames) + LEN(@PropertyString)-2, 100))+1,100))) -1)

+1

) as Owners from cs_Sections WHERE PATINDEX(@PropertyString, PropertyNames) > 0

This code basically finds all the rows that have the property, the property is defined as [PropertyName]:[DataType]:[Begin]:[Length] or ( SectionOwners:S:0:5 ) so the first big SUBSTRING, is getting the first integer after the PropertyName:Datatype:, and the second is getting the next integer after the first, which is the length... (the only real assumption in the above code, is that the combined digits of the [begin]:[length] cannot exceed 100...  I am grabbing only the first 100 cars after the PropertyString to find the integers in)

While my tests on SQL2005 seem to indicate that this is not a horrible query performance wise, I wouldn't want to constantly be doing this type of string manipulation, So I would only recommend this for reporting, special one off queries, or to use on a relatively infrequent process, like item save, to peel off the custom data and put it in an indexable location.

Show your CS2007 stuff and Win

Telligent is having a little contest to see who can build the best theme for CS...  There are a couple of contests actually, one showcasing our new theme / markup system for full site themes, and another to creatively use the "export" option of our dynamic theme export feature.

The prizes include two MacBooks and Two XBox 360 Elites.

Check out the official page!

http://docs.communityserver.org/wiki/page.aspx/239/community-server-2007-theming-extravaganza/

Dan

Join Us - Community Server team has open positions

Come and join this outstanding team.  We are looking to fill two spots at the moment...  A Community Server Specialist; a developer familiarity with CS, C# and ASP.NET and a Client Side Guru, someone who can help us take our XHTML / CSS / Javascript to the next level.

If you have any questions about working on the team, feel free to contact any of us;  See Scott W's blog post for instructions on how to apply.

http://scottwater.com/blog/archive/cs-jobs/

Dan

Fixing Non-Relative Urls in Posts

One of the challenges with the TinyMCE (as I recall we had this same issue with FreeTextBox) is relative urls..  In CS because we are in a control panel, making posts which can be viewed on various parts of the site, it can be difficult for the site to determine the correct relative URL to use for content; as such there is code in place to convert relative urls to full urls on things like SRC attributes of images.

The problem is that if you move your site, all of this content is hard coded into the body of your posts, further, if you use SSL, users will get security warnings for image which are hard coded to http instead of relative or https.

In CS we can use the "Censorship" feature, to strip the full url from our posts... (note in CS 2.1 this was something tiny like 20 chars, so you have to tweak the code; in CS 2007 the fields has been enlarged to 256 chars)  In the Control Panel, Administration Section, System Tools group, you will find the "Manage / Create Censorships" option.

Then proceed to add tags like src="http://blog.danbartels.com/ as a "Bad Word" and src="/ as the "Replacement Token"

and to the same for href="http://blog.danbartels.com/

This will cause those strings to get stripped and replaced in your posts as you save them, removing the fully qualified site paths and replacing them with relative pathing.

Dan

More Posts Next page »
 
Powered by Community Server (Commercial Edition), by Telligent Systems
powered by god (with a little help from Telligent Systems - Community Server 2.1)