Skip to main content
Home  › ... Razor

Reuse Templates and Code Tutorials

Tutorial HomeReuse

Reuse code with .cs files (new in 2sxc 10.01)

Starting with 2sxc 10.01 CreateInstance() can also be used with .cs files, from both razor pages as well as WebApi controllers. This allows you to create shared code which can be used in Razor and WebApi controllers.

Using shared library of simple functions

The example takes a cs file FunctionsBasic.cs with shared code in a class FunctionsBasic. This example uses a simple C# class, so the code only has what's in it.

Output

Hello from FunctionsBasic: Hello from shared functions!
@{
  var lib = CreateInstance("FunctionsBasic.cs");
}
<div>Hello from FunctionsBasic: @lib.SayHello()</div>

Source Code of FunctionsBasic.cs

// Important notes: 
// - This class should have the same name as the file it's in
public class FunctionsBasic {

  public string SayHello() {
    return "Hello from shared functions!";
  }
}

// Example for another class in the same file
public class Second {
  public string SayHello() {
    return "Hello from the second class!";
  }
}

Using a different Class from a library files

The example takes a cs file with shared code, but gets the class Second.

Output

Hello from FunctionsBasic: Hello from the second class!
@{
  var lib2 = CreateInstance("FunctionsBasic.cs", name: "Second");
}
<div>Hello from FunctionsBasic: @lib2.SayHello()</div>

Source Code of FunctionsBasic.cs

// Important notes: 
// - This class should have the same name as the file it's in
public class FunctionsBasic {

  public string SayHello() {
    return "Hello from shared functions!";
  }
}

// Example for another class in the same file
public class Second {
  public string SayHello() {
    return "Hello from the second class!";
  }
}

Using shared code with context

Often you may need context - like the Dnn or App objects. We made this easy by defining a base class you can inherit from, called Custom.Hybrid.Code14 (previously ToSic.Sxc.Dnn.DynamicCode). If you use that as your base-class, all existing context is automatically attached, allowing you to access variables like App.

Output

@{
  var powerLib = CreateInstance("FunctionsWithContext.cs");
}
<div>
  <img loading="lazy" src='@powerLib.QrPath("https://2sxc.org")' width="75px">
</div>

Source Code of FunctionsWithContext.cs

// Important notes: 
// - This class should have the same name as the file it's in
// - This inherits from Custom.Hybrid.Code14
//   which will automatically provide the common objects like App, Dnn etc.
//   from the current context to use in your code
public class FunctionsWithContext: Custom.Hybrid.Code14 {

  public string QrPath(string link) {
        // path to qr-code generator
        var qrPath = "//api.qrserver.com/v1/create-qr-code/?color={foreground}&bgcolor={background}&qzone=0&margin=0&size={dim}x{dim}&ecc={ecc}&data={link}"
            .Replace("{foreground}", App.Settings.QrForegroundColor.Replace("#", ""))
            .Replace("{background}", App.Settings.QrBackgroundColor.Replace("#", ""))
            .Replace("{dim}", App.Settings.QrDimension.ToString())
            .Replace("{ecc}", App.Settings.QrEcc)
            .Replace("{link}", link)
            ;
        return qrPath;
    }

}

Using shared libraries in WebApi Controllers

The mechanism above also works in WebApi Controllers (if you have 2sxc 10.01+). Note that specifically in WebApi you can only use CreateInstance(...) for .cs files.

Output

Click to see the result of a WebApi call with the shared code:

<p>
  Click to see the result of a WebApi call with the shared code:
  <button type="button" class="btn btn-primary" onclick="callApiWithSharedCode(this)">
    Call WebApi
  </button>
</p>
  
@* 2sxclint:disable:no-inline-script *@
<script>
  function callApiWithSharedCode(context) {
    $2sxc(context).webApi.fetchJson('app/auto/reuse/api/sharedcode/hello')
      .then(function (results) {
        console.log(results);
        alert(results);
      });
    return false;
  }
</script>

