The Ed-Fi “Classic Dashboards” are no longer supported through the Ed-Fi Alliance. You can still receive support and maintenance through the Ed-Fi vendor community. Please look at any of the vendors’ dashboard solutions on the Registry of Ed-Fi Badges or the Ed-Fi Starter Kits if you are looking for a visualization solution to use with the Ed-Fi ODS. This documentation will remain available to assist existing Classic Dashboard implementers.

Dashboard Photo Management

This is a set of recommendations for importing student, staff, and education organization (e.g., school, local education agency) photos into the Ed-Fi Dashboards. An architectural walkthrough of the core implementation is also provided.

Importing Photos

Photos can be uploaded through the Photo Management tab in the Administration section of the dashboard application. The photos should be in a ZIP file with sub-folders called "Staff", "Students", and "EdOrgs" with their respective images in each folder. The images should be named with the unique identifier of the entity and the file extension (e.g., .jpg, .png).

Photo File Format and Dimensions

Files need a valid image in a format supported by the .NET framework with the preferred formats being JPEG or PNG. For other formats supported, see the Microsoft documentation for image formats http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat.aspx. Images should have a 3:4 ratio, which is the standard aspect ratio for yearbook photos. Logos for schools and local education agencies may need to be scaled or cropped to fit a 3:4 layout.

The SharpZipLib library (http://www.icsharpcode.net/opensource/sharpziplib/) is used by the Dashboard code to support the parsing of ZIP files.

Storing Photos

The default storage implementation (EdFi.Dashboards.Resources.Photo.Implementations.Storage.FilePhotoStorage) stores the photos in the file system per the location specified by the PersistedRepositoryDirectory setting in the Web.config file.

This functionality can be easily modified through extensibility to store the files in the database, on a remote server, or any other storage location. Before using a specific implementation, permissions must be given to the application pool identity to write to the given location, and, of course, the process serving up the files will need read access. If the files are being stored in a location where the file name will be shown to the user of the application, it is highly recommended to obscure the file name through encoding or a similar process.

Photo Hosting Options

The default hosting implementation (EdFi.Dashboards.Resources.Images.ContentProvider.StudentFileSystemBasedImageContentProvider and related classes) serves up the images from the file system, and is supported by the FilePhotoStorage implementation. To enable this implementation, the configuration-specific installer needs to be modified to use these implementations in a chain instead of the static providers (see below):

protected override void RegisterIImageContentProvider(IWindsorContainer container)
{
    var assemblyTypes = typeof(Marker_EdFi_Dashboards_Resources).Assembly.GetTypes();

    var chainTypes = (from t in assemblyTypes
                        let serviceType = t.GetInterface(typeof(IImageContentProvider).Name)
                        where serviceType != null && !t.IsAbstract && t.Name.EndsWith("FileSystemBasedImageContentProvider")
                        select t);

    var chainRegistrar = new ChainOfResponsibilityRegistrar(container);
    chainRegistrar.RegisterChainOf<IImageContentProvider, NullImageProvider>(chainTypes.ToArray(), "ImageContentProviderChain");
}

For ease of developer use and initial setup, the default implementation serves up photo images from file system of the Dashboard UI web server. While this is suitable for development and even small production implementations, performance analysis shows that having a separate web server for hosting images provides the best performance. This separate web server should be routed to by a separate sub-domain with its own SSL certificate.

The web server should be configured to serve default images for people and education organizations if the requested image is not found. This can be accomplished in IIS with the URL Rewrite Module 2.0. Alternately, nginx can be used for a lightweight web server with retry rules.

The web server should request the browser cache the image for an extended period of time to reduce the number of requests handled by the server. The cache expiration should take into account that student photos are generally updated once a school year. It is further recommend to add a load balancer in front of the image hosting web server and installing the certificate there. This will facilitate adding additional web servers if needed.

The production Ed-Fi Dashboard instance should be configured to use the RemoteImageLinkProvider for the IImageLinkProvider. This provider requires a RemoteImagePath entry in the appSettings section of the Web.config for the Ed-Fi Dashboard. The value of the setting should be the base URL for image hosting. For example, "https://images.edfidashboard.org".

General Architecture

The sections below outline some of the major code elements that support the import and saving of the photos. Each interface provides a simple extension point.

  • PhotoManagementController. Controller that receives the bytes of the uploaded file chunk by chunk and assembles them to create a single file for processing. This controller calls into the PhotoManagementService.
  • PhotoManagementService. Assembles a request object with the current district Id and selected school Id with the file bytes that represent the school. This service calls into the PhotoProcessor.
  • PhotoProcessor. The conductor that calls into all of the underlying implementations for specified processing. This calls into the IPackageReader, IIdentifierProvider, IPhotoResizer, and IPhotoStorage.
  • IPackageReader. Through a chain of responsibility, this represents multiple parsers that attempt to parse the uploaded file. If parsed successfully, a collection of OriginalPhoto instances are returned.
public abstract class OriginalPhoto
{
    public byte[] Photo { get; set; }

    /// <summary>
    /// Gets the uniquely identifying information about the photo.
    /// </summary>
    public abstract string FriendlyName { get; }
}
public class UniqueOriginalPhoto : OriginalPhoto
{
    public long Id { get; set; }
    public IdentifierType IdentifierType { get; set; }

    public override string FriendlyName
    {
        get { return string.Format("{0} - {1}", Id, IdentifierType); }
    }
}
  • IIdentifierProvider. Through another chain of responsibility, this represents multiple lookup providers that attempt to find the unique Ids for each entity that has a photo. If parsed successfully, an Identifier instance is returned.
public class Identifier
{
    public int Id { get; set; }
    public IdentifierType Type { get; set; }
}
public enum IdentifierType
{
    Student,
    Staff,
    School,
    District
}
  • IPhotoResizer. Resizes the original photo into 3 separate sizes (i.e., list, thumbnail, and profile) for the header.
  • IPhotoStorage. Stores each version of the photo.

Contents