New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Recipe: Form Files SaveInADAM in Your Custom WebAPI

You can save files of an item/entity to ADAM (automatic digital asset manager) using new APIs in 2sxc 9.30. Here's how.


This recipe helps you understand how to leverage the new SaveInAdam(...) command in 2sxc 9.30. It's already in use in Mobius Forms 2 - so you can learn from that, but this recipe will show you more about what you must do, incl. how to get files from the HTML-form to be submitted to your WebAPI.

Story: Showcase Directory

In this example we are creating a public directory of showcases, where people can submit websites they made with DNN. Each website has a title, link, description and some files for the logo and many screenshots. We'll assume that there is a custom form to submit new applications, and this form also has some upload fields to select a logo and up to 5 screenshots.

Overview Uploading to ADAM

To use this in your own apps, you'll do the following:

  1. Create a content-type which will hold the data - in this example we'll call it "Showcase"
  2. Create File/Hyperlink fields to store the logo and all the screenshots
  3. Design the public input Form using standard HTML / JavaScript
  4. Create the WebAPI to save the data which is submitted
  5. Test everything
  6. Publish

1. Create your Content-Type and Basic Fields

This is standard 2sxc-work and will not be explained in this recipe.

2. Defining Fields for Storing Files

ADAM works by providing files for a field. So the field "Logo" can contain one or more files, and the field "Screenshots" works the same way. To define these fields, we must:

  1. Create the field as a hyperlink-library field
  2. It is recommended that you also specify what files are allowed to be uploaded (like *.png, *.jpg) to ensure that you really only get these files. This is also done in the settings of hyperlink fields

