So you want to convert your Modded CSK/GCN to .Net 2.0 - My Notes:

Last post 11-22-2005 6:15 PM by jodywbcb. 9 replies.

Sort Posts:

  • So you want to convert your Modded CSK/GCN to .Net 2.0 - My Notes:

    11-13-2005, 7:15 PM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985

    For those of you whom want to run the CSK / GCN under 2.0 - here are my notes for the conversion I did on my heavily modded version of the app.

    Conversion Notes:


    •  Copy your 1.1 version to a seperate directory for a backup.
    • In VS 2003 (the old version) manually delete ALL files that are excluded from your project.  Trust me you will want to do that!!!!  VS 2005 simply loads everything - and has no idea if it is excluded or not.
    • Load up the purged project in VS 2005
    • Let it do its conversion...
    • You should get about 3 hardcore errors and about 1200 warnings.

    Now you can work on the project - you will want to do the following:



    • Take the web solution and add another c# library project. File - Add new project to existing solution.  Select Library - in the name for it : ASPNET.StarterKit.Communities
    • It will create a new project in the solution that when you view properties will have:
    Assembly Name: ASPNET.StarterKit.Communities
    Namespace: ASPNET.StarterKit.Communities
    • Delete the class.cs that will be in the root of your new project.
    • Delete old AssemblyInfo.cs as new project creates a new one in the \Properties folder.

    when compiles creates: ASPNET.StarterKit.Communities.dll


    • Then move the APP_Code folder from your web project to the new project (cut then paste). Add references. Strong Name the Assembly.
    • Add references to the Project...System.Design, System.Data, etc...  if you view the references tabs most will be easy to know which ones.  Else when you compile you will see the references not actually referenced but called from the (using such and such.. in your code)..Add missing references and recompile..
    • Add a reference to the web project to grab the dll.
    • Compile just the AspNet.. project
    • Fix the three errors (you may have a few more or less)



    Find and Replace any skin that had: (select the web project and select replace only in project).

    <%@ Control %>

    With:

    <%@ Register TagPrefix="community" Assembly="ASPNET.StarterKit.Communities" Namespace="ASPNET.StarterKit.Communities" %>

    The above is so that we can reference the ASPNET.StarterKit.Communities namespace and use the assembly.


    Do a replace all in the web project that has:

    <%@ Register TagPrefix="community" Namespace="ASPNET.StarterKit.Communities" %>

    With

    <%@ Register TagPrefix="community" Assembly="ASPNET.StarterKit.Communities" Namespace="ASPNET.StarterKit.Communities" %>

    Without the assembly info then the @Register will not be able to locate the referenced assembly.



    Skins....

    If you have implemented my Theme Mod - with 2.0 it will for some reason not locate the 'default csk skin' if a templated skin is not found.  This issue is with the SkinnedCommunityControl.cs and probably has to do with the logic for determining the failures of file not found.  Best bet is if a skin is not found - then take the name of the skn not found and simply copy and paste an original (copy of) and rename it to the skin name of the one not found.  I have no immediate fix yet as my only intent with converting the CSK to .Net 2.0 was that I couldn't use Redd's version - simply because my versions are heavily modded and more importantly I am having SEVERE issues running Asp.Net 1.1 apps under x64 version of IIS even in 32 bit compatability mode. With pre-RTM .Net x64 2.0 I had no problems but soon as I upgraded my AMD Opteron Server to RTM bits - nothing works correctly. See my other post for fix for skinnedcommunitycontrol.cs.


    IE:
    -----------------------------------------------------------------------
    Server Error in '/TESTWBCB' Application.
    The file '/TESTWBCB/communities/common/themes/axis/skins/contentskins/parentsection_parentsection-style1.ascx' does not exist.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Web.HttpException: The file '/TESTWBCB/communities/common/themes/axis/skins/contentskins/parentsection_parentsection-style1.ascx' does not exist.

    Source Error:

    Line 325:            {
    Line 326:                
    Line 327:                skin = Page.LoadControl( CommunityGlobals.AppPath + skinKey);
    Line 328:                
    Line 329:            }

    ------------------------END

    This was caused by nested try-catch which .Net 2.0 really will not allow you to do. So if you have mods where you rely on nested try catches or a catch statement that does something more than simply recording the error and exiting the function then you may find yourself running into issues.  Where possible try to determine if you are going to generate an error and handle it in code versus relying on try ..catch..  I may be wrong on that one but after spending 4 days troubleshooting - it was all I could surmise...

    Other issues:

    1. With it successfully compiled and deployed.  I have not found a resolution for the mapped image extenstions. They sometimes work or do not.  If it doesn't then drop the site and re-add it is all I can tell as I have two web site properties now running my converted version of the csk / gcn compiled under 2.0.  If you do not map them then the images from the DB do not appear.  If you do map them - the images from the db appear but not the file system ones.  Somehow I think there is a correlation between the problem with the skinnedcommunity control not being able to traverse directories properly and the images - maybe directory security??  Not so sure....  
    2. Either or both remain unsolved on my end even with the trust set to "Full" as mentioned in above post...  but I have noted it only happens on my x64 server and not my dev server (which is x86)....
    3. Persisted logins do not work any longer....My guess it has to deal with new methods of how .Net 2.0 handles sessions / cookies.
    4. However, .Net 2.0 can now detect crawler announcements (it never did in 1.1)




    Other Notes:

    1. The Mail classes will still work (deprecated... ) however you will always get a warning message to change the code to the new namespaces.
    2. You will get a bunch of errors if you compile the solution but have a problem with the actual library project.  I recommend compiling the library project seperately and disregard the 'can not find control" in "such and such .ascx" page.
    3. You will need to eventually add an ID="something" to every control in every .ascx page for reliability.  
    4. None of the CSK/GCN themes are html compliant.  To make it so does require alot of work.  For example - all html tags need to be lower case (by default the IDE will uppercase most of them).  
    5. All of the controls when render will always be ctl_0_ctl1...something which will result in no html validation by current standards set by w3c. Dan Bartel on his blogs has code that will make those controls compliant....
    6. A bunch of the SQL code is deprecated now so be wary of seeing the list and doing a 'find and replace'.   You will correct about 894 of the entries by in modules such as voting - you will find things break... takes a few moments to correct the issue by hand.
    7. Keep a backup of your web.config.  I have found that the IDE will incorrectly re-write / format it and suddenly nothing will work...



    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
  • Re: So you want to convert your Modded CSK/GCN to .Net 2.0 - My Notes:

    11-16-2005, 10:56 AM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985
    Additionally:

    Whether running the CSK as a 1.1 app under 2.0 or converted to 2.0 you will probably notice that no longer are your sessions being persisted.

    With RTM 2.0 the timeout for cookies is now 30 minutes by default. Someone out there thought that we needed to be reminded of the security hazard of persisting cookies for 'indefinately'. You can change this behavior by editing your web.config

    find:

    <forms ... />

    add:

    <forms ... timeout=[some value in minutes] />

    ie: timeout=50000000 which equates to something like 98 years

    That solves the persisted login (forms.authentification) issue with 2.0....

    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
  • Re: So you want to convert your Modded CSK/GCN to .Net 2.0 - My Notes:

    11-20-2005, 12:40 PM
    • Participant
      868 point Participant
    • BillKrat
    • Member since 08-19-2003, 7:30 PM
    • Amarillo, tx
    • Posts 176

    I was wondering what was going on.... Thank you!  This will help me on not only the CSK but the Project Manager starter kit (which is where I noticed the issue).

    P.S.   I addressed the image issue on the "pinned" post http://forums.asp.net/891513/ShowPost.aspx - within 12 lines of code (three files) you can remove the dependency on IIS for displaying images via the ImageHandler class.  I've made reference to this post from the above mentioned link to ensure others can benefit from your solutions to issues.

  • Re: So you want to convert your Modded CSK/GCN to .Net 2.0 - My Notes:

    11-20-2005, 3:39 PM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985
    I saw your solution thanks for posting. Disregard previous content - saw what you actually accomplished... Note anyone using this can use the remainder of Redd's mod without my fixes as there will not be dual "?" embedded (well from what I can see anyways)...

    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
  • My Notes Continued: Mail / Notify

    11-21-2005, 6:41 PM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985
    Updating Mail sub functions to 2.0


    Horribly under-tested ; however fixes the warnings for System.Web.Mail....


    Code is for Stock GCN / CSK 1.x (No other Mods - so if you have any of the MODs I have written in the past you may need to slightly tweak)....


    please post any corrections to this thread...


    NotifyUtility.cs


    namespace Cavalia {

    using System;
    using System.Data;
    using System.Data.SqlClient;
    //Was System.Web.Mail;
    using System.Net.Mail;
    using Cavalia;


    //*********************************************************************
    //
    // NotifyUtility Class
    //
    // Contains static methods for working with notification
    // emails.
    //
    //*********************************************************************

    public class NotifyUtility {



    //*********************************************************************
    //
    // GetNotificationStatus Method
    //
    // Returns true if the user is receiving notifications for
    // this section or content page.
    //
    //*********************************************************************

    public static bool GetNotificationStatus(int contentPageID, int sectionID, string username) {
    SqlConnection conPortal = new SqlConnection(CommunityGlobals.ConnectionString);
    SqlCommand cmd = new SqlCommand("Community_NotifyGet", conPortal);
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    cmd.Parameters.AddWithValue("@sectionID", sectionID);
    cmd.Parameters.AddWithValue("@username", username);
    cmd.Parameters.AddWithValue("@contentPageID", contentPageID);
    cmd.Parameters.Add("@status", SqlDbType.Bit).Direction = ParameterDirection.Output;

    conPortal.Open();
    cmd.ExecuteNonQuery();
    bool result = (bool)cmd.Parameters["@status"].Value;
    conPortal.Close();

    return result;
    }


    //*********************************************************************
    //
    // UpdateNotificationStatus Method
    //
    // Updates user notification status in the database.
    //
    //*********************************************************************

    public static void UpdateNotificationStatus(int contentPageID, int sectionID, string username, bool status) {
    SqlConnection conPortal = new SqlConnection(CommunityGlobals.ConnectionString);
    SqlCommand cmd = new SqlCommand("Community_NotifyUpdate", conPortal);
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    cmd.Parameters.AddWithValue("@sectionID", sectionID);
    cmd.Parameters.AddWithValue("@username", username);
    cmd.Parameters.AddWithValue("@contentPageID", contentPageID);
    cmd.Parameters.AddWithValue("@status", status);

    conPortal.Open();
    cmd.ExecuteNonQuery();
    conPortal.Close();
    }


    //*********************************************************************
    //
    // SendNotifications Method
    //
    // Sends notification emails to interested users.
    //
    //*********************************************************************

    public static void SendNotifications(int sectionID, int contentPageID, string contentTitle, string username) {
    NotifyFormatInfo formatInfo = new NotifyFormatInfo();
    string mailSubject;
    string mailBody;
    //Removed - no longer required
    //MailMessage mailMessage = null;

    // Get the notification message
    MessageInfo notifyEmail = MessageUtility.GetMessage("Email Notification");

    // Get the Smtp server
    string smtpServer = CommunityGlobals.SmtpServer;

    // Get base url
    string baseUrl = CommunityGlobals.ResolveAbsoluteUrl(CommunityGlobals.AppPath);

    // Set common format info properties
    formatInfo.EditProfileLink = baseUrl + "/Users_EditProfile.aspx";
    formatInfo.SectionName = SectionUtility.GetSectionNameFromID(sectionID);
    formatInfo.ContentLink = CommunityGlobals.ResolveAbsoluteUrl(ContentPageUtility.CalculateContentPath(sectionID, contentPageID));
    formatInfo.ContentTitle = contentTitle;

    // Get the notifications
    SqlConnection conPortal = new SqlConnection(CommunityGlobals.ConnectionString);
    SqlCommand cmdGet = new SqlCommand("Community_NotifySendNotifications", conPortal);
    cmdGet.CommandType = CommandType.StoredProcedure;

    cmdGet.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    cmdGet.Parameters.AddWithValue("@sectionID", sectionID);
    cmdGet.Parameters.AddWithValue("@contentPageID", contentPageID);

    conPortal.Open();
    SqlDataReader dr = cmdGet.ExecuteReader();
    while (dr.Read()) {
    mailSubject = notifyEmail.Title;
    mailBody = notifyEmail.Body;

    formatInfo.Username = (string)dr["user_username"];
    //Mail routine Replacement
    using (MailMessage message = new MailMessage("notify@" + CommunityGlobals.PrimaryDomain, (string)dr["User_Email"], FormatEmail(formatInfo, mailSubject), FormatEmail(formatInfo, mailBody)))
    {
    //This can be expanded to use the users's profile settings
    message.IsBodyHtml = true;
    SmtpClient mailClient = new SmtpClient();
    mailClient.Host = smtpServer;
    mailClient.UseDefaultCredentials = true;
    mailClient.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
    //Send delivers the message to the mail server
    mailClient.Send(message);

    }

    /*
    //Replaced with code above
    mailMessage = new MailMessage();
    mailMessage.From = "notify@" + CommunityGlobals.PrimaryDomain;
    mailMessage.To = (string)dr["User_Email"];
    mailMessage.Subject = FormatEmail(formatInfo, mailSubject);
    mailMessage.Body = FormatEmail(formatInfo, mailBody);

    SmtpMail.SmtpServer = smtpServer;
    SmtpMail.Send(mailMessage); */
    }
    conPortal.Close();
    }



    //*********************************************************************
    //
    // FormatEmail Method
    //
    // Formats notification email.
    //
    //*********************************************************************

    public static string FormatEmail(NotifyFormatInfo formatInfo, string text) {
    // Perform replacements
    text = text.Replace("<Username>", formatInfo.Username);
    text = text.Replace("<EditProfileLink>", formatInfo.EditProfileLink);
    text = text.Replace("<SectionName>", formatInfo.SectionName);
    text = text.Replace("<ContentLink>", formatInfo.ContentLink);
    text = text.Replace("<ContentTitle>", formatInfo.ContentTitle);

    return text;
    }


    //*********************************************************************
    //
    // NotifyUtility Constructor
    //
    // Private constructor in the case of a class with static methods.
    //
    //*********************************************************************

    private NotifyUtility() {}

    }
    }


    -------------------------

    EmailUtility.cs

    namespace Cavalia {

    using System;
    using System.Collections;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Data;
    using System.Data.SqlClient;
    using System.Web;
    //Was System.Web.Mail;
    using System.Net.Mail;


    //*********************************************************************
    //
    // EmailUtility Class
    //
    // Contains static utility methods for sending emails.
    //
    //*********************************************************************

    public class EmailUtility {


    //*********************************************************************
    //
    // GetNewsletterStatus Method
    //
    // Returns the number of newsletters sent and the number of
    // newsletters that still need to be sent.
    //
    //*********************************************************************

    public static SqlDataReader GetNewsletterStatus(int newsletterID) {
    SqlConnection conPortal = new SqlConnection( CommunityGlobals.ConnectionString );
    SqlCommand cmdGet = new SqlCommand( "Community_AdminGetNewsletterStatus", conPortal );
    cmdGet.CommandType = CommandType.StoredProcedure;
    cmdGet.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    cmdGet.Parameters.AddWithValue("@newsletterID", newsletterID);
    conPortal.Open();
    SqlDataReader dr = cmdGet.ExecuteReader();
    return dr;
    }


    //*********************************************************************
    //
    // SendNewsletter Method
    //
    // Sends newsletter to all users who requested a newsletter.
    //
    //*********************************************************************

    public static void SendNewsletter
    (
    int newsletterID,
    string subject,
    string body,
    IsBodyHtml bodyFormat
    ) {
    int status;
    string subjectForUser;
    string bodyForUser;

    // Get the Smtp Server
    string smtpServer = CommunityGlobals.SmtpServer;

    // Format Subject and Body Text
    subject = FormatContentText(subject, bodyFormat);
    body = FormatContentText(body, bodyFormat);

    // Create connection for updating email status
    SqlConnection conStatus = new SqlConnection( CommunityGlobals.ConnectionString );
    conStatus.Open();

    // Get the users to send email
    SqlConnection conNews = new SqlConnection( CommunityGlobals.ConnectionString );
    SqlCommand cmdGet = new SqlCommand( "Community_AdminSendNewsletter", conNews );
    cmdGet.CommandType = CommandType.StoredProcedure;
    cmdGet.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    cmdGet.Parameters.AddWithValue("@newsletterID", newsletterID);


    // Loop through the emails
    conNews.Open();
    SqlDataReader dr = cmdGet.ExecuteReader();
    while (dr.Read()) {
    // Update status
    status = UpdateNewsletterStatus(conStatus, newsletterID, (int)dr["user_id"]);
    if (status == 1)
    throw new Exception( "newsletter already sent!");

    // Copy the newsletter template
    subjectForUser = subject;
    bodyForUser = body;

    // Format Subject for individual user
    subjectForUser = FormatUserText
    (
    subject,
    bodyFormat,
    (string)dr["user_username"],
    (string)dr["user_password"],
    (string)dr["user_firstname"],
    (string)dr["user_lastname"]
    );

    // Format Body for individual user
    bodyForUser = FormatUserText
    (
    body,
    bodyFormat,
    (string)dr["user_username"],
    (string)dr["user_password"],
    (string)dr["user_firstname"],
    (string)dr["user_lastname"]
    );




    // Send the newsletter
    try {
    SendEmail
    (
    String.Format("news@{0}", CommunityGlobals.PrimaryDomain),
    (string)dr["user_email"],
    subjectForUser,
    bodyForUser,
    bodyFormat,
    smtpServer
    );
    } catch (Exception ex) {
    ActivityUtility.RecordError("Error sending newsletter", ex);
    }

    // clear the user copies
    subjectForUser = String.Empty;
    bodyForUser = String.Empty;

    }
    conNews.Close();

    // Close the update status connection
    conStatus.Close();
    }






    //*********************************************************************
    //
    // UpdateNewsletterStatus Method
    //
    // Records the fact that a newsletter has been sent to a user
    // so that the newsletter is not emailed twice.
    //
    //*********************************************************************

    private static int UpdateNewsletterStatus
    (
    SqlConnection connection,
    int newsletterID,
    int userID
    ) {
    SqlCommand cmdUpdateStatus = new SqlCommand( "Community_AdminUpdateNewsletterStatus", connection );
    cmdUpdateStatus.CommandType = CommandType.StoredProcedure;
    cmdUpdateStatus.Parameters.AddWithValue("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
    cmdUpdateStatus.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    cmdUpdateStatus.Parameters.AddWithValue("@newsletterID", newsletterID);
    cmdUpdateStatus.Parameters.AddWithValue("@userID", userID);
    cmdUpdateStatus.ExecuteNonQuery();
    return (int)cmdUpdateStatus.Parameters["@RETURN_VALUE"].Value;

    }




    //*********************************************************************
    //
    // AddEmail Method
    //
    // Adds a new email to the Emails table so it can be sent by the timer.
    //
    //*********************************************************************

    // public static void AddEmail
    // (
    // string from,
    // string to,
    // string subject,
    // string body,
    // IsBodyHtml bodyFormat,
    // string smtpServer
    // ) {
    //
    // SqlCommand cmdAdd = new SqlCommand( "Community_EmailsAddEmail", connection );
    // cmdUpdateStatus.CommandType = CommandType.StoredProcedure;
    // cmdUpdateStatus.Parameters.AddWithValue("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
    // cmdUpdateStatus.Parameters.AddWithValue("@communityID", CommunityGlobals.CommunityID);
    //
    //
    // MailMessage message = new MailMessage();
    // message.From = from;
    // message.To = to;
    // message.Subject = subject;
    // message.Body = body;
    // message.BodyFormat = bodyFormat;
    //
    //
    // SmtpMail.SmtpServer = smtpServer;
    // SmtpMail.Send(message);
    //
    // }
    //



    //*********************************************************************
    //
    // SendEmail Method
    //
    // Sends a single email.
    //
    //*********************************************************************

    public static void SendEmail
    (
    string from,
    string to,
    string subject,
    string body,
    IsBodyHtml bodyFormat,
    string smtpServer
    )
    //this code replaces previous
    {
    using (MailMessage message = new MailMessage(from, to, subject, body))
    {
    message.IsBodyHtml = true;
    SmtpClient mailClient = new SmtpClient();
    mailClient.Host = smtpServer;
    mailClient.UseDefaultCredentials = true;
    mailClient.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
    //Send delivers the message to the mail server
    mailClient.Send(message);

    }
    }


    //*********************************************************************
    //
    // SendFormattedEmail Method
    //
    // Sends a single email with formatting applied to it. For
    // example, <Username> is replaced with a username.
    //
    //*********************************************************************

    public static void SendFormattedEmail
    (
    string from,
    MessageInfo messageInfo,
    ProfileInfo profileInfo,
    string smtpServer
    ) {
    // format the text
    messageInfo.Title = FormatUserText
    (
    messageInfo.Title,
    IsBodyHtml.Text,
    profileInfo.Username,
    profileInfo.Password,
    profileInfo.FirstName,
    profileInfo.LastName
    );

    messageInfo.Body = FormatUserText
    (
    messageInfo.Body,
    IsBodyHtml.Text,
    profileInfo.Username,
    profileInfo.Password,
    profileInfo.FirstName,
    profileInfo.LastName

    );

    messageInfo.Body = FormatContentText(messageInfo.Body, IsBodyHtml.Text);

    // Send the email
    SendEmail
    (
    from,
    profileInfo.Email,
    messageInfo.Title,
    messageInfo.Body,
    IsBodyHtml.Text,
    smtpServer
    );


    }


    //*********************************************************************
    //
    // FormatEmailText Method
    //
    // Formats email text without sending the email.
    //
    //*********************************************************************

    public static string FormatEmailText
    (
    string text,
    IsBodyHtml bodyFormat,
    ProfileInfo profileInfo
    ) {
    // Format Content Text
    text = FormatContentText(text, bodyFormat);

    // Get and apply user specific formatting
    text = FormatUserText
    (
    text,
    bodyFormat,
    profileInfo.Username,
    profileInfo.Password,
    profileInfo.FirstName,
    profileInfo.LastName
    );

    return text;
    }


    //*********************************************************************
    //
    // FormatUserText Method
    //
    // Formats text with user specific information.
    //
    //*********************************************************************

    public static string FormatUserText
    (
    string text,
    IsBodyHtml bodyFormat,
    string username,
    string password,
    string firstName,
    string lastName
    ) {
    string matchString;

    // Get base url
    string baseUrl = CommunityGlobals.ResolveAbsoluteUrl(CommunityGlobals.AppPath);

    // Replace username
    matchString = Regex.Escape("<Username>");
    text = Regex.Replace(text, matchString, username);

    // Replace password
    matchString = Regex.Escape("<Password>");
    text = Regex.Replace(text, matchString, password);

    // Replace first name
    matchString = Regex.Escape("<FirstName>");
    text = Regex.Replace(text, matchString, firstName);

    // Replace last name
    matchString = Regex.Escape("<LastName>");
    text = Regex.Replace(text, matchString, lastName);

    // Replace full name
    matchString = Regex.Escape("<FullName>");
    text = Regex.Replace(text, matchString, firstName + " " + lastName);

    // Replace Edit Profile Link
    matchString = Regex.Escape("<EditProfileLink>");
    if (bodyFormat == IsBodyHtml.Html)
    text = Regex.Replace(text, matchString, String.Format("<a href=\"{0}\">{0}</a>", baseUrl + "/Users_EditProfile.aspx"));
    else
    text = Regex.Replace(text, matchString, baseUrl + "/Users_EditProfile.aspx");

    // Replace Home Link
    matchString = Regex.Escape("<HomeLink>");
    if (bodyFormat == IsBodyHtml.Html)
    text = Regex.Replace(text, matchString, String.Format("<a href=\"{0}\">{0}</a>", baseUrl + "/Default.aspx"));
    else
    text = Regex.Replace(text, matchString, baseUrl + "/Default.aspx");

    return text;
    }



    //*********************************************************************
    //
    // FormatContentText Method
    //
    // Formats email text with content specific information.
    //
    //*********************************************************************

    public static string FormatContentText(string text, IsBodyHtml bodyFormat) {
    string matchText;

    // Replace new articles
    matchText = Regex.Escape("<NewArticles>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Article"), bodyFormat));

    // Replace new events
    matchText = Regex.Escape("<NewEvents>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Event"), bodyFormat));

    // Replace new books
    matchText = Regex.Escape("<NewBooks>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Book"), bodyFormat));

    // Replace new links
    matchText = Regex.Escape("<NewLinks>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Link"), bodyFormat));

    // Replace new downloads
    matchText = Regex.Escape("<NewDownloads>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Download"), bodyFormat));

    // Replace new photos
    matchText = Regex.Escape("<NewPhotos>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Photo"), bodyFormat));

    // Replace new discuss
    matchText = Regex.Escape("<NewDiscuss>");
    if (Regex.IsMatch(text, matchText))
    text = Regex.Replace(text, matchText, FormatContentCollection(ContentPageUtility.GetNewContent("Post"), bodyFormat));

    return text;
    }


    //*********************************************************************
    //
    // FormatContentCollection Method
    //
    // Formats a collection of content items (events, articles, etc)
    // and returns the formatted string.
    //
    //*********************************************************************

    public static string FormatContentCollection(ArrayList colContent, IsBodyHtml bodyFormat) {
    string contentLink;
    StringBuilder builder = new StringBuilder();

    foreach (ContentInfo _contentInfo in colContent) {
    contentLink = ContentPageUtility.CalculateFullContentPath(_contentInfo.SectionID, _contentInfo.ContentPageID);

    if (bodyFormat == IsBodyHtml.Html) {
    builder.Append("<li>");
    builder.AppendFormat("<a href=\"{0}\">{1}</a>", contentLink, _contentInfo.Title);
    builder.Append("<br>");
    builder.Append(CommunityGlobals.FormatPlainText(_contentInfo.BriefDescription));
    builder.Append("<p>");
    } else {
    builder.AppendFormat("\n{0}", _contentInfo.Title);
    builder.AppendFormat("\n {0}", _contentInfo.BriefDescription);
    builder.AppendFormat("\n\n {0}", contentLink);
    builder.Append("\n ");

    }
    }

    return builder.ToString();
    }


    //*********************************************************************
    //
    // EmailUtility Constructor
    //
    // Use a private constructor for a class with static methods.
    //
    //*********************************************************************

    private EmailUtility() {}
    }
    }


    ------------------

    Additionally, you need to declare an enum for IsBodyHtml. I created a new class in my conversion and placed all of my enums in it... You could place it directly in the class files listed above..


    Example of my enum class

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Cavalia
    {
    public enum AllowHtml //SMR- CSK integration
    {
    None = 0,
    Limited = 1,
    Full = 2
    }
    public enum RoleType
    {
    ViewRole = 0,
    AddRole = 1,
    EditRole = 2,
    DeleteRole = 3,
    CommentRole = 4,
    RateRole = 5,
    ModerateRole = 6

    }
    //These Roles are used to determine whom may manipulate sections
    public enum AdminRoleType
    {
    MayAddSection = 0,
    MayEditSection = 1,
    MayDeleteSection = 2,
    IsSectionOwner = 3

    }
    //*********************************************************************
    //
    // CommunityImageType Enumeration
    //
    // Represents the image type for a community image.
    //
    //*********************************************************************

    public enum CommunityImageType
    {
    Global = 0,
    Logo = 1,
    Topic = 2
    }
    public enum IsBodyHtml
    {
    Html = 0,
    Text = 1
    }
    }


    -------------------------------------

    Again not throughly tested as I was simply trying to get rid of warnings and I intend on re-writing both classes with Project Cavalia... However, figured I would share...
    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
  • My Notes Continued: upgrading from deprecated ConfigurationSettings.GetConfig

    11-21-2005, 7:14 PM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985
    To upgrade the ConfigurationSettings.GetConfig deprecation it is safe to do a:

    Replace in Files:

    Find: ConfigurationSettings.GetConfig
    Replace with: ConfigurationManager.GetSection

    Therer should be about 11 occurences with the stock CSK / GCN

    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
  • Yes [Yes] Re: My Notes Continued: Mail / Notify

    11-21-2005, 7:59 PM
    • Participant
      868 point Participant
    • BillKrat
    • Member since 08-19-2003, 7:30 PM
    • Amarillo, tx
    • Posts 176
    [Jody] Horribly under-tested ; however fixes the warnings for System.Web.Mail

    Hey, I'll take it :)   Your one step ahead of me and I'm loving it!   Thanks for sharing!
     


  • Re: My Notes Continued: Mail / Notify

    11-22-2005, 4:03 AM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985
    [Bill]Thanks..

    Next issues... after doing the conversion the two major obstacles truly lie within the ISPadmin and Admin portions of the CSK/GCN.


    Both use code-behind which converts to CodeFile. However, in my journey - I really do not like the codefile method. As I am creating assemblies during my conversion so that I can eventually have DAL layers (I would like to be able to run with Oracle myself as an option - mainly because I do benchmarking and I like having more options to compare to)...

    The main issue with codefiles is they get compiled as individual assemblies during runtime. For some uses that is ok - but where you have something like the CSK where integration into features such as Section, Services etc... You'll note that most of what is contained in the AdminUtility classes should be contained in the core. My reason for stating that is that - during my customizations - I want the ability to embed admin features in the content pages themself so that I do not have to click thirty million times to change the section title of a csk site that has 1000+ sections.


    I have the ISPAdmin now as a an actual assembly.

    I have the Admin tool as an assembly.

    However, herein lies a problem. The conversion process breaks the TabStrip and ListPicker functions which rely on JScript primarily for functionality. Specifically this impacts the AddSection / EditSection.


    Tabstrip control simply renders every tab on the page. My theory is that the clientscript functions are deprecated and in deprecated mode they simply do not work as they did in .Net 1.1. The ListPicker mode however did still work.


    So - I invested time with replacing the TabStrip with 2.0's MultiView and Menu control. Since the ListPicker was still working figured I could at least get the tabbing correct.


    MultiView is a new control with 2.0 that kinda replaces Panels. However it is important to note that for HTML formating - the MultiView supports ONLY .Net 2.0's Themes and Skins but not CSS. So you can not wrap <DIV> <Style> within a MultiView for formatting directly. Instead you have to embed something like Panel that does. Kinda defeats the purpose but I digress.

    So a MultiView Control consists of Views. A MultiView is basically a collection of views. Views can be loosely thought of as panels. Only one of the views in a multiview control ever has 'focus' (or displayed).

    The drawback to MultiView is that there is no Menu control. Not totally true... you can embed into the <asp:view> </view> a Button, HtmlButtons .. but in order to display a menu visible you have to repeat those buttons in each <asp:view></view> ..which results in a heck of alot of extra code...this was obviously not one of the best thought out controls MSFT dumped into 2.0.

    There is a work around however, in that you can create a <asp:Menu> control that in code / script can loop through all of the <asp:view> items and generate an actual menu! Wait too much excitement....


    The <asp:Menu> control has a SEVERE issue. It requires that the Page.Header (otherwise known as <Head> must not be empty if you want to have a menu that has any kind of formatting. Which means this:

    <html runat="server"> must exist in the AdminHeader.ascx.

    This poses a problem.

    By doing so - prevents you from running any kind of javascript - such as that which does the help feature... which also breaks the ListPicker.... since it relies on generating javascript for client side.

    Sigh...


    I have no solution for either.


    Has anyone actually tried solving (or even experiences) the issue I have? I could paste code - but its a ton so I am hoping I described well enough. I will post the Multiview code... this is for the aspx and .cs (may need to be modifed if using codefile (easy enough just ad the codefile to the line with inherits..)

    the aspx editsections.aspx
    ____________________________________

    <%@ Register TagPrefix="community" TagName="SectionWebBoxes" Src="SectionWebBoxes.ascx" %>
    <%@ Register TagPrefix="community" TagName="SectionAdvanced" Src="SectionAdvanced.ascx" %>
    <%@ Register TagPrefix="user" TagName="AdminHeader" Src="~/Admin/Controls/AdminHeader.ascx" %>
    <%@ Register TagPrefix="community" TagName="SectionGeneral" Src="SectionGeneral.ascx" %>
    <%@ Register TagPrefix="community" TagName="SectionWebServices" Src="SectionWebServices.ascx" %>
    <%@ Register TagPrefix="community" TagName="SectionAppearance" Src="SectionAppearance.ascx" %>
    <%@ Register TagPrefix="community" TagName="SectionSecurity" Src="SectionSecurity.ascx" %>
    <%@ Register TagPrefix="community" Assembly="Core Application" Namespace="Cavalia" %>
    <%@ import Namespace="Cavalia" %>
    <%@ Register TagPrefix="admin" Assembly="Cavalia.Admin" Namespace="Cavalia.Admin" %>
    <%@ Page Language="c#" Inherits="Cavalia.Admin.EditSections.EditSection" %>
    <user:AdminHeader Title="Edit Section" runat="server" id="AdminHeader1" />
    <h3>Edit Section</h3>
    <div class="pageDescription" style="WIDTH:500px">
    Use this page to modify the sections in your community. Click one of the tabs
    to modify a particular type of property.
    </div>
    <form enctype="multipart/form-data" runat="server">
    <community:DisplayQuota id="valQuota" text="Over community quota, please delete existing images before you continue."
    runat="Server" />
    <br>
    <asp:Menu id="Menu1" width="468px" runat="server" orientation="Horizontal" StaticEnableDefaultPopOutImage="False" OnMenuItemClick="Menu1_MenuItemClick" BackColor="#F7F6F3" DynamicHorizontalOffset="2" Font-Names="Verdana" Font-Size="0.8em" ForeColor="#7C6F57" StaticSubMenuIndent="10px">
    <StaticMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px"></StaticMenuItemStyle>

    <DynamicHoverStyle BackColor="#7C6F57" ForeColor="White"></DynamicHoverStyle>

    <DynamicMenuStyle BackColor="#F7F6F3"></DynamicMenuStyle>

    <StaticSelectedStyle BackColor="#5D7B9D"></StaticSelectedStyle>

    <DynamicSelectedStyle BackColor="#5D7B9D"></DynamicSelectedStyle>

    <DynamicMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px"></DynamicMenuItemStyle>

    <StaticHoverStyle BackColor="#7C6F57" ForeColor="White"></StaticHoverStyle>
    </asp:Menu>

    <asp:multiview id="MainMenu" runat="server" ActiveViewIndex=0 EnableTheming="False" >
    <asp:view id="General" runat="server" >
    <community:SectionGeneral id="ctlGeneral" runat="Server" />
    </asp:view>
    <asp:view id="Appearance" runat="server" >
    <community:SectionAppearance id="ctlAppearance" runat="Server"/>
    </asp:view>
    <asp:view id="Webboxes" runat="server" >
    <community:SectionWebBoxes id="ctlWebBoxes" runat="Server" />
    </asp:view>
    <asp:view id="Security" runat="server" >
    <community:SectionSecurity id="ctlSecurity" runat="Server" />
    </asp:view>
    <asp:view id="WebServices" runat="server">
    <community:SectionWebServices id="ctlWebServices" runat="Server" />
    </asp:view>
    <asp:view id="Advanced" runat="server" >
    <community:SectionAdvanced id="ctlAdvanced" runat="Server" />
    </asp:view>
    </asp:multiview>
    <p>

    <asp:Button text="Apply Changes" runat="server" id="Button1" onclick="UpdateSection" />
    </p>
    <asp:ValidationSummary ShowSummary="True" runat="server" id="ValidationSummary1" />
    </form>
    <table cellpadding="3" cellspacing="0" border="0" class="body">
    <tr>
    <td><a href="Default.aspx">Return to Edit Sections</a></td>
    <td>|</td>
    <td><a href="../Default.aspx">Return to Admin</a></td>
    <td>|</td>
    <td><a href="../../Default.aspx">Return to Site</a></td>
    </tr>
    </table>

    ------

    the code (or codefile:editsection.aspx.cs))

    _______


    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;

    namespace Cavalia.Admin.EditSections
    {
    /// <summary>
    /// Summary description for EditSection.
    /// </summary>
    public class EditSection : System.Web.UI.Page
    {
    protected Cavalia.DisplayQuota valQuota;
    protected System.Web.UI.WebControls.Menu Menu1;
    protected System.Web.UI.WebControls.MultiView MainMenu;
    protected System.Web.UI.WebControls.View General;
    //protected System.Web.UI.WebControls.Panel pnlGeneral;
    protected System.Web.UI.WebControls.View Appearance;
    //protected System.Web.UI.WebControls.Panel pnlAppearance;
    protected System.Web.UI.WebControls.View Webboxes;
    // protected System.Web.UI.WebControls.Panel pnlWebboxes;
    protected System.Web.UI.WebControls.View Security;
    //protected System.Web.UI.WebControls.Panel pnlSecurity;
    protected System.Web.UI.WebControls.View WebServices;
    // protected System.Web.UI.WebControls.Panel pnlWebServices;
    protected System.Web.UI.WebControls.View Advanced;
    // protected System.Web.UI.WebControls.Panel pnlAdvanced;
    protected System.Web.UI.WebControls.Button Button1;
    protected System.Web.UI.WebControls.ValidationSummary ValidationSummary1;


    protected SectionGeneral ctlGeneral;
    protected SectionAppearance ctlAppearance;
    protected SectionWebBoxes ctlWebBoxes;
    protected SectionWebServices ctlWebServices;
    protected SectionSecurity ctlSecurity;
    protected SectionAdvanced ctlAdvanced;





    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
    //
    // CODEGEN: This call is required by the ASP.NET Web Form Designer.
    //
    InitializeComponent();
    base.OnInit(e);
    }

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {

    }
    #endregion


    public int SectionID {
    get { return (int)ViewState[ "SectionID" ]; }
    set { ViewState[ "SectionID" ] = value; }
    }


    protected void Page_Load(object sender, System.EventArgs e) {
    // Hide quota stats if not over quota
    if (valQuota.IsValid)
    valQuota.Visible = false;

    if (!IsPostBack) {
    // Assign section ID
    SectionID = Int32.Parse( Request.QueryString["id"] );

    // Get the Section information
    SectionInfo objSectionInfo = SectionUtility.GetSectionInfoFromDB(SectionID);

    // Assign the Section values
    ctlGeneral.Section = objSectionInfo;
    ctlAppearance.Section = objSectionInfo;
    ctlWebBoxes.Section = objSectionInfo;
    ctlSecurity.Section = objSectionInfo;
    ctlWebServices.Section = objSectionInfo;
    ctlAdvanced.Section = objSectionInfo;

    //Init the Menu with this
    for (int index = 0; index < MainMenu.Views.Count; index++)
    {
    Menu1.Items.Add(new MenuItem(MainMenu.Views[index].ID, index.ToString()));
    }
    Menu1.Items[0].Selected = true;


    // Initialize roles
    ArrayList colAllRoles = UserUtility.GetAllRoles();
    ctlSecurity.AllRoles = colAllRoles;
    ctlAdvanced.AllRoles = colAllRoles;

    }
    }

    protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)
    {
    MainMenu.ActiveViewIndex = Int32.Parse(e.Item.Value);
    }


    protected void UpdateSection(Object s, EventArgs e) {
    if (IsValid) {
    SectionUtility.EditSection
    (
    SectionID,
    ctlGeneral.Name,
    ctlGeneral.Title,
    ctlGeneral.MenuTitle,
    ctlGeneral.Description,
    ctlGeneral.IsEnabled,
    ctlWebBoxes.InheritWebBoxes,
    ctlWebBoxes.WebBoxDisplayMode,
    ctlWebBoxes.InheritWebServiceBoxes,
    ctlWebBoxes.WebServiceBoxDisplayMode,
    ctlAppearance.PageSkin,
    ctlAppearance.PageStyle,
    ctlGeneral.ParentSectionID,
    ctlAppearance.PageHeader,
    ctlAppearance.PageFooter,
    ctlAppearance.Footer,
    ctlAppearance.PageMetaKeys,
    ctlAppearance.PageMetaDesc,
    ctlAdvanced.RecordsPerPage,
    ctlAdvanced.EnableTopics,
    ctlAdvanced.EnableComments,
    ctlAdvanced.EnableModeration,
    ctlAdvanced.EnableRatings,
    ctlAdvanced.EnableCommentRatings,
    ctlAdvanced.EnableNotifications,
    ctlAppearance.InheritTransformations,
    ctlAppearance.Transformations,
    ctlWebServices.IsSectionWebService,
    ctlWebServices.WebServicePassword,
    ctlAdvanced.AllowHtmlInput,
    ctlAdvanced.AllowCommentHtmlInput,
    ctlAppearance.Logo,
    ctlAppearance.FailSkin
    );

    // Update View Roles
    if (ctlSecurity.ViewRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.ViewRole, ctlSecurity.ViewRoles);

    // Update Add Roles
    if (ctlSecurity.AddRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.AddRole, ctlSecurity.AddRoles);

    // Update Edit Roles
    if (ctlSecurity.EditRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.EditRole, ctlSecurity.EditRoles);

    // Update Delete Roles
    if (ctlSecurity.DeleteRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.DeleteRole, ctlSecurity.DeleteRoles);

    // Update Comment Roles
    if (ctlAdvanced.CommentRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.CommentRole, ctlAdvanced.CommentRoles);

    // Update Moderate Roles
    if (ctlAdvanced.ModerateRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.ModerateRole, ctlAdvanced.ModerateRoles);

    // Update Rate Roles
    if (ctlAdvanced.RateRolesChanged)
    SectionUtility.AddSectionRoles(SectionID, RoleType.RateRole, ctlAdvanced.RateRoles);

    // Update Web Boxes
    if (ctlWebBoxes.WebBoxesChanged)
    SectionUtility.AddSectionWebBoxes(SectionID, ctlWebBoxes.WebBoxes);

    // Update Web Service Boxes
    if (ctlWebBoxes.WebServiceBoxesChanged)
    SectionUtility.AddSectionWebServiceBoxes(SectionID, ctlWebBoxes.WebServiceBoxes);

    // Update Service Subscriptions
    if (ctlWebServices.ServiceSubscriptionsChanged)
    SectionUtility.AddSectionServiceSubscriptions(SectionID, ctlWebServices.ServiceSubscriptions);

    // Redirect to EditSections
    Response.Redirect("Default.aspx");
    }

    }



    }
    }


    And there we have it - one thing to note - I have the admin as an assembly so the listpicker is part of the dll now ...Replace Cavalia references with the full blown Aspnet...

    Code is for STOCK CSK and GCN I simply changed the namespace...

    If anyone wants the ISPAdmin dll I can post that on my site but thus far I feel there is limited insterest in this...


    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
  • Re: My Notes Continued: Mail / Notify

    11-22-2005, 5:04 AM
    • Participant
      868 point Participant
    • BillKrat
    • Member since 08-19-2003, 7:30 PM
    • Amarillo, tx
    • Posts 176
    [Jody]
    I have the ISPAdmin now as a an actual assembly.
    I have the Admin tool as an assembly

    When you have time could you please take a sec ;) and share how to convert these into assemblies?   Your few minutes could save me hours.   I actually tried to follow the link I saw earlier that referenced an article you did about this but it took me to a dead page.

    Working with code behind files is not going to be practical long  as I have to wait a long time for the compile - not good when I'm just making a few second change during development.   I trust if I move as much code as possible into assembles my "waiting time" will be less.

    It looks like you have a lot on your hands so not a problem if you are to busy.

    Bill
  • Re: My Notes Continued: Mail / Notify

    11-22-2005, 6:15 PM
    • Contributor
      4,482 point Contributor
    • jodywbcb
    • Member since 03-12-2003, 11:52 AM
    • West Seattle,WA
    • Posts 985
    My BETA version of the Admin portion converted to 2.0 (link)


    This is a learning project - see EULA on download page for restrictions.  Requires being a verified member to download.

    It includes the whole admin portion in a seperate projects within a solution.  Less one or two items and the Add / Edit section listpicker not working... should be functional.  See my impromptu instructions on the download page. 

    There is no support for this - it merely illustrates how to convert the codefile conversion to an actual assembly so that there is one main dll instead of a bunch of codefiles which get compiled as seperate dlls at runtime. 

    Again it is an example and as of this posting - is what I am using in my dev enviroment.  It is provided in hopes that someone may be able to assist in the listpicker issue mentioned a post or two above in this thread....




    -- jody
    My Blogs on .Net 2.0 and Ajax
    http://csk.wbcb.com
    http://ArtbyJody.com
Page 1 of 1 (10 items)
Microsoft Communities