View from inside the viper

Logging in DotNetNuke

  April 2, 2013 19:27
by Mark

Starting in DotNetNuke 6.0 support was added for log4net, a first rate logging framework developed by the Apache Foundation.

So why log? Well any non trivial module can benefit from logging, it means you can easily debug an issue on a live site and see what is happening under the hood.
A liberal sprinkling of logging statements in your DotNetNuke module can save you a lot of time when you have some unexpected behaviour in your module.

DNN Logging 101

DNN have wrapped the standard log4net logging statements in a class called DnnLog which is part of the assembly DotNetNuke.Instrumentation.dll. So to get started with logging you need to add a reference to this dll in your code.

Within the logging framework we have different levels of log, this allows us to filter out some of the debug statements in a production DNN install and just log errors or fatal events to the log output for example. Starting at the lowest logging level going to the highest level we have

  • debug
  • info
  • warn
  • error
  • fatal

So if we have the logger set to record all debug level messages it will also log the higher log levels as well, if we however set the log to error level then only error and fatal would be record with the other lower levels ignored.

Within the DNN class DnnLog we have a method for each type of these logging events with various overloaded options.

DnnLog.Debug("Category ID:{0} is at depth:{1} of the category tree", c.CategoryID, depth);

So using this logging statement we can use string formatting to record the debug log message. We can also log exception using a different overloaded method. Using intellisense it is pretty easy to discovery the correct method to use.

Taking Control

So that is all there is to it, oh wait, where do the log messages appear and how do we control the level?

Within the root of the DNN site you will find the file DotNetNuke.log4net.config this is used to control the logging within the site. The default setting is to log to a file only error levels or above.
In a development environment it might be more productive to set the log level to debug so that we get all log statements. To do this we would simple edit the root level

  <level value="Error" />
  <appender-ref ref="RollingFile" />

To the new value of

  <level value="Debug" />
  <appender-ref ref="RollingFile" />

The RollingFile appender will log the output into a text file which can be found in this directory, \Portals\_default\Logs
A new log will be created each day, its important to remember that DNN won’t delete old log files so this could grow to be a large directory if left unchecked.

Bonus Tip

Something which can be useful when debugging and developing is to have the DNN log statements output in the standard Trace Output for the page.
Its a pretty simple thing to do, you would just need to add a new appender that uses the AspNetTraceAppender and then define the appender in the root element.

<?xml version="1.0" encoding="utf-8" ?> 
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> 
    <file value="Portals/_default/Logs/" /> 
    <datePattern value="yyyy.MM.dd'.log.resources'" /> 
    <rollingStyle value="Date" /> 
    <staticLogFileName value="false" /> 
    <appendToFile value="true" /> 
    <maximumFileSize value="10MB" /> 
    <maxSizeRollBackups value="5" /> 
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> 
    <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%date [%property{log4net:HostName}][Thread:%thread][%level] %logger - %message%newline" /> 
      <locationInfo value="true" /> 
  <appender name="AspNetTraceAppender" type="log4net.Appender.AspNetTraceAppender" > 
    <layout type="log4net.Layout.PatternLayout"> 
        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> 
    <level value="DEBUG" /> 
    <appender-ref ref="RollingFile" /> 
    <appender-ref ref="AspNetTraceAppender" /> 

Then whenever you have Trace turned on the log statement

I hope you found this article useful and you give the DNN logging framework a try in your next module.

DotNetNuke Ecommerce Made Easy with the Latest Cart Viper Release 1.6

  April 23, 2012 16:24
by Mark

1063650_37233894Today marks a great day in the development of Cart Viper our ecommerce solution for DotNetNuke, we have just release version 1.6 of the product.

