Using SMB Volumes in .NET Apps

Warning: Pivotal Cloud Foundry (PCF) v2.3 is no longer supported because it has reached the End of General Support (EOGS) phase as defined by the Support Lifecycle Policy. To stay up to date with the latest software and security updates, upgrade to a supported version.

This topic describes how to use Server Message Block (SMB) Volumes in a .NET Application. In this example, we create an application that reads and writes to a note.txt file within an SMB Volume share.

Prerequisites

The following is required to use SMB Volumes in your .NET App:

  • Visual Studio
  • An IaaS Account
  • Pivotal Application Service for Windows (PASW)
  • An accessible SMB Volume in an IaaS with a UNC path
  • An existing .NET Framework application
  • SMB Username
  • SMB Password

Using SMB Volumes in .NET Apps with Steeltoe

Steeltoe is a set of libraries that help your team write cloud native applications. Steeltoe contains functionality for mounting SMB Volumes. Using Steeltoe requires modifying your application code. For more information, see the Steeltoe Documentation.

If you are using Steeltoe, add the following environment variables to your Config Server Provider:

  • SMB_PATH
  • SMB_USERNAME
  • SMB_PASSWORD
Where:
  • SMB_PATH is the UNC path to your SMB.
  • SMB_USERNAME is your IaaS account username.
  • SMB_PASSWORD is is your IaaS account password.

For more information about adding environment variables to your Config Server Provider, see Config Server Provider in the Steeltoe documentation.

After adding your environment variables to your Config Server Provider, proceed to SMB Mounting.

Using SMB Volumes in .NET Apps with Your Batch Profile

If you do not want to modify your application code to include Steeltoe, you can utilize SMB Mounting without Steeltoe.

  1. Retrieve the UNC of your existing SMB share. The UNC is your machine’s FQDN.
  2. Create a .profile.bat file in your .NET app’s root directory.
  3. Use Apps Manager or the Cloud Foundry Command Line Interface (cf CLI) to set the following environment variables:
    • SMB_PATH
    • SMB_USERNAME
    • SMB_PASSWORD
  4. Add the following command to your .profile.bat file:

    net use z: %SMB_PATH% %SMB_PASSWORD% /USER:%SMB_USERNAME%
  5. Proceed to SMB Mounting.

SMB Mounting

  1. Using CF CLI or Apps Manager, add SMB_PATH, SMB_USERNAME, and SMB_PASSWORD as environment variables to your local computer or the computer you are deploying using for deploying your application.
    • If you are using SMB Volumes with your batch profile and have already added these environment variables, ignore this step.

    Note: If Visual Studio does not detect these new environment variables, restart Visual Studio.

  2. In Visual Studio, create a new file in your solution named SMBConfiguration.cs. This file is the single representation of your SMB Volume configuration and reads the connection data from the environment variables you established previously.
    // SMBConfiguration.cs
    using System;
    
    namespace NetFrameworkApp.Controllers
    {
        public class SMBConfiguration
        {
            public String GetSharePath()
            {
                return Environment.GetEnvironmentVariable("SMB_PATH");
            }
    
            public String GetUserName()
            {
                return Environment.GetEnvironmentVariable("SMB_USERNAME");
            }
    
            public String GetPassword()
            {
                return Environment.GetEnvironmentVariable("SMB_PASSWORD");
            }
        }
    }
    
  3. In Visual studio, create a new MVC Controller named NoteController. This file creates a controller endpoint that reads a the example note file. For more information about creating a controller, see Add a controller to an ASP.NET Core MVC app in the Microsoft Documentation.
  4. In the command line, add Steeltoe.Common and Steeltoe.Common.Net to your application with a Package Manager of your choice. If you are not using Steeltoe, ignore this step.
  5. Edit NoteController.cs to read from a file named note.txt, which does not exist yet but theFileMode.OpenOrCreate method creates that file. Refer to the example code snippet below, which reads the contents of the note file and stashes the note.txt content in the Viewbag. If you are not using Steeltoe, ignore the reference to Steeltoe.Common.Netin the following code snippet.
  6. // NoteController.cs
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Mvc;
    using Steeltoe.Common.Net;
    
    namespace NetFrameworkApp.Controllers
    {
        public class NoteController : Controller
        {
            SMBConfiguration configuration = new SMBConfiguration();
            public ActionResult Index()
            {
    
                var credential = new NetworkCredential(configuration.GetUserName(), configuration.GetPassword());
    
                using (var share = new WindowsNetworkFileShare(configuration.GetSharePath(), credential))
                using (var inputStream = new FileStream(Path.Combine(configuration.GetSharePath(), "note.txt"), FileMode.OpenOrCreate))
                using (var streamReader = new StreamReader(inputStream))
                {
            // Never display raw user input as HTML. Do not do this in production code.
                    ViewBag.Note = streamReader.ReadToEnd();
                }
    
    
                return View();
            }
        }
    }
    
  7. In Visual Studio, create a subdirectory in Views named Note.
  8. In Visual Studio, create a new View named Index. For more information about Views, see Views in ASP.NET Core MVC and Add a view to an ASP.NET Core MVC app in the Microsoft Documentation.
  9. In Visual Studio, create a Index.cshtml file that contains the following:
  10. // Index.cshtml
    
    @ViewBag.Note
    
    Running the application now would show an empty page with no errors.

  11. Modify the Index.cshtml file to contain a form. This form posts to a yet to be created update endpoint and also displays our note inside a text area.
  12. 
    
    // Index.cshtml
    ...
    <form action="/note/update" method="post">    
        <textarea name="note">@ViewBag.Note</textarea>    
        <div>
            <button type="submit">Update</button>
        </div>
    </form>
    
    
    
  13. Modify the NoteController.cs to have an update endpoint. This endpoint saves the data posted to the endpoint back into the note.txt. Refer to the example code snippet in the following step.
  14. Modify the NoteController.cs to include the ControllerBase class RedirectToAction method, which redirects to the index page so the user can see what was just saved. For more information about the ControllerBase class, see the Microsoft .NET API Browser Documentation.

    Refer to the example code snippet below.
  15. // NoteController.cs
    namespace NetFrameworkApp.Controllers
    {
        public class NoteController : Controller
        {
          ...
    
            [HttpPost]
            public ActionResult Update(String note)
            {
                var credential = new NetworkCredential(configuration.GetUserName(), configuration.GetPassword());
    
                using (var share = new WindowsNetworkFileShare(configuration.GetSharePath(), credential))
                using (var outputStream = new FileStream(Path.Combine(configuration.GetSharePath(), "note.txt"), FileMode.Create))
                using (var streamWriter = new StreamWriter(outputStream))
                {
                    streamWriter.Write(note);
                }
    
                return RedirectToAction("Index");
            }
        }
    }
    

Known Issue

Inability to SSH Into App Instance

Despite an SMB mapping being successfully created, trying to cf ssh into that app instance to access the created mapping results in an an unspecified path error.