The DotNetNuke 7.0 Developer Quick Start page is intended to be used as a resource that can help get DotNetNuke extension developers up to speed on the latest offerings available in 7.0.0.
Please note, DotNetNuke 7.0 has some new baseline platform support requirements, these can be read hereAn overview of the new features can be found
here .
Pre-requisites
With the 7.0 release, DotNetNuke has changed pre-requisites for installation/upgrade. These are required for a number of reasons, but primarily so we can utilise the Web API from Microsoft and leverage some additional new capabilities of .net 4.0. Shaun Walker details the reasons for these changes
here.
A more complete overview of system requirements can be found
hereServices Framework
Services Framework allows developers to easily create a Web API that any "device" that speaks HTTP can call. In this sense "device" can be almost anything such as a smart phone, curl script, XmlHttpRequest. Almost anything that has an internet connection will do, and that means if you can write code for it, Services Framework will probably help you to integrate it with your DotNetNuke site. The single biggest convenience of Services Framework is that authentication, authorization and establishing a DotNetNuke context are all built in.
Services Framework is built on top of ASP.Net WebAPI. There are only a couple of small things that must be done a bit different in Services Framework than in ASP.Net WebAPI. In almost all cases when the question "How do I do X with Services Framework?" comes up, the answer is "The same way you do it in ASP.Net WebAPI.".
Note: the wiki has another has an additional
Services Framework - WebAPI page with useful information and links.
What's New in 7.0Not much and everything. In DotNetNuke 7 Services Framework has made the jump from ASP.Net MVC to ASP.Net WebAPI. The core features or mostly the same, but the under pinnings are totally different and better.
What's Different from WebAPI
Permission DefaultsBy default in ASP.Net WebAPI everything can be called by everyone with various attributes are then applied to tighten security. Services Framework takes the opposite approach, by default everything requires Host level access. Attributes are then applied to loosen those restrictions.
DnnApiControllerAll Services Framework controllers must inherit from DnnApiController. DnnApiController takes care of authentication and loading DotNetNuke context. Remember that by ASP.Net WebAPI convention controller names must end with "Controller" (e.g. MyFirstController).
DnnApiController also provides a few extra properties with some DotNetNuke context:
PortalSettings The settings of the current portal.
UserInfo The current user.
ActiveModule For services that are tied to a specific module (more on this below), will be null for services not tied to a specific module.
DnnAuthorizeAttributeVery similar to the ASP.Net WebAPI AuthorizeAttribute, but with an extra propertie and it works with DotNetNuke users.
StaticRoles The same as AuthorizeAttribute.Roles. That name was changed in anticipation of providing a more dynamic form of Role authorization that better fits the dyanmic nature of DotNetNuke roles.
IServiceRouteMapperIn ASP.Net WebAPI routes are normally mapped at Application_Start in Global.asax. In ServicesFramework routes get mapped after DotNetNuke is initialized, and after new portals are created. To allow proper mapping of routes, each Services Framework module must implement one instance of IServiceRouteMapper. Do not implement more than one instance of IServiceRouteMapper in a module. Doing so will cause the order of your routes to be undertermined.
When DotNetNuke needs to setup the routes, it will call RegisterRoutes on each ServiceRouteMapper implementation and pass it an object that implements IMapRoute.
The RegisterRoutes call is also a good time to make any changes to the GlobalConfiguration of the WebAPI, as it is guaranteed to be called before processing and service requests. Modifying GlobalConfiguration will affect all services and should only be used with great caution. It is also important to remember that RegisterRoutes may occaisionally be called more than one time during the life of an HttpApplication. Routes must be registered each time RegisterRoutes is called, but any other initialization likelly should only occur during the first call.
IMapRouteIMapRoute provides several overloads of the MapRoute method, which is used to actually map each route. The IMapRoute version of MapRoute is similar to the ASP.NET Mvc MapRoute with a few differences.
At minimum MapRoute requires:
string moduleFolderName This is typically the name of the folder in which the module is installed. This will be used as part of the route name that is required by ASP.Net WebAPI.
string url The url for your route. This exactly the same as the ASP.Net WebAPI routeTemplate parameter.
string[] namespaces An array of namespaces to search for controller to match this route.
Optionally MapRoute supports:
object defaults This is exactly the same as the ASP.Net WebAPI parameter.
object constraints This is exactly the same as the ASP.Net WebAPI parameter.
Finally the return value also differs. ASP.Net WebAPI returns an IHttpRoute object. Services Framework returns an IList
. Depending on the portal configuration it may be neccesary to create more than one route for each route specified. If required, the "real" name of each route can be found in Route.DataTokens["Name"]
.
RouteExtensions
Provides a GetName method that allows you to get the true name of each route mapped by the route mapper.
UrlHelperExtensions
Provides a DnnLink method to be used in place of the standard Link method. DnnLink takes some extra paratmers that are used to generate a link for the correct DNN route and portal.
Security
Service developers should be aware of additional Services Framework Security considerations.
What's Added over and above WebAPI
RequiresHostAttribute Apply this attribute to true to require Host level access. WebAPI provides a standard and complimentary AllowAnonymousAttribute which also works with Services Framework.
Additional MediaTypes Services framework adds a media type formatter which can convert between text/plain or text/html and string types. This is useful for AJAX services that are meant to return plain text.
Authentication methods Services Framework adds built-in authentication in three forms.
Web forms is useful for developing AJAX based modules. It requires that users login via a standard web page. It is recommended to be used with SSL otherwise the user credentials and Auth cookie will be transmitted in the open.
Basic Auth is useful for providing credentials outside of AJAX situations. User credentials are transmitted as Base64 encoded text, so SSL is highly recommended. To prevent browser interception, the WWW-Authenticate header is omitted from responses to XMLHttpRequests however the Basic Auth mechanism will work if credentials are provided in the headers, though it is not clear that this provides any advantages over Web Forms authentication.
Digest Auth is useful for providing credentials outside of AJAX situations. User credentials are encrypted along with a nonce to help protect the credentials. Digest Auth may be a good choice where SSL is not available. To prevent browser interception, the WWW-Authenticate header is omitted from responses to XMLHttpRequests therefore it is not possible to use Digest Authentication in an AJAX context.
namespaces Services Framework requires all routes specify one or more namespaces in which to locate applicable controllers.
DnnModuleAuthorizeAttribute This attribute is used to secure a service based on the permissions of a module instance. When using this permission all clients must submit the relevant Tab and Module ids as headers, there are helper methods in the JQuery plugin to help with this. The attribute has properties for PermissionKey, and AccessLevel each request will call ModulePermissionController.HasModuleAccess with the specified properties to authorize the user.
SupportedModulesAttribute Normally used in concert with DnnModuleAuthorize, this attribute takes a comma delimited string of module names, and only allows access to modules whose registered name appears in the list.
ValidateAntiForgeryTokenAttribute This attribute is similar to it's MVC equivalent, and in fact uses the same .Net base classes under the covers. It is intended to help prevent CSRF style attacks on web pages. It works by placing an encoded cookie and form field into a web page. Each request must include a matching set of these values. To make the anti-forgery device more friendly to content types other than form-urlencoded (e.g. JSON) the form fields are submitted as headers. There are helpers in the JQUery plugin to assist with submitting the correct values.
JQuery Plugin_ To assist in using the Services Framework for AJAX module development a JQuery plugin has been included. It is quite small and well worth reading through the debug version at /js/debug/dnn.servicesframework.js. The plugin includes a few more methods than what is listed below, but they are primarily intended as helpers for the below methods.
getServiceRoot Pass in the moduleFolderName of your service and it will return the correct root path to call your service for the current portal. The general form is /childpath/DesktopModules/moduleFolderName/API/.
setModuleHeaders This is meant to be called as a beforeSend method $.ajax. It will set headers for tab and module ids as well as the anti-forger token if present.
HttpRequestMessageExtensions
Provides additional methods to get the Tab and Module Ids included in a request. The tab and module id formats can be extended beyond the default header and query string locations by implementing the ITabAndModuleInfoProvider interface.
Also provides safe access to the HttpContext of a request. Wherever possible HttpContext should be avoided in services, however it is not always possible in those rare cases this method should be used. This method is essential when writing an Asynchronous service as the HttpContext will not be available from HttpContextSource.Current, or HttpContext.Current. There is also a GetIPAddress method available to cover the single most common reason for accessing the HttpContext.
Tab and Module Info
By default tab and module information can be passed to service framework requests via headers or the querystring. It is possible to extend these options by implementing the ITabAndModuleInfoProvider interface. Once a new implementation is written it must be registered via the HttpConfigurationExtensions.AddTabAndModuleInfoProvider method. This should be done inside a services route mapper, and care should be taken to only register the provider the fist time routes are mapped. It is occaisionally possibe for routes to be remapped while the site is up and running, which results in additional calls to map routes.
Custom Authentication Filters and Attributes
Services Framework ships with some general purpose authentication filters and attributes. However it may be necessary to implement authentication and authorization specific to a service. It is quite straight forward to implement your own filters and attributes they should be derived from one of AuthFilterBase, or AuthorizeAttributeBase. Additionally there is the IOverrideDefaultAuthLevel interface, this interface is used to indicate that the presence of the auth filter should override the default Host only authorization required to access a method. This is used on many auth filters but not all, a good example of a filter that doesn't need this interface is the ValidateAntiForgeryToken. Passing the anti-forgery check says nothing about the level of authorization required to access a method.
DotNetNuke.Framework.ServicesFramework TBD
7.0 Compatible Modules
Due to breaking changes explained above, modules which utilized the services framework in 6.2.x versions will need to be updated for 7.0 in order to operate. It is also worth noting that any module that utilizes notifications with custom API's call will also need to be updated.
Feature Changes
Social Groups And Security Roles
Role and Social Group Renaming
- Social Groups can now be renamed.
- Security Roles can also be renamed with the exception of System Roles
- System Roles(Administrators, Registered Users, Subscribers, Unverified Users) are marked as IsSystemRole in the database and thus cannot be renamed.
Role Ownership
- Security Roles can now have multiple owners.
Social Group Filtering
- Social Groups have new settings under Group Module Settings such as Enable Search, Sort Field and Sort Direction, Page Size
Site registration
DotNetNuke has always shipped with Public set as it's default portal (site) Registration Type. This was a decision that was inherited from the IBuySpy portal codebase that early versions of DotNetNuke utilised, and whilst it has advantages in enabling users to sign up immediately after installation, there are some drawbacks. Analysis of 18 months of security issues showed that 44% of them required the potential hacker to have a valid, authorized user account to start off with. As many sites ultimately aren't intended for public users (e.g. a personal site may have only one user or a business site may use active directory integration), the decision was made to change the site registration type to "Private" in 7.0.0
You can read more about this change on this blog
default.css changes
The default.css is one of the most important files as it is responsible for how DotNetNuke looks and helps to establish the user experience. It has over time collected styles for features that have been removed or changed and has collected declarations to mitigate upgrade concerns from legacy versions of DotNetNuke; consequently, this file has become inadvertently bloated with redundant styles, overwrites, and work arounds. These deviations can affect many of the more delicate rendering behaviors of browsers and can make skin and module development a challenge. In addition, these nuisances have made it difficult to validate default.css for standards compliance as well as made for a much larger CSS file. Furthermore, we want to introduce some more exciting and advanced UI features in DotNetNuke 7.0 which has encouraged us to re-evaluate default.css file in order to determine a style framework that could support them.
This blog covers this in more detail, and the wiki has a useful page here that explains more on the how default.css works.
DAL 2
DotNetNuke has introduced a new (optional) datalayer, that utilises a micro-orm called Peta-Poco. It provides the following:
- A close-to-the-metal option to execute any sql - basic SqlHelper like functionality. This would allow us to replace SqlHelper with a PetaPocoHelper class, which we have done in the core.
- Fetch (retrieve) methods that can take a parameterized SQL snippet as a parameter e.g.. “WHERE PortalID = @0”, thus reducing the overhead of creating and managing stored procedures.
- Page methods that can auto-generate the sql required to return a page of data from the database.
- Simple methods to Insert, Update and Delete “objects” in the database, with no need to write any sql.
- An IMapper interface which, while it doesn’t support cross-table mapping, will support things like an object qualifier (or table prefix)
- Transaction support
Further details can be found on the DAL 2 page.
Installer log
DotNetNuke 7.0.0 introduces a new "Installer" log that logs actions (both information and errors) that occur during installation, upgrade and extension installation. You can read more about it here