This is a major release with over 35 great new features or improvements to Cart Viper. Over the coming days and weeks we’ll be talking some more about some of the key new features in this release and why it can help you create a great ecommerce store for your customers.

  1. Numerous performance improvements
  2. Ability to sell events - AJAX events calendar module (please note this is an extra add-on).
  3. Google Sitemap support for getting the best possible SEO.
  4. Youtube videos on product details
  5. Categories support Youtube videos.
  6. Pre-checkout notification callback method to validate the order before allowing it be placed within the store.
  7. Export new orders to the Amazon Message Queue SQS, allows integration into external systems to process placed orders.
  8. New payment gateway Cyber Source
  9. Support for three new currencies JOD, HKD, THB and MXN
  10. Mix and match discounts, buy 6 items from this category and get 10% off the items for example.
  11. Let customers request a quote for a large order, moderate and adjust the prices then allow the customer to pay for the order online using a credit card.
  12. Optionally define customer managers that need to approve orders from sub accounts before the order can be placed within the store. Great for B2B sites that need basic order moderation for their corporate clients.
  13. Define a global quantity limit and quantity purchase pattern for a product to mean that only specified quantities of the product can be purchased.
  14. Ability to use custom smtp settings per portal when sending the emails generated by Cart Viper.
  15. Support for an unlimited number of options for a variant, user interface just expands as you enter product options.
  16. The product tabs and related products output is now controlled using a token, so you are free to place this controls anyway you like within the template.
  17. Improved product tab feature including, token support, embed modules, tab header, tab security roles and better sorting.
  18. The template system used to style the store now allows you to import an existing DNN module into the template.
  19. Define product facets which allows customers to filter products based on the product facets, size, colour, type, manufacturer etc.
  20. When search by keywords the products can be filter to a given manufacturer or category using the keyword facet search.
  21. An unlimited number of variants can be imported via csv.
  22. Ability to send order confirmation emails to multiple email addresses with your organisation.
  23. More tokens added to the custom email templates.
  24. Mark a product as in-store pickup only, means the customer must collect direction from the store.
  25. Optional ability to apply a percentage or fixed amount surcharge to an order placed with Paypal Standard.
  26. The store admin can now search for all orders placed during a start and end date.
  27. New order status - partial shipped.
  28. Batch printing of orders, select the date range and the order status then generate a PDF containing all the orders, print out and include with your package.
  29. Ability to restrict which states in the USA you will ship goods to.
  30. Cyber Source external tax gateway support, exact tax calculations based on the customer’s address.
  31. Newsletter subscribers management page to display a list of existing subscribers. Export the list to CSV.
  32. Allow products to be visible only to users with the required role.
  33. Include a shipping tracking number when you dispatch a customer’s order.
  34. Support for defining tax rates by each Canadian Province for stores located in Canada.
  35. New mega menu style category menu this can be rendered either vertically or horizontally. Optionally we can output the standard DNN menu into the mega menu to create a complete menu solution for your store.
  36. Recurring billing support when using payment gateway.

We are excited to have created this release and we hope you’ll take the free 14 day trial and see for yourself.

Existing customers from earlier versions can download the new version and upgrade for free, simply download and install the free trial, your existing license will unlock this to a full version.
We strongly recommend that you follow the upgrade steps in the manual and take a full backup of your database and existing site.

DNN SEO–10 Minute Task to Get a Better SEO Ranking

  March 26, 2012 09:52
by Mark

Today getting the best possible SEO ranking for your DNN website is critical to the success or failure of your website. But what if you were missing out on maximising your potential that only takes 10 minutes fix?

Its important that every page in your DNN website has a unique meta description, this not only helps with getting a better rank but its common for the page description to be displayed in the search results. A carefully written page description can help encourage a user to click your entry in the result.

Even a small DNN site could prove a lot of work in checking the description for each page but there is a free module Keyword Editor that you can deploy to your site which lets you manage the meta description for all your pages. Better yet the module has an AJAX interface which lets you edit the page’s description so you don’t need to visit every page in your site.

Getting Started

1. Download and install the module.

2. Create a new page in the admin menu, its important that the page is only available to the site administrator. You don’t want visitors to your site being able to change your page descriptions.

3. Simply click on the row to start editing the page’s meta data, when you have completed editing the row just click on another row in the table to save the values.


Ten minutes spent tuning your page descriptions in DNN could have a dramatic improvement of your site traffic!

Customising the Captions in Cart Viper

  May 8, 2011 18:27
by Mark

Cart Viper allows you to customise the captions used throughout the module, this allows you to change the captions to better suit your requirements for example or client.

All the captions are stored in a resource files (.resx) within the module folder, however we do not recommend that you edit these files since any future upgrade of Cart Viper will replace your modified files ones from the new package.
Instead you should use a portal specific resource file which will not get over written with future upgrade and also means the change won’t affect other portals.

DotNetNuke first looks for a resource key it needs in a portal specific resource file before falling back to general resource file if unable to locate the key.
Since we have this fall back feature our portal specific resource file only needs to contain the resource caption we want to change, the standard resource file will supply the other captions.