Source Code of api/SharedCodeController.cs

// Add namespaces for security check in Oqtane & DNN despite differences in .net core/.net Framework
// If you only target one platform, you can remove the parts you don't need
#if NETCOREAPP
using Microsoft.AspNetCore.Authorization; // .net core [AllowAnonymous] & [Authorize]
using Microsoft.AspNetCore.Mvc;           // .net core [HttpGet] / [HttpPost] etc.
#else
using System.Web.Http;                    // .net 4.5 [AllowAnonymous] / [HttpGet]
using DotNetNuke.Web.Api;                 // [DnnModuleAuthorize] & [ValidateAntiForgeryToken]
#endif

[AllowAnonymous]                          // all commands can be accessed without a login
[ValidateAntiForgeryToken]                // protects API from users not on your site (CSRF protection)
public class SharedCodeController : Custom.Hybrid.Api14 // see https://r.2sxc.org/CustomWebApi
{
  [HttpGet]
  [AllowAnonymous]
  public string Hello()
  {
    var shared = CreateInstance("../FunctionsBasic.cs");
    return shared.SayHello();
  }
}

// The next line is for 2sxc-internal quality checks, you can ignore this
// 2sxclint:disable:no-dnn-namespaces - 2sxclint:disable:no-web-namespace

Source Code of FunctionsBasic.cs

// Important notes: 
// - This class should have the same name as the file it's in
public class FunctionsBasic {

  public string SayHello() {
    return "Hello from shared functions!";
  }
}

// Example for another class in the same file
public class Second {
  public string SayHello() {
    return "Hello from the second class!";
  }
}

Source Code of this file

Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

@inherits Custom.Hybrid.Razor14
@using ToSic.Razor.Blade;
<!-- unimportant stuff, hidden -->


@* TODO: @2dk - remove unnecesary HRs, correct indentations *@


<div @Sys.PageParts.InfoWrapper()>
  @Html.Partial("../shared/DefaultInfoSection.cshtml")
  <div @Sys.PageParts.InfoIntro()>
      <h2>Reuse code with .cs files (new in 2sxc 10.01)</h2>
      <p>
        Starting with 2sxc 10.01 <code>CreateInstance()</code> can also be used with .cs files,
        from both razor pages as well as WebApi controllers.
        This allows you to create shared code which can be used in Razor and WebApi controllers.
      </p>
    </div>
  </div>


<h2>Using shared library of simple functions</h2>
The example takes a cs file... <!-- unimportant stuff, hidden -->

  @{
    var lib = CreateInstance("FunctionsBasic.cs");
  }
  <div>Hello from FunctionsBasic: @lib.SayHello()</div>



<h2>Using a different Class from a library files</h2>
The example takes a cs file with shared... <!-- unimportant stuff, hidden -->

  @{
    var lib2 = CreateInstance("FunctionsBasic.cs", name: "Second");
  }
  <div>Hello from FunctionsBasic: @lib2.SayHello()</div>



<h2>Using shared code with context</h2>
Often you may need context - like the... <!-- unimportant stuff, hidden -->

  @{
    var powerLib = CreateInstance("FunctionsWithContext.cs");
  }
  <div>
    <img loading="lazy" src='@powerLib.QrPath("https://2sxc.org")' width="75px">
  </div>



<!-- unimportant stuff, hidden -->

  <p>
    Click to see the result of a WebApi call with the shared code:
    <button type="button" class="btn btn-primary" onclick="callApiWithSharedCode(this)">
      Call WebApi
    </button>
  </p>
  
  @* 2sxclint:disable:no-inline-script *@
  <script>
    function callApiWithSharedCode(context) {
      $2sxc(context).webApi.fetchJson('app/auto/reuse/api/sharedcode/hello')
        .then(function (results) {
          console.log(results);
          alert(results);
        });
      return false;
    }
  </script>



@* Footer *@
@Html.Partial("../Shared/Layout/FooterWithSource.cshtml", new { Sys = Sys })