Archive

Archive for the ‘MCMS 2002’ Category

Visual J# 3.0 Requirement for MCMS 2002?

One of our CMS web managers worked to install the CMS Site Manager on a new employee’s computer today, and got a really odd message.

Say what?  3.0?  Last I checked (http://msdn2.microsoft.com/en-us/vjsharp/bb188598.aspx), the highest was still 2.0.  So, after working with the user and trying both 1.1 and 2.0 (just for grins), no go.

After searching through the web, I came across this old MSDN forums post:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1182594&SiteID=1

It appears the 3.0 is just a detect of the current .NET version you have installed.  Unfortunately, since 3.0 doesn’t have a J# version, it requires removing 3.0, installing MCMS Site Manager, then reinstalling 3.0.

Ugh.  Not a smooth move, Mr. Microsoft.

Categories: c#, MCMS 2002, Microsoft

Merging Different DataSources – Old and LINQ Ways

July 2, 2007 Comments off

Recently, I had to come up with a way to do lookups from an existing application (with data in a SQL Server 2005 base) to our primary database (an Oracle 10g base).  If these were in the same database, or even same server, you could join the tables and things would be pretty easy.  Unfortunately, this took two steps, but turned out to not be so bad.

Here’s an example.  Note, I’m using the Enterprise Library for pull the data down, but the true example is independent of that—feel free to use whatever connection you feel fit to use.

Database dbSandbox = DatabaseFactory.CreateDatabase(“Sandbox”);

 

string sqlSandbox = “SELECT COUNT(r.RecordId) as Count, r.DepartmentId “ +

“FROM ExceptionRecords r “ +

                  “WHERE Year = @Year “ +

                  “GROUP BY r.DepartmentId “ +

                  “ORDER BY r.DepartmentId”;

 

DbCommand cmdSandbox = dbSandbox.GetSqlStringCommand(sqlSandbox);

db.AddInParameter(cmdSandbox, “Year”, DbType.Int32, 2006);

 

DataTable dtSandbox = dbSandbox.ExecuteDataSet(cmd).Tables[0];

Now we have a DataTable object that contains our information.  However, while we have the DepartmentId, we need the Department Name for our report.  That information is not located anywhere within the SQL Server database because the application is using our standard framework to get that information at runtime.

So, let’s add a new string column to our DataTable to hold the Department name.

dtSandbox.Columns.Add(new DataColumn(“DepartmentName”, typeof (string)));

Now, we’re ready to loop through and populate that new column.

foreach (DataRow row in dtSandbox.Rows)

{

row[“DepartmentName”] = Depts.GetDept(Convert.ToInt32(row[“DepartmentId”])).Name;

}

We’re now free to use this DataTable for our report or add additional columns/calculations to it.

Now, what if we wanted to get a bit crazy and use LINQ instead of standard T/SQL?

SBDataContext db = new SBDataContext();

var records = from r in db.ExceptionRecords

where r.Year == 2006

orderby r.DepartmentId ascending

group r by r.DepartmentId into g

select new {

DepartmentId = g.Key,

Count = g.Count() };

So, we’ve now got a var object that contains our grouped information.  The group statement in LINQ basically says: take the information you have in “r” and group it by a column, in this case DepartmentId, and place that into a new object, called [g] (for group, for sake of simplicity).  Afterwards, we created a new var object (to be placed into records) that consisted of the grouping key (which was the DepartmentId) and a count by each DepartmentId.

For the SQL inclined, we’ll notice that the statement looks similar to our one above:

SELECT [t1].[DepartmentId], [t1].[value] AS [Count]
FROM (SELECT COUNT(*) AS [value], [t0].[ DepartmentId]
FROM [ExceptionRecords] AS [t0]
WHERE [t0].[Year] = @p0
GROUP BY [t0].[ DepartmentId]) AS [t1]

Now, we must place the DepartmentName with the record.  If we simply wanted to write it out, we could do something like:

foreach (var c in records)

{

Response.Write(String.Format(“{0} ({1}) – {2}<br/>”,

Depts.GetDept(c.DepartmentId).Name,

c.DepartmentId,

c.Count));

}

Or we could create a DataTable (since GetDataTable() has unfortunately disappeared from the current LINQ release; hopeful that it will make it’s return along with the LinqDataSource in Beta2):

DataTable dt = new DataTable();

dt.Columns.Add(new DataColumn(“Count”, typeof (Int32)));

dt.Columns.Add(new DataColumn(“DepartmentId”, typeof(Int32)));

dt.Columns.Add(new DataColumn(“DepartmentName”, typeof(string)));

 

foreach (var c in records)

{

DataRow dr = dt.NewRow();

dr[“Count”] = c.Count;

dr[“DepartmentId”] = c.DepartmentId;

dr[“DepartmentName”] = Depts.GetDept(c.DepartmentId).Name;

dt.Rows.Add(dr);

}

Is one better than the other?  Ehh… the TSQL solution is quick, painless, and using Enterprise Library, relatively standard to support.  The LINQ solution requires almost no TSQL knowledge, allows everything to be handled by the application, but is a bit bumpy if you’re wanting to populate anything that doesn’t understand the var object.  Going from Data -> DataTable is a LOT less code than with LINQ, but eventually, perhaps, that won’t even be necessary.

 

Creating Customized CMS 2002 Print Pages (without Custom Templates)

January 29, 2007 1 comment

One of the most challenging, and mind-numbing, tasks of CMS 2002 revolves around creating and maintaining custom “print page” templates.  I’ve seen, and worked with, quite a few convoluted examples and ideas and, in the end, build off of a simplistic print page created by a prior coworker of mine.

The concept focus on using basic JavaScript to re-render the page specified in DIV tags.

Read more…

Categories: .net 1.1, c#, MCMS 2002

Keeping up with Microsoft

December 7, 2006 Comments off

We’ve been attempting to push out a shared solution for CMS and SharePoint Portal since I took this position, hmm, wow, over two years ago.  It’s not so much that it took me that long to load the software on the server, get a vision written, and get a customer base interested in the product–that was easy.  It was getting past the politics of my own department–the MIS Department.

Now, here we are in December of 2006 and MOSS 2007 is knocking on the door (it’s loaded in a test lab already) and I’ve been asked to write up the presentation and information to roll SharePoint out–SharePoint 2003.

So, a rock and an outdated place–roll out an old technology that doesn’t integrate into some of the new .NET 2.0/3.0 technologies I’m working on for other projects or wait until 2007 is feasible and chance that team technologies falls out of favor again?

That’s today’s internal debate.

MCMS 2002 SP2 & SQL Server 2005 Provider Timeout Fix

November 28, 2006 3 comments

Okay, so… annoying little bug.  When attempting to export or import packages from MCMS 2002, I would constantly recieve an error that the SqlDataProvider has timed out and returned a (403) Forbidden HTTP error.  The connect didn’t SEEM to time out–it was reading the channels in Site Manager just fine.  The site itself worked just fine.

I’ve hunted for days to discover if it was a permission issue, a file location issue, or even a database issue.  Nothing associated SP2 with time out issues–especially in regards to Site Manager.

Until today.

KB913401 points out the EXACT error in “Content Management Server 2002 SP1a”.  However, the text of the article refers to SP2, not SP1a.  Meh.

After getting the hotfix, I installed, ran the DCA, had it ‘upgrade’ the database, and things work like a champ now!

A side note:

The instructions say to copy _dca.ini to the MCMS SQL Install folder.  Copy BOTH files.  The DCA will error out if the _sp1atosp2upgrade.sql file is not also present in that folder.  I’m not sure why the MSFT article leaves that file out of the installation instructions.

Categories: .net 1.1, MCMS 2002, SQL

CMS2002: Quick and Easy Random "Factoid" Control

November 16, 2006 Comments off

A recent request came through to allow our CMS users to add a random “fact of the moment” or “factoid” to the homepage.  The tool would need to cycle through 5-10 random facts that include a title and heading.

My initial reaction was to simply create a database table and let it read from the database table.  How much more simple can you get?  Three or four columns, depending on how detailed you wanted to get (title, body, date, boolean for display) and a simple dataset.  On the other hand, what about the user?  How would s/he update it?  That requires creating an admin page for that control–something that I wasn’t sure I wanted to do or maintain long-term.

So, what’s another option?  What’s easily dropped into a dataset and readable?  Well, XML!

Pros:

  1. The code is extremely simplistic.
  2. The user maintenance is fairly short and mundane–anyone, with a bit of training, can update the XML file as long as it’s easy to read.

Cons:

  1. Breaking the XML file will break the control unless proper safeguards are in place.
  2. How do we secure the file to keep it safe?  Where do we put it? 

The Code

In CMS, I opted to simply create a custom user control (TextRotator.ascx, for this example) with the code in a separate file (TextRotator.ascx.cs).

The user control itself contains, for this example, simply two label controls–the header and body.  In the HTML, I’m assigning the lblHeader label the CssClass of “rotatingHeader” and the lblBody label the CssClass of “rotatingBody”.  These are then added to our base CSS file that is called by all pages in our CSS project.  You can also style these separately within the control.

Now, on to the code-behind.

The user control needs to:

  1. Create an empty Dataset and populate it with values from our XML file.
  2. Choose a random value to display.
  3. Set the header and body approprately to the chosen random value.

Before we start coding, let’s layout our XML file first.

For this example, we’re going to just have a title and a body.  As additional nodes are added, additional “factoids” are rotated through–at least that’s the plan!

<?xml version=”1.0″ encoding=”utf-8″ ?>
<rotatingtext>
<fact>
  <title>Did you know…?</title>
  <body>Wichita Public Schools is the largest district between the Mississippi River and Denver, and Dallas and the Canadian border.</body>
</fact>
</rotatingtext>

Step 1 is easily completed by using the built-in methods of a DataSet.

// Create a new dataset and drop the rotating.xml file into it.
DataSet ds = new DataSet();
ds.ReadXml(Server.MapPath(“~/rotating.xml”));

The DataSet.ReadXml method provides “a way to read either data only, or both data and schema into a DAtaSet from an XML document.”  That’s exactly what we want to do here.  The XML file is located in the root directory of our website for easy access and, in production, be located anywhere the developer desires.

Step 2 is completed by two steps.  First, we must determine how many records exist in our dataset and, from there, we can generate a random number between 0 and our total records.

// Find the total number of objects (factoids to rotate).
int totalObjects = ds.Tables[0].Rows.Count;

// Generate a random number between 0 and the total factoids.
// We don’t want to always show the same factoid.

Random rnd = new Random();
int pickedObject = rnd.Next(totalObjects);

The Random.Next(Int32) method provides a random number between 0 and the number provided by our Rows.Count.  It’s most important to remember that if you have eight entries, they are returned as 0 to 7.

Step 3 requires us to capture our new random number and use it to access the DataSet and display our results.

// Set the header and body to the picked objects.
lblHeader.Text = ds.Tables[0].Rows[pickedObject][“title”].ToString();
lblBody.Text = ds.Tables[0].Rows[pickedObject][“body”].ToString();

The DataSet.Tables[].Rows[pickedObject] ensures that the random number generated above is picked out of our DataSet along with the proper column name (matching our XML file’s schema).

Finally, I suggest surrounding everything with the proper try/catch statements to ensure that, in the event that the XML file is not found, the entire CMS site does not collapse.

That’s it!  From here, we save and compile to generate our user control and we’re ready to drop it on our CMS templates for consumption.

Categories: .net 1.1, MCMS 2002

CMS2002: Image, ImageButtons, and How to Add Redirects

October 31, 2006 Comments off

It’s thumbnail madness this week, it appears.  I keep running into odd things regarding thumbnails and redirection.  Today it’s not specifically opening a new window, and it’s not ASP.NET 2.0.  We’re looking at good old ASP.NET 1.1, Microsoft CMS 2002, and attempting to get a posting’s associated image (which we have a thumbnail of on the home page) to redirect the visitor to the news posting when clicked.

My original idea?  An image with an onclick attribute.  Nope!  Images don’t have an onclick event.

My next idea?  An image button!  Nope!  Imagebuttons create postbacks and the client script (javascript) isn’t executed.

So the solution?  A not-as-fancy literal!

Note: This assumes that you have instanciated your environment accordingly.  ThisPosting is a singular posting that is part of a PostingCollection called Postings.  MaxHeight and MaxWidth are variables contained in the web.config file.

The first thing we need to do is grab the ImagePlaceholder from the template:

ImagePlaceholder SummaryImage
SummaryImage = (ImagePlaceholder)ThisPosting.Placeholders[“SummaryImage”]

Now, let’s create our Literal control.  We’re creating a control rather than a simple String because we’ll later use the Controls.Add to place it.  If you are simply rendering it out, a String would work.

Literal postingImage = new Literal();
postingImage.Text = “<a href='” + url + “‘ border=’0’><img src='” + SummaryImage.Src + “‘ width='” + MaxWidth.ToString() + “‘ height='” MaxHeight.ToString() + “‘ border=’0’></a>”;

Now, as I stated, my news postings are rendered out into a table.  We need to add this new control to our TableCell cell.  To do this, a simple Controls.Add works.

cell = new TableCell();
cell.HorizontalAlign = HorizontalAlign.Left;
cell.VerticleAlign = VerticalAlign.Top;
cell.CssClass = “summary”;
cell.Controls.Add(cell);

From here, I have a table called tblSummary that the cell created above will be placed into.

Categories: .net 1.1, MCMS 2002