Lets take a look at an example, I’m going to change the caption on the mini cart module to use the world “Basket” in place of “Cart”.


The first thing we need to do is locate the correct resource file.

The resource files are located in the folder /DesktopModules/CartViper/App_LocalResources


Each ascx control has 4 resource files, each for the 4 different languages we support. For the demo here I’m just going to change the English version however the same principle can be applied to any of the other languages.
Additionally we have a SharedResources.resx file which contains captions used by the AJAX code to return the correct messages to display.

Since we are going to change the captions on the Mini Cart control the file we need to look at is MiniCart.ascx.resx

Lets go a head and open that file with notepad or similar, the file itself is just a XML document that has key value pairs for the captions.
Most of the file contains comments and boiler plate entries, the place we need to look at are the elements with the <data> element.
The name attribute of the entry will be the name of control that is rendering the caption.


I've created a blank resource file which you can use as the basis for the new file. Into this file we are going to copy the entries we want to change. I’m going to copy the following entries into my new file.

<data name="btnViewCart.Text" xml:space="preserve"> 
  <value>View my Cart</value> 
<data name="AddAnother.Text" xml:space="preserve"> 
  <value>Add one or more {0} to the cart.</value> 
<data name="lblNumberItemsText.Text" xml:space="preserve"> 
  <value>:</value> 
<data name="lblYourCart.Text" xml:space="preserve"> 
  <value>Cart Summary</value> 

After copying these into the template file I’m going to change the word “cart” to “basket” in the value elements.

The most important part of implementing the change is to name the file correctly, the file needs to be named with the original file name but needs .Portal-X (where X is the ID of the portal you are wanting to apply the change for) inserted just before the .resx extension ending.

Since the original file name was MiniCart.ascx.resx the new portal specific change needs to be named MiniCart.ascx.Portal-2.resx (my demo portal has an ID of 2) and placed into the folder /DesktopModules/CartViper/App_LocalResources

Refreshing the page shows the new resource file has been picked up by DotNetNuke.


My complete resource file is listed below for reference.


<?xml version="1.0" encoding="utf-8"?>
  <xsd:schema id="root" xmlns="" xmlns:xsd= 
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:import namespace="" /> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="metadata"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="assembly"> <xsd:complexType> <xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=, Culture=neutral,
PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=, Culture=neutral,
PublicKeyToken=b77a5c561934e089</value> </resheader> <!-- CART VIPER - CUSTOM resx TEMPLATE ADD YOUR CUSTOM DATA ENTRIES INTO THE FILE BELOW THIS COMMENT --> <data name="btnViewCart.Text" xml:space="preserve"> <value>View my Basket</value> </data> <data name="AddAnother.Text" xml:space="preserve"> <value>Add one or more {0} to the basket.</value> </data> <data name="lblNumberItemsText.Text" xml:space="preserve"> <value>Items In Basket:</value> </data> <data name="lblYourCart.Text" xml:space="preserve"> <value>Basket Summary</value> </data> </root>

Cart Viper Version 1.2.6 Released

  April 14, 2011 11:51
by Mark

New Release of Cart Viper 1.2.6Yesterday we released the next version of Cart Viper 1.2.6.

This new release contains lots of new and improved features along with bug fixes to minor issues.

  • Create and manage an unlimited number of tabs for a product.
  • Google Checkout is supported as a payment gateway.
  • Carousel template for use with the Related Products, Recently View Products and Product widget module.
  • The Category menu can now optionally expand and collapse the items in the menu.
  • Order PDF supports adding the Model Number or SKU field to each line item ordered.
  • Payment method displayed on the confirmation emails, order and PDF generated by Cart Viper.
  • Ability to display a MSRP which is struck out in the store front.
  • Out of Stock flag on a product.
  • Wish lists now support product variants.
  • Ability to make a wish list public and share the link with friend.
  • Ability to operate a store without an online payment gateway just using the offline payment option.
  • Ability to display prices inc VAT in the cart and mini cart.
  • Products support serial numbers with automatic assignment of the next free serial number.
  • Optionally collect Company Name and/or VAT number at the checkout stage.
  • Numerous minor bug fixes

With that release out of the door we are now turning out attention to the next release, if you’ve got a suggest or idea you would like to see added please let us know.

Why Cart Viper?

  April 12, 2011 15:40
by Mark

Why pick Cart Viper as your ecommerce platform for DotNetNuke?

