tags:

views:

129

answers:

1

Hi,

We have a CMS I created and it's working great but now I want to move the download of the mobile binary (installer) files to the CMS. They are currently streamed from another server.

The only solution I can see is to have an index of what files are in what folders etc as an Xml document and use Linq2Xml for retrieving the files and streaming them to the mobile browser. I really don't want to use a database for this. I was thinking of upgrading the download portals to MVC because of the built in capabilities to stream a file directly to a browser by specifying byte[], filename and mime.

Any better suggestions?

+1  A: 

Very simple to provide files directly from an MVC controller. Here's one I prepared earlier, as it were:

[RequiresAuthentication]
public ActionResult Download(int clientAreaId, string fileName)
{
    CheckRequiredFolderPermissions(clientAreaId);

    // Get the folder details for the client area
    var db = new DbDataContext();
    var clientArea = db.ClientAreas.FirstOrDefault(c => c.ID == clientAreaId);

    string decodedFileName = Server.UrlDecode(fileName);
    string virtualPath = "~/" + ConfigurationManager.AppSettings["UploadsDirectory"] + "/" + clientArea.Folder + "/" + decodedFileName;

    return new DownloadResult { VirtualPath = virtualPath, FileDownloadName = decodedFileName };
}

You might need to do a bit more work actually deciding what file to deliver (or, more likely, do something completely different), but I've just cut it down to the basics as an example that shows the interesting return bit.

DownloadResult is a customised ActionResult:

public class DownloadResult : ActionResult
{
    public DownloadResult()
    {
    }

    public DownloadResult(string virtualPath)
    {
        VirtualPath = virtualPath;
    }

    public string VirtualPath { get; set; }

    public string FileDownloadName { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (!String.IsNullOrEmpty(FileDownloadName))
        {
            context.HttpContext.Response.AddHeader("Content-type",
                                                   "application/force-download");
            context.HttpContext.Response.AddHeader("Content-disposition",
                                                   "attachment; filename=\"" + FileDownloadName + "\"");
        }

        string filePath = context.HttpContext.Server.MapPath(VirtualPath);
        context.HttpContext.Response.TransmitFile(filePath);
    }
}
Jason
Not too shabby but there is a built in function for this in MVC called FileContentResult, usage:return new FileContentResult(bytes, "x-epoc/x-sisx-app");
mhenrixon
Since I heard no complaints about the plans I'll stick to it :) It's actually already in production! Thanks for the helpful answer!!
mhenrixon
Ah, I wonder if FileContentResult is a more recent addition to the framework then? I must have acquired that bit of code whilst using one of the preview releases. Thanks for the updated info.
Jason