Sense/Net Devblog
The development blog of Sense/Net
Back to Sense/Net

Publish documents containing sensitive data with redaction

by Tamás Bíró 22. April 2014 17:49

For different reasons, organizations often have to publish documents that also contain sensitive data that cannot be published, such as personal or financial data. One reason for this might be a law or other regulation. Many public sector organizations have the obligation to publish contracts and other documents that usually also contain sensitive data.

In addition to this, organizations would often like to prevent download of original documents, or want to download a read only format, such as PDF.

With Sense/Net Document Preview and redaction, all this is possible.

What is redaction? According to Wikipedia:

 “The word may be used in relation to obscuring or deleting specific information, rather than editing an entire document; e.g. a court may order that the names of people be redacted (from a document).”

Redaction in a document management system simply means drawing and burning a black rectangle over specific areas of documents, rendering all information on that area unreadable.

As you can see, the chart for 2014 is redacted from this document, along with several other parts of the text.

If you only have Restricted Preview permission, you can only see the redacted version of the document. The redaction is actually burnt into the preview image, so there is no way to remove it, even if you can hack your browser. The black rectangles are in the image file, not drawn by JavaScript. If you have the Preview Without Redaction or Open permission, you have the option to hide the rectangles, in this case they are not burnt into the images themselves.

How it works? When you preview the file, a JavaScript based rich UI manipulates the images, so you can scroll, zoom, pan and page through them. You can also add highlights, annotations and redactions on the same user interface, by simply drawing with your mouse, naturally, only if you have the proper permissions to do so (Save).

Documents can also be downloaded as PDF, but redaction will be burnt into the PDF as well, based on your permissions.

Summarizing it:

  • Preview documents without downloading, right in your browser
  • Add and edit redaction from your browser, with appropriate permission
  • Preview with or without redactions, based on permissions
  • Burn redactions into images, original content is removed totally
  • Optionally download redacted version in PDF
  • No plugin or installation needed
  • Works on tablets
  • Reusable JavaScript code
  • Use redactions in your own development

For more details on permissions, visit the wiki documentation:


.Net | document management | preview | Office | redaction | security

Preview documents without downloading

by molnark 17. April 2014 15:45

Have you ever needed to browse through a big bunch of Office files? When you have to download, open, scroll, close for each document one by one? When you have to do this like 200 hundred times? Did you enjoy it? No one does.

With Document Preview, you can page through documents without downloading, without even leaving your browser. And you don’t even need a plugin, so no Java, no Flash, no ActiveX (yuck), only pure html and JavaScript. So pure it even works on tablet browsers. And it saves you bandwidth, because you do not have to download large files.


How it works? Pretty simple concept, but hard to code. Good news is that we did the coding for you already. As soon as a document is saved (uploaded or changed) a workflow starts converting the file into preview images. It uses a third party component to convert files into images and also to PDFs. When you preview the file, a Javascript based rich UI manipulates the images, so you can scroll, zoom, pan and page through them. You can also add highlights, annotations and redactions.

To see the preview image, you do not need the Open permission, but one of the Preview permissions is enough.

Summarizing it:

  •         Preview documents without downloading, right in your browser
  •         No plugin or installation needed
  •         Scroll, zoom, pan and page
  •         Thumbnails
  •         Works on tablets
  •         Reusable JavaScript code
  •         Save bandwidth
  •         Highlights, annotations and redactions
  •         Watermark
  •     Use the preview GUI in your own development as components

For more details, visit the wiki documentation:

Tags: , ,

Content Query | Feature | GUI | Tips and tricks | Tutorial

Sense/Net OData tips and tricks

by Timur Kristóf 14. December 2012 17:56

At Sense/Net we pride ourselves on working with the cutting edge. Thus we implemented a REST API for our Content Repository which is based on the OData standard by Microsoft. This means that without any extra effort, our software automatically becomes compatible with a huge bunch of already existing software which can utilize our OData service as clients.

To maximize user experience, we've created a completely custom OData implementation. It currently supports most of the standard with a small amount of custom extensions and a few features left out. But don't worry, this is just the first iteration of the feature, stay tuned for more. Also, do check out Tamás's blog post about the API itself and my own blog post about the general advantages of having a REST API.

Today I’m here to show you some examples and tricks about using this API to the fullest.

For now, let's stay in the browser and use AJAX for accessing them. There are a bunch of built-in articles in the demo site too, so let's just use those for now. (So that anyone can try out these even on our demo site.)