flame_abstractDotNetNuke gives your clients a great web application allowing them manage their website’s content with easy. Now imagine using DotNetNuke to offer a complete ecommerce store for the client, complete with online checkout, order history, template driven design and so much more besides.

Having a single web application for both CMS and ecommerce makes management easy for client, it also makes creating the solution simple for you since you’re experienced with DotNetNuke already.

Since we first had the idea to create Cart Viper we have worked hard to make a great product that is easy to use and contains all the features you need.
Over the last 9 months we’ve been adding and improving the features of Cart Viper, most of these have come direct from you our customers providing feedback.
We are committed to making the best ecommerce module on the DotNetNuke platform.

Don’t take our word for it, look at the review, testimonials and take the free 14 day trial.

DotNetNuke eCommerce Modules Review

  February 22, 2011 15:45
by Nigel

Recently Robb Bryn over at DotNetNuke fool took the time to review several eCommerce modules for DotNetNuke, we are pleased to say his review put Cart Viper top overall with an average score of 3.6 from a possible 5. We are obviously very pleased about this as we have only be developing Cart Viper for 6 months, and were in a strong line-up that included all our more established competitors.

We have taken Robb’s comments onboard and are looking to address a number of his concerns with our forthcoming 1.2.4 release with a view to making an even better product!

You can read the full review here.

Cart Viper is available for a free 14 day trial here.


Cart Viper Version 1.2.3 Released

  February 2, 2011 16:05
by Nigel

Here at Cart Viper we are happy to announce we have released version 1.2.3 of Cart Viper and it is now available to download and take a free 14 day trial.

New features for this release:

  • Remove all unmanaged code so Cart Viper is now fully compatible for running in a medium trust environment.
  • Google analytics ecommerce and event tracking supported.
  • If a product is a digital download you can specify an unlimited number of files to be downloaded by the user once order has been placed.
  • Ability to import SEO keywords for a product during the product import routine.
  • Add ability to disable product comparison feature via admin settings.
  • Bug fix when viewing an order as an anonymous customer.

If you think there is a feature missing from Cart Viper or there is anything we can improve please contact us


Cart Viper – Version 1.2.2 Released

  January 19, 2011 15:13
by Nigel

Following on from our New Years resolution to release smaller updates more frequently of Cart Viper our DotNetNuke Ecommerce module, Mark and myself are happy to announce version 1.2.2 is now available to download for a free 14 day trial!

New features:

  • Enhanced existing “My Account” module so a customer can now search for their orders by order ID or order status.
  • Optionally limit the quantity of a product a single user can purchase per order.
  • Mark a product as “free shipping” so regardless of the shipping rules for the store this product will not incur a shipping cost.
  • Product wishlist enhancement – a user can now create an unlimited amount of product wishlists.
  • Product comparison – allow a user to compare up to 4 products side by side to view the differences.
  • Product import via CSV enhancement – if the product already exists in the store the product is updated rather than re-added during an import.
  • Product SKU – store admin can now optionally store a product SKU.
  • Product barcode – store admin can now optionally store a product barcode.
  • Product widget enhancement – can now select products that are currently on special offer to display in the product widget.
  • Product category edit bug fix.
  • Product offer bug fix.

If you have any feedback good or bad or would like to request a feature please let us know.


Improved Order Confirmation Emails

  January 13, 2011 14:29
by Mark

One of the improvements we’ve made to Cart Viper 1.2 our advanced ecommerce application for DotNetNuke is the support for using templates to generate the emails which are sent to the customer once they place an order.

In the previous version the email was limited to being a plain text email which is stored in the resource files, this still exists and you can continue to use this but we’ve adding in advancing template functionality which allows you to create rich HTML emails.

So for example you can now add your store logo and branding to the order confirmation email.


How to Enable the New Email Template Feature

  1. Login as a store administrator
  2. View the store admin page and click the store info option
  3. Expand the Store Email Templates section and check the option Enable Custom Order Emails
  4. This will then use the templates listed in the drop down lists to create the email message used to communicate with the your customers.

Enabling HTML email templates

The template files are just html file which contain normal HTML mark-up and also tokens which are substituted with data from Cart Viper at the time of the email generation. So for example we have a token which allows us to output the customer’s name into the email.

When using Cart Viper in multiple portals with a single host each store can have their own customised email templates as well.

The manual provides a full break down of the tokens we support in the templates and how to go about customising them for your requirements.


Don’t forget we offer a full 14 days free trial, no registration required, all backed up by our first class support.