Important: In this scenario you should NOT set content-type permissions or field permissions, as they are not checked when your code (in the C# WebAPI) adds data. These permissions are for the public REST API. If you give users write permissions, this would allow people to create data or upload files bypassing your WebAPI.

3. Design your HTML/JS Form

Now you can design the public input Form using standard HTML / JavaScript, JavaScript validators etc. to guide the user adding showcases. This is normal HTML work and not explained in this recipe.

When this form submits the data to your WebAPI, it must include the files in the submission. This is typically done by encoding the files to base64 and placing it in your json, and also including information like the file name. Here's a snippet of how it's done from the Mobius Forms 2

    Convert File Fields To Base64 for Upload

    // note: example taken from more complex code
    // this just shows the base64 encoding bits
    var deferred = $.Deferred();
    var file = e.get(0).files[0];
    if (!file)
    var reader = new FileReader();
    reader.addEventListener("load", function () {
        Encoded: reader.result,
        Field: propName
    }, false);
    return deferred.promise();

    4. Create your Save WebAPI

    Finally we'll create the WebAPI to save the data which is submitted, typically marking it as draft so the items are not shown till they are reviewed. Here's what you must do (note: you can also steal some code from Mobius Forms 2 API, but that does way more, so take only what you need):

    1. Create a new web-api file (a cshtml-file in the api folder inheriting from SxcApiController)
    2. Write code to create a dictionary-object containing all the values you want to save…
    3. …then write the code to save the new entity using App.Data.Create(…) save-new-entity code, ideally marking the new item as draft (so public users don't see it until released by an admin)
    4. Write the save files code

    The specifics of how you will do this will vary, but basically it's something along these lines:

      Example Web-API code (taken from Mobius Forms 2)

      using ...;
      public class MyFormController : SxcApiController
        [DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.Anonymous)]
        public void ProcessForm([FromBody]Dictionary<string,object> contactFormRequest)
          var typeName = "Showcase";
        var screenshotsField = "Screenshots";
        var guid = Guid.NewGuid();
          // make dictionary case-insensitive
          var values = new Dictionary<string, object>(contactFormRequest, 
          values.Add("EntityGuid", guid);
          App.Data.Create(typeName, values);
          // Save files to Adam
          var files = ((Newtonsoft.Json.Linq.JArray)contactFormRequest["Files"])
            .ToObject<IEnumerable<Dictionary<string, string>>>()
          foreach(var file in files)
            var data = Convert.FromBase64String((file["Encoded"]).Split(',')[1]);
            SaveInAdam(stream: new MemoryStream(data), fileName: file["Name"], 
              contentType: typeName, 
              guid: guid, 
              field: screenshotsField);

      5. Test

      We've included testing in this recipe, to ensure that you don't forget common issues. So we recommend you try the following things to be sure everything works:

      1. Submit some data and verify that it's draft when saving (assuming you wanted the draft-mode)
      2. Submit some data, omitting some expected files - like not passing in a logo or screenshot
      3. Submit some data with invalid files (like a .exe or a .doc when only expecting images)
      4. Submit some data with unexpected file names - like a file name containing a hash (#) character

      6. Publish

      That's it - enjoy. We hope you loved this - if yes, please leave a comment.
      Love from Switzerland,


      Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see github), an open source module for creating attractive content and DNN Apps.

      Read more posts by Daniel Mettler


      There are currently no comments, be the first to post one.

      Comment Form

      Only registered users may post comments.


      Aderson Oliveira (22)
      Alec Whittington (11)
      Alessandra Daniels (3)
      Alex Shirley (10)
      Andrew Hoefling (3)
      Andrew Nurse (30)
      Andy Tryba (1)
      Anthony Glenwright (5)
      Antonio Chagoury (28)
      Ash Prasad (37)
      Ben Schmidt (1)
      Benjamin Hermann (25)
      Benoit Sarton (9)
      Beth Firebaugh (12)
      Bill Walker (36)
      Bob Kruger (5)
      Bogdan Litescu (1)
      Brian Dukes (2)
      Brice Snow (1)
      Bruce Chapman (20)
      Bryan Andrews (1)
      cathal connolly (55)
      Charles Nurse (163)
      Chris Hammond (213)
      Chris Paterra (55)
      Clint Patterson (108)
      Cuong Dang (21)
      Daniel Bartholomew (2)
      Daniel Mettler (181)
      Daniel Valadas (48)
      Dave Buckner (2)
      David Poindexter (12)
      David Rodriguez (3)
      Dennis Shiao (1)
      Doug Howell (11)
      Erik van Ballegoij (30)
      Ernst Peter Tamminga (80)
      Francisco Perez Andres (17)
      Geoff Barlow (12)
      George Alatrash (12)
      Gifford Watkins (3)
      Gilles Le Pigocher (3)
      Ian Robinson (7)
      Israel Martinez (17)
      Jan Blomquist (2)
      Jan Jonas (3)
      Jaspreet Bhatia (1)
      Jenni Merrifield (6)
      Joe Brinkman (274)
      John Mitchell (1)
      Jon Henning (14)
      Jonathan Sheely (4)
      Jordan Coopersmith (1)
      Joseph Craig (2)
      Kan Ma (1)
      Keivan Beigi (3)
      Kelly Ford (4)
      Ken Grierson (10)
      Kevin Schreiner (6)
      Leigh Pointer (31)
      Lorraine Young (60)
      Malik Khan (1)
      Matt Rutledge (2)
      Matthias Schlomann (16)
      Mauricio Márquez (5)
      Michael Doxsey (7)
      Michael Tobisch (3)
      Michael Washington (202)
      Miguel Gatmaytan (3)
      Mike Horton (19)
      Mitchel Sellers (40)
      Nathan Rover (3)
      Navin V Nagiah (14)
      Néstor Sánchez (31)
      Nik Kalyani (14)
      Oliver Hine (1)
      Patricio F. Salinas (1)
      Patrick Ryan (1)
      Peter Donker (54)
      Philip Beadle (135)
      Philipp Becker (4)
      Richard Dumas (22)
      Robert J Collins (5)
      Roger Selwyn (8)
      Ruben Lopez (1)
      Ryan Martinez (1)
      Sacha Trauwaen (1)
      Salar Golestanian (4)
      Sanjay Mehrotra (9)
      Scott McCulloch (1)
      Scott Schlesier (11)
      Scott Wilkinson (3)
      Scott Willhite (97)
      Sebastian Leupold (80)
      Shaun Walker (237)
      Shawn Mehaffie (17)
      Stefan Cullmann (12)
      Stefan Kamphuis (12)
      Steve Fabian (31)
      Steven Fisher (1)
      Tony Henrich (3)
      Torsten Weggen (3)
      Tycho de Waard (4)
      Vicenç Masanas (27)
      Vincent Nguyen (3)
      Vitaly Kozadayev (6)
      Will Morgenweck (40)
      Will Strohl (180)
      William Severance (5)
      What is Liquid Content?
      Find Out
      What is Liquid Content?
      Find Out
      What is Liquid Content?
      Find Out