As a first example, let's say you want to access some content in your Sense/Net installation. Here's how you do that with jQuery.

    type: "GET",
    url: " /OData.svc/Root/Sites/Default_Site/NewsDemo/Internal",
    dataType: "json",
    success: function (result) {
        // Do something with the result
    error: function () {


Note that the resulting thingy in the success callback is a JavaScript object. This means that you can treat what you get back from the API in an object-oriented manner in JavaScript. It's very powerful.

You can see that the result contains way too much data for us, so let's use the $select query parameter to tell the Repository what we actually want from it. Let's get the Id, Path, and Lead text of the articles.

    type: "GET",
    url: "/OData.svc/Root/Sites/Default_Site/NewsDemo/Internal?$select=Id,Path,Lead",
    dataType: "json",
    success: function (result) {
        // Do something with the result
    error: function () {

Let's do something useful with the resulting stuff now. We're using Kendo UI ourselves these days, and so should you. Let's create a simple template using the template framework of Kendo UI and render our results with that.

Here's a rudimentary template which you can use to render the results:

<script id="javascriptTemplate" type="text/x-kendo-template">
    # for (var i = 0; i < data.length; i++) { #
        <li>#= data[i].Lead #</li>
    # } #


This basically lays out the articles in a simple way and provides links for viewing them in full. Next step: let's also retrieve the last modifier user of the articles. Here's how you would do that:



Oops! We can see that the resulting object has a __deferred property in it. This means that the object is another entity and is not fully loaded right now because that would cause too much data to be transferred through the wire. This is when the $expand query parameter comes to the rescue! (Note: you may have to upgrade your Sense/Net 6.2 installation to the latest release get this feature.)

Here's the URL to get what we want:


More tutorials are on the way to help you guys utilize this awesomeness.
Stay tuned for more OData goodness!



Tags: , , , ,

.Net | Tips and tricks | Tutorial

Sense/Net Content Repository now supports OData

by Tamás Bíró 12. December 2012 02:55

Many of our users were asking for a REST API for the Sense/Net Content repository. I have good news: Sense/Net Community 6.2 now has a REST API, based on the OData standard.

OData is a data access protocol from Microsoft released under the Microsoft Open Specification Promise, so anyone can use and implement it for any purpose, for free. The protocol was designed to provide standard CRUD access of a data source via a website. OData has been submitted to OASIS.

OData follows many of the principles of REST. Representational State Transfer (REST) is a software architectural style for distributed hypermedia systems like the World Wide Web. The term was originally defined in a doctoral dissertation (Architectural Styles and the Design of Network- based Software Architectures) about the web written by Roy Fielding. We choose OData because we did not want to reinvent the wheel, and because so many libraries (such as Kendo UI) have built in support for OData.

All interactions with an OData feed are done using URIs to address resources and standard HTTP verbs (GET, POST, PUT, DELETE, etc) to act on those resources. Therefore, any platform with a reasonably complete HTTP stack is enough to make communicating with a data service simple. That said, a number of client libraries are available which allow for development at a higher level of abstraction.

The requested resource can be any content in the Sense/Net Content Repository. The resource may be addressed with relative or absolute path. Naturally, the requesting user must have permission to the given content. The following requests are equivalent, they both request the content named “Workspaces” located under the site called “ExampleSite”:


Four HTTP methods are used in requests to specify the expected operation:

  • GET: getting one or more entities. The URL contains all request information.
  • PUT: modifying an entity. The URL defines the entity and the request's input stream contains a URL encoded JSON object. This object describes the properties and new values that will be changed on the requested entity.
  • POST: creating an entity. The URL defines the entity and the request's input stream contains a URL encoded JSON object. The URL determines the place and name of the new entity. The JSON object describes the properties and initial values of the new entity.
  • DELETE: deleting an entity. The URL determines the entity that will be deleted. Always only one entity (and its children) will be deleted.

Requests can be sent for individual properties too. A sample property request loads the Display Name of the workspace that has the URL name  “londondocumentworkspace”:'londondocumentworkspace')/.DisplayName

This returns with the following response:

  "d": {
    "DisplayName": "London Document Workspace"


OData is built on Web technologies such as HTTP, Atom Publishing Protocol (AtomPub) and JSON to provide access to information from a variety of applications, services, and stores. The protocol emerged from experiences implementing AtomPub clients and servers in a variety of products over the past several years.  OData is being used to expose and access information from a variety of sources including, but not limited to, relational databases, file systems, content management systems, such as Sense/Net.

For more informatuion on OData visit:

OData client libraries are available for a range of platforms including .NET and Silverlight through WCF Data Services, as well as AJAX, PHP, Java and the IPhone. There are libraries that support the ATOM or JSON format, and thus support OData and Sense/Net, such as Kendo UI.

For a detailed description of the capabilities of the current release, visit:

You can download Sense/Net Community 6.2 with OData support for free:

Tags: , , ,

Sense/Net Content Repository

Localization: helper tool for converting strings to resources

by Miklós Tóth 9. December 2012 18:56

We recently anounced that finally the whole Sense/Net ECMS is internationalized: all visible texts are easily localizable. All our core content types, portlets and views contain only string resource keys instead of hard-coded English texts. To achieve this, we created a couple of internal helper tools to extract hard-coded strings and replace them with string resource keys. We did not release these tools with the official community release of Sense/Net 6.2. These tools are experimental, but we have decided to publish one of them to make localizing your existing content a bit easier.

Resource converter was created to extract strings from text files of the following types:


  • content type definitions (CTDs)
  • portlet classes: portlet names
  • portlet classes: property titles and descriptions

The tool is extendable, you can create your own converter plugins that make your localization process faster. For example you may create converters for ASCX controls, page templates or any kind of text file. The tool works in the file system so you need to have your files in a local folder instead of the repository. The files need to be writable if you plan to execute the tool with the "Update source files" option enabled, so if you are using a version control system, make sure that the files are checked out and writable.


As you can see on the screenshot below, you only need to drag a folder or a single file onto the tool, choose a converter and set the language code. You may execute the tool without updating the source files first. The result is a log file containing the files the tool will modify and the generated resource xml content (copied to the clipboard, ready to paste).




This is how the Car content type definition file looks like before conversion:



After converting the CTD:



You can see that all display names and descriptions, and even the choice options are converted to resources. The generated resource content is on your clipboard ready to use: you can paste it onto a new xml file and upload it to the portal as a Resource content.

Please note that the tool was used and tested only on our core files. It is advisable to back up your files before you try to convert them with the tool.

Download (source code): Resource converter tool zip

Custom converters

To create your custom converter, you only have to implement the IResourceConverter interface in the package above, and modify the Program.cs source file to load your custom type too.


Localization | Tips and tricks

Introducing Sense/Net performance counters

by Miklós Tóth 22. June 2012 13:23

In the latest release (Sense/Net 6.1, you can get it here) there are a number of performance improvements. We decided to include a module in the product that helps these kind of development tasks.

Performance counters are well-known tools for measuring the performance of a Windows application or web site. Sense/Net provides several built-in performance counters and lets developers add their own custom performance counters. These can be used to measure the performance of a custom module by writing one line of code.

For more information about counters see this wiki article.


Announcement | Feature | Tips and tricks

IT HAS ARRIVED! The New Resource Editor!!!

by Levente Dobson 20. February 2012 18:19

Type in the resources= parameter to the address bar:

If you are an Administrator, every string resource will be highlighted:

From here you can see immediately which labels can be localized on a page and which cannot. These are also links, so


Every language appears that has been configured in the Site's CTD, with the corresponding string resource values. If no value has been given yet, the textbox is empty.

The string resources can be freely edited here in-place, and the corresponding resource content will be updated:

I hope you already see how simple it became to create a localizable page and localize it.

The builder only needs to think of a classname and a stringresourcename, and place the appropriate code in the view:

This will appear with the default values on the UI.



And what is automatically generated in the background:




Localizing javascripts

by Levente Dobson 16. September 2011 18:18

Sense/Net comes with built-in Localization features to enable users to translate their sites and/or change language settings of pages by a single click. The CMS also provides means for developers to make javascripts localizable. This comes handy when you are developing Ajax features that create Html DOM elements with labels, or simply work with labels. To access a resource class, simply include the following tag at the very top of the javascript file:

// resource MyClass

This tag must be placed in the same block as all other javascript dependency definitions, like:

// using $skin/scripts/SN/SN.Util.js
// resource MyClass

From here onwards you are able to access the provided string resource keys via the SN.Resources object as simple strings. For example:

var labelText = SN.Resources.MyClass.LabelText;

The SN.Resource.<className> object contains all the keys that are defined in the CMS for the given class, for the actual language settings.

More information:


GUI | Tips and tricks | Tutorial | Localization

Query template replacer

by János Lévai 16. September 2011 17:21

During projects it is sometimes necessary to use custom query templates. For example, if you want to gather content that was created not longer ago than one year with respect to the current date. In lucene query this is impossible to define, but you can always create your own custom template replacer. The trick here is to inherit from LucQueryTemplateReplacer. Here is an example from the product:


public class PortalLucQueryTemplateReplacer : RepositoryLucQueryTemplateReplacer
        private static readonly string[] objectNames = new[] { "currentsite""currentworkspace"
            "currentpage""currentcontent" };
        public override IEnumerable<string> ObjectNames
            get { return objectNames; }
        public override string EvaluateObjectProperty(string objectName, string propertyName)
            if (HttpContext.Current == null || PortalContext.Current == null)
                return base.EvaluateObjectProperty(objectName, propertyName);
            switch (objectName.ToLower())
                case "currentsite":
                    return GetProperty(PortalContext.Current.Site, propertyName);
                case "currentworkspace":
                    return GetProperty(PortalContext.Current.ContextWorkspace, propertyName);
                case "currentpage":
                    return GetProperty(PortalContext.Current.Page, propertyName);
                case "currentcontent":
                    return GetProperty(PortalContext.Current.ContextNode, propertyName);
                    return base.EvaluateObjectProperty(objectName, propertyName);




Tips and tricks | Tutorial | Content Query

Tutorial: Applying for a job position using Survey

by Attila Pápai 22. June 2011 15:47

Let's assume that you have an IT company and you're looking for new employees for a bigger project. You have a website powered by Sense/Net but you never created any Survey with it. This tutorial will help you to create a survey for people who applies to your job offer. At first our job is to figure out what questions we want to ask from the candidates.

Survey question planning

On the first page of the survey we gather some personal information:Your name

  • Date of birth
  • Work experience
  • Are you a student?

Since the candidate can be a student we would like to know which school is he or she attending to:

  • Name of school
  • Major
  • Expected graduation date

He or she might be graduated and have already had some work experience, right? These questions could be on the next page:

  • Have you worked in a team?
  • Have you ever led a team?
  • Programming skills

Working well in a team is a great strength especially when you're the leader of them. If the candidate was a leader, then:

  • How big was the team you led?

Finally, let's talk about money:

  • Expected gross salary

As you can see we defined five pages with different questions. These pages will be separated with Page breaks and we will specify rules to jump between these pages. For example if the candidate is a student then he or she will be asked about his or her education but not about work experience and those candidates who worked in a team will be asked about the size of their team as well in a separate page. Finally, all the candidates need to specify their expectations about salary. The following flowchart represents the survey:

Creating an empty survey

  1. Using the Explorer create an instance of Survey Content Type anywhere in your site and configure the general properties as it was describe in the Configuration section above
  2. In Explore mode click on the Manage questions action from the Settings scenario

Defining the questions

In the flowchart all the questions and page breaks are numbered by how the questions should follow each other. Every page with several questions is followed by a Page break except the last one.
In the following table you can see how the types of questions were defined:
QuestionField typeAvailable valuesOptions
Your name ShortText    
Date of birth DateTime   DateTime mode: Date
Work experience Choice less than 2 years
2-5 years
more than 5 years
Display choices: RadioButtons
Are you a student? YesNo Yes
PageBreak1 PageBreak   Rule:
Question: Are you a student?
Yes: 1
No: 2
Name of school ShortText    
Major ShortText    
Expected graduation date DateTime   DateTime mode: Date
PageBreak2 PageBreak   Rule:
Question: Are you a student?
Yes: 4
No: 4
Have you worked in a team? YesNo Yes
Have you ever led a team? YesNo Yes
Programming skills LongText    
PageBreak3 PageBreak   Rule:
Question: Have you ever led a team?
Yes: 3
No: 4
How big was the team you led? YesNo Yes
PageBreak4 PageBreak   Rule:
Expected gross salary ShortText  

You can create these questions by clicking on the Add field action and selecting the proper Field type.

Explanation of rules

  • Page1 rule - if the candidate is a student he or she will be redirected to Page #1 otherwise to Page #2
  • Page2 rule - we're dealing with a student so we don't want to ask questions about work experiences therefore he or she will be taken to Page #4
  • Page3 rule - if the candidate has already have experience in team work then we'd like to know more about it in Page #3 otherwise there's one more question left in Page #4
  • Page4 rule - since there's only one more page left we can leave this empty

Note: Page numbers are zero based. In other words, the first page is followed by the first page break, the second page is followed by the second page break and so on.


That's all folks. Easy as pie, isn't it? 
The flowchart has been created for a reason. It helps you build your survey. In a flowchart you can see how the user will be navigated between pages and with it setting up a survey is a lot easier. So it's recommended to create your own flowchart even using a pencil before you start any work in the portal.

You can read more about Survey in our wiki page:

Tags: ,


Bookmark and Share