modulecontrollervieworchardcms

Using ShellSettings in Orchard CMS to get the Current/Active Tenant's Name


I'm trying to return a view based on the currently active tenant but it isn't working. For some reason settings.Name is empty even though it should contain the name of the tenant site. Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Orchard.Themes;
using Orchard.Environment.Configuration;

namespace Speedbump.Controllers
{
    public class SpeedBumpController : Controller
    {
        [Themed]
        public ActionResult Index(ShellSettings settings)
        {
            //Initialize Variables
            string requestedURL = "";
            string finalRequestedURL = "";
            bool wasValidURL = false;

            //Grab the query string parameters and put them into variables to be used later
                //Requested URL
                requestedURL = Request.QueryString["url"];

            //Remove "http://" or "https://" from the Requested URL (if it exists)
            if (requestedURL.IndexOf("http") > -1)
            {
                finalRequestedURL = requestedURL.Replace("http://", "");
            }
            else if (requestedURL.IndexOf("https") > -1)
            {
                finalRequestedURL = requestedURL.Replace("https://", "");
            }
            else
            {
                finalRequestedURL = requestedURL;
            }

            //Create a list of strings to contain all the "valid" URLs
            var whiteList = new List<string>();

            //Add URLs to the list
            whiteList.Add("www.google.com");
            whiteList.Add("www.gmail.com");

            //Loop through each URL in the list of Valid URLs checking against the finalRequestedURL
            foreach (string validURL in whiteList)
            {
                if (finalRequestedURL == validURL)
                {
                    wasValidURL = true;
                    break;
                }
                wasValidURL = false;
            }

            //ViewBag Items
            ViewBag.wasValidURL = wasValidURL;
            ViewBag.requestedURL = finalRequestedURL;
            ViewBag.tenantName = settings.Name;

            //Return a different view depending on whether or not the url is valid
            if (wasValidURL)
            {
                if (!string.IsNullOrEmpty(settings.Name))
                {
                    return View(settings.Name + "ValidURL");
                }
                else
                {
                    return View("ValidURL");
                }

            }
            else
            {
                if (!string.IsNullOrEmpty(settings.Name))
                {
                    return View(settings.Name + "InvalidURL");
                }
                else
                {
                    return View("InvalidURL");
                }
            }
        }
    }
}

Any help would be greatly appreciated. Thank you.


Solution

  • This is not how dependency injection works. You don't inject through an action parameter, but through a constructor parameter. That's the first problem.

    The second problem is that you shouldn't inject ShellSettings, but IWorkContextAccessor, then do .GetContext().CurrentSite on it to get the site settings.

    That should answer your question, but there are also other problems in your code.

    For example, you shouldn't access the querystring. Use action parameters instead and let the framework do the model binding.

    Right after that, you're testing for "http" anywhere in the url, which will create false positives, and will also catch "https", so the else will never ever be reached. Instead, use StartsWith and "http://".

    Then, don't use Replace: if you know the URL starts with "http://", you can just use SubString(7).

    Don't hard-code your white list in code. Instead, make that configurable.

    Learn to use Contains instead of writing unnecessary loops.

    Don't use ViewBag here: there doesn't seem to be a good reason to.

    It seems like what you want to do is return redirect results, instead of views.