2021-07-26 09:32:08 +02:00
|
|
|
using System;
|
2021-02-22 10:09:20 +01:00
|
|
|
using System.Diagnostics;
|
2021-07-26 09:32:08 +02:00
|
|
|
using System.IO;
|
2020-07-08 15:47:26 +10:00
|
|
|
using System.Linq;
|
2021-07-26 09:32:08 +02:00
|
|
|
using System.Text;
|
2021-02-22 10:09:20 +01:00
|
|
|
using System.Threading;
|
2021-07-26 09:32:08 +02:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
|
using Umbraco.Cms.Core;
|
2021-02-18 11:06:02 +01:00
|
|
|
using Umbraco.Cms.Core.Models;
|
|
|
|
|
using Umbraco.Cms.Core.Services;
|
|
|
|
|
using Umbraco.Cms.Core.Strings;
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
// see https://github.com/Shazwazza/UmbracoScripts/tree/master/src/LoadTesting
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.TestData
|
|
|
|
|
{
|
|
|
|
|
public class LoadTestController : Controller
|
|
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
private static readonly Random s_random = new Random();
|
|
|
|
|
private static readonly object s_locko = new object();
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private static volatile int s_containerId = -1;
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private const string ContainerAlias = "LoadTestContainer";
|
|
|
|
|
private const string ContentAlias = "LoadTestContent";
|
|
|
|
|
private const int TextboxDefinitionId = -88;
|
|
|
|
|
private const int MaxCreate = 1000;
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private static readonly string s_headHtml = @"<html>
|
2020-07-08 15:47:26 +10:00
|
|
|
<head>
|
|
|
|
|
<title>LoadTest</title>
|
|
|
|
|
<style>
|
|
|
|
|
body { font-family: arial; }
|
|
|
|
|
a,a:visited { color: blue; }
|
|
|
|
|
h1 { margin: 0; padding: 0; font-size: 120%; font-weight: bold; }
|
|
|
|
|
h1 a { text-decoration: none; }
|
|
|
|
|
div.block { margin: 20px 0; }
|
|
|
|
|
ul { margin:0; }
|
|
|
|
|
div.ver { font-size: 80%; }
|
|
|
|
|
div.head { padding:0 0 10px 0; margin: 0 0 20px 0; border-bottom: 1px solid #cccccc; }
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class=""head"">
|
|
|
|
|
<h1><a href=""/LoadTest"">LoadTest</a></h1>
|
|
|
|
|
<div class=""ver"">" + System.Configuration.ConfigurationManager.AppSettings["umbracoConfigurationStatus"] + @"</div>
|
|
|
|
|
</div>
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
private const string FootHtml = @"</body>
|
|
|
|
|
</html>";
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private static readonly string s_containerTemplateText = @"
|
2021-02-22 10:09:20 +01:00
|
|
|
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
|
2020-07-08 15:47:26 +10:00
|
|
|
@{
|
|
|
|
|
Layout = null;
|
2021-07-26 09:32:08 +02:00
|
|
|
var container = Umbraco.ContentAtRoot().OfTypes(""" + ContainerAlias + @""").FirstOrDefault();
|
2020-07-08 15:47:26 +10:00
|
|
|
var contents = container.Children().ToArray();
|
|
|
|
|
var groups = contents.GroupBy(x => x.Value<string>(""origin""));
|
|
|
|
|
var id = contents.Length > 0 ? contents[0].Id : -1;
|
|
|
|
|
var wurl = Request.QueryString[""u""] == ""1"";
|
|
|
|
|
var missing = contents.Length > 0 && contents[contents.Length - 1].Id - contents[0].Id >= contents.Length;
|
|
|
|
|
}
|
2021-07-26 09:32:08 +02:00
|
|
|
" + s_headHtml + @"
|
2020-07-08 15:47:26 +10:00
|
|
|
<div class=""block"">
|
|
|
|
|
<span @Html.Raw(missing ? ""style=\""color:red;\"""" : """")>@contents.Length items</span>
|
|
|
|
|
<ul>
|
|
|
|
|
@foreach (var group in groups)
|
|
|
|
|
{
|
|
|
|
|
<li>@group.Key: @group.Count()</li>
|
|
|
|
|
}
|
|
|
|
|
</ul></div>
|
|
|
|
|
<div class=""block"">
|
|
|
|
|
@foreach (var content in contents)
|
|
|
|
|
{
|
|
|
|
|
while (content.Id > id)
|
|
|
|
|
{
|
|
|
|
|
<div style=""color:red;"">@id :: MISSING</div>
|
|
|
|
|
id++;
|
|
|
|
|
}
|
|
|
|
|
if (wurl)
|
|
|
|
|
{
|
|
|
|
|
<div>@content.Id :: @content.Name :: @content.Url</div>
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
<div>@content.Id :: @content.Name</div>
|
|
|
|
|
} id++;
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
" + FootHtml;
|
2021-07-26 09:32:08 +02:00
|
|
|
|
|
|
|
|
private readonly IContentTypeService _contentTypeService;
|
|
|
|
|
private readonly IContentService _contentService;
|
|
|
|
|
private readonly IDataTypeService _dataTypeService;
|
|
|
|
|
private readonly IFileService _fileService;
|
2020-08-06 12:59:21 +02:00
|
|
|
private readonly IShortStringHelper _shortStringHelper;
|
2021-07-26 09:32:08 +02:00
|
|
|
private readonly Cms.Core.Hosting.IHostingEnvironment _hostingEnvironment;
|
|
|
|
|
private readonly IHostApplicationLifetime _hostApplicationLifetime;
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public LoadTestController(
|
|
|
|
|
IContentTypeService contentTypeService,
|
|
|
|
|
IContentService contentService,
|
|
|
|
|
IDataTypeService dataTypeService,
|
|
|
|
|
IFileService fileService,
|
|
|
|
|
IShortStringHelper shortStringHelper,
|
|
|
|
|
Cms.Core.Hosting.IHostingEnvironment hostingEnvironment,
|
|
|
|
|
IHostApplicationLifetime hostApplicationLifetime)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
_contentTypeService = contentTypeService;
|
|
|
|
|
_contentService = contentService;
|
|
|
|
|
_dataTypeService = dataTypeService;
|
|
|
|
|
_fileService = fileService;
|
|
|
|
|
_shortStringHelper = shortStringHelper;
|
|
|
|
|
_hostingEnvironment = hostingEnvironment;
|
|
|
|
|
_hostApplicationLifetime = hostApplicationLifetime;
|
2020-07-08 15:47:26 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
|
|
|
|
|
public IActionResult Index()
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
IActionResult res = EnsureInitialize();
|
|
|
|
|
if (res != null)
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
var html = @"Welcome. You can:
|
|
|
|
|
<ul>
|
|
|
|
|
<li><a href=""/LoadTestContainer"">List existing contents</a> (u:url)</li>
|
|
|
|
|
<li><a href=""/LoadTest/Create?o=browser"">Create a content</a> (o:origin, r:restart, n:number)</li>
|
|
|
|
|
<li><a href=""/LoadTest/Clear"">Clear all contents</a></li>
|
|
|
|
|
<li><a href=""/LoadTest/Domains"">List the current domains in w3wp.exe</a></li>
|
|
|
|
|
<li><a href=""/LoadTest/Restart"">Restart the current AppDomain</a></li>
|
|
|
|
|
<li><a href=""/LoadTest/Recycle"">Recycle the AppPool</a></li>
|
|
|
|
|
<li><a href=""/LoadTest/Die"">Cause w3wp.exe to die</a></li>
|
|
|
|
|
</ul>
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
return ContentHtml(html);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private IActionResult EnsureInitialize()
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
if (s_containerId > 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
lock (s_locko)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
if (s_containerId > 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
IContentType contentType = _contentTypeService.Get(ContentAlias);
|
2020-07-08 15:47:26 +10:00
|
|
|
if (contentType == null)
|
2021-07-26 09:32:08 +02:00
|
|
|
{
|
2020-07-08 15:47:26 +10:00
|
|
|
return ContentHtml("Not installed, first you must <a href=\"/LoadTest/Install\">install</a>.");
|
2021-07-26 09:32:08 +02:00
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
IContentType containerType = _contentTypeService.Get(ContainerAlias);
|
2020-07-08 15:47:26 +10:00
|
|
|
if (containerType == null)
|
2021-07-26 09:32:08 +02:00
|
|
|
{
|
2020-07-08 15:47:26 +10:00
|
|
|
return ContentHtml("Panic! Container type is missing.");
|
2021-07-26 09:32:08 +02:00
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
IContent container = _contentService.GetPagedOfType(containerType.Id, 0, 100, out _, null).FirstOrDefault();
|
2020-07-08 15:47:26 +10:00
|
|
|
if (container == null)
|
2021-07-26 09:32:08 +02:00
|
|
|
{
|
2020-07-08 15:47:26 +10:00
|
|
|
return ContentHtml("Panic! Container is missing.");
|
2021-07-26 09:32:08 +02:00
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
s_containerId = container.Id;
|
2020-07-08 15:47:26 +10:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private IActionResult ContentHtml(string s) => Content(s_headHtml + s + FootHtml);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public IActionResult Install()
|
|
|
|
|
{
|
2020-08-06 12:59:21 +02:00
|
|
|
var contentType = new ContentType(_shortStringHelper, -1)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
Alias = ContentAlias,
|
2020-07-08 15:47:26 +10:00
|
|
|
Name = "LoadTest Content",
|
|
|
|
|
Description = "Content for LoadTest",
|
|
|
|
|
Icon = "icon-document"
|
|
|
|
|
};
|
2021-07-26 09:32:08 +02:00
|
|
|
IDataType def = _dataTypeService.GetDataType(TextboxDefinitionId);
|
2020-08-06 12:59:21 +02:00
|
|
|
contentType.AddPropertyType(new PropertyType(_shortStringHelper, def)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
|
|
|
|
Name = "Origin",
|
|
|
|
|
Alias = "origin",
|
|
|
|
|
Description = "The origin of the content.",
|
|
|
|
|
});
|
2021-07-26 09:32:08 +02:00
|
|
|
_contentTypeService.Save(contentType);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
Template containerTemplate = ImportTemplate(
|
|
|
|
|
"LoadTestContainer",
|
|
|
|
|
"LoadTestContainer",
|
|
|
|
|
s_containerTemplateText);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2020-08-06 12:59:21 +02:00
|
|
|
var containerType = new ContentType(_shortStringHelper, -1)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
Alias = ContainerAlias,
|
2020-07-08 15:47:26 +10:00
|
|
|
Name = "LoadTest Container",
|
|
|
|
|
Description = "Container for LoadTest content",
|
|
|
|
|
Icon = "icon-document",
|
|
|
|
|
AllowedAsRoot = true,
|
|
|
|
|
IsContainer = true
|
|
|
|
|
};
|
|
|
|
|
containerType.AllowedContentTypes = containerType.AllowedContentTypes.Union(new[]
|
|
|
|
|
{
|
|
|
|
|
new ContentTypeSort(new Lazy<int>(() => contentType.Id), 0, contentType.Alias),
|
|
|
|
|
});
|
|
|
|
|
containerType.AllowedTemplates = containerType.AllowedTemplates.Union(new[] { containerTemplate });
|
|
|
|
|
containerType.SetDefaultTemplate(containerTemplate);
|
2021-07-26 09:32:08 +02:00
|
|
|
_contentTypeService.Save(containerType);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
IContent content = _contentService.Create("LoadTestContainer", -1, ContainerAlias);
|
|
|
|
|
_contentService.SaveAndPublish(content);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
return ContentHtml("Installed.");
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private Template ImportTemplate(string name, string alias, string text, ITemplate master = null)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
var t = new Template(_shortStringHelper, name, alias) { Content = text };
|
|
|
|
|
if (master != null)
|
|
|
|
|
{
|
|
|
|
|
t.SetMasterTemplate(master);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_fileService.SaveTemplate(t);
|
|
|
|
|
return t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IActionResult Create(int n = 1, int r = 0, string o = null)
|
|
|
|
|
{
|
|
|
|
|
IActionResult res = EnsureInitialize();
|
|
|
|
|
if (res != null)
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r < 0)
|
|
|
|
|
{
|
|
|
|
|
r = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r > 100)
|
|
|
|
|
{
|
|
|
|
|
r = 100;
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
var restart = GetRandom(0, 100) > (100 - r);
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
if (n < 1)
|
|
|
|
|
{
|
|
|
|
|
n = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n > MaxCreate)
|
|
|
|
|
{
|
|
|
|
|
n = MaxCreate;
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
|
{
|
|
|
|
|
var name = Guid.NewGuid().ToString("N").ToUpper() + "-" + (restart ? "R" : "X") + "-" + o;
|
2021-07-26 09:32:08 +02:00
|
|
|
IContent content = _contentService.Create(name, s_containerId, ContentAlias);
|
2020-07-08 15:47:26 +10:00
|
|
|
content.SetValue("origin", o);
|
2021-07-26 09:32:08 +02:00
|
|
|
_contentService.SaveAndPublish(content);
|
2020-07-08 15:47:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (restart)
|
2021-07-26 09:32:08 +02:00
|
|
|
{
|
2020-07-08 15:47:26 +10:00
|
|
|
DoRestart();
|
2021-07-26 09:32:08 +02:00
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
return ContentHtml("Created " + n + " content"
|
|
|
|
|
+ (restart ? ", and restarted" : "")
|
|
|
|
|
+ ".");
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
private static int GetRandom(int minValue, int maxValue)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
lock (s_locko)
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
return s_random.Next(minValue, maxValue);
|
2020-07-08 15:47:26 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public IActionResult Clear()
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
IActionResult res = EnsureInitialize();
|
|
|
|
|
if (res != null)
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
IContentType contentType = _contentTypeService.Get(ContentAlias);
|
|
|
|
|
_contentService.DeleteOfType(contentType.Id);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
return ContentHtml("Cleared.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DoRestart()
|
|
|
|
|
{
|
|
|
|
|
HttpContext.User = null;
|
|
|
|
|
Thread.CurrentPrincipal = null;
|
2021-07-26 09:32:08 +02:00
|
|
|
_hostApplicationLifetime.StopApplication();
|
2020-07-08 15:47:26 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public IActionResult ColdBootRestart()
|
2021-04-26 15:40:46 +10:00
|
|
|
{
|
2021-05-21 12:32:39 +02:00
|
|
|
Directory.Delete(_hostingEnvironment.MapPathContentRoot(Path.Combine(Constants.SystemDirectories.TempData,"DistCache")), true);
|
2021-04-26 15:40:46 +10:00
|
|
|
|
|
|
|
|
DoRestart();
|
|
|
|
|
|
|
|
|
|
return Content("Cold Boot Restarted.");
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public IActionResult Restart()
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
|
|
|
|
DoRestart();
|
|
|
|
|
|
|
|
|
|
return ContentHtml("Restarted.");
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public IActionResult Die()
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
var timer = new Timer(_ => throw new Exception("die!"));
|
|
|
|
|
_ = timer.Change(100, 0);
|
2020-07-08 15:47:26 +10:00
|
|
|
|
|
|
|
|
return ContentHtml("Dying.");
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
public IActionResult Domains()
|
2020-07-08 15:47:26 +10:00
|
|
|
{
|
2021-07-26 09:32:08 +02:00
|
|
|
AppDomain currentDomain = AppDomain.CurrentDomain;
|
2020-07-08 15:47:26 +10:00
|
|
|
var currentName = currentDomain.FriendlyName;
|
|
|
|
|
var pos = currentName.IndexOf('-');
|
2021-07-26 09:32:08 +02:00
|
|
|
if (pos > 0)
|
|
|
|
|
{
|
|
|
|
|
currentName = currentName.Substring(0, pos);
|
|
|
|
|
}
|
2020-07-08 15:47:26 +10:00
|
|
|
|
2021-07-26 09:32:08 +02:00
|
|
|
var text = new StringBuilder();
|
2020-07-08 15:47:26 +10:00
|
|
|
text.Append("<div class=\"block\">Process ID: " + Process.GetCurrentProcess().Id + "</div>");
|
|
|
|
|
text.Append("<div class=\"block\">");
|
2021-07-26 09:32:08 +02:00
|
|
|
|
|
|
|
|
// TODO (V9): Commented out as I assume not available?
|
|
|
|
|
////text.Append("<div>IIS Site: " + HostingEnvironment.ApplicationHost.GetSiteName() + "</div>");
|
|
|
|
|
|
2020-07-08 15:47:26 +10:00
|
|
|
text.Append("<div>App ID: " + currentName + "</div>");
|
|
|
|
|
//text.Append("<div>AppPool: " + Zbu.WebManagement.AppPoolHelper.GetCurrentApplicationPoolName() + "</div>");
|
|
|
|
|
text.Append("</div>");
|
|
|
|
|
|
|
|
|
|
text.Append("<div class=\"block\">Domains:<ul>");
|
|
|
|
|
text.Append("<li>Not implemented.</li>");
|
|
|
|
|
/*
|
|
|
|
|
foreach (var domain in Zbu.WebManagement.AppDomainHelper.GetAppDomains().OrderBy(x => x.Id))
|
|
|
|
|
{
|
|
|
|
|
var name = domain.FriendlyName;
|
|
|
|
|
pos = name.IndexOf('-');
|
|
|
|
|
if (pos > 0) name = name.Substring(0, pos);
|
|
|
|
|
text.Append("<li style=\""
|
|
|
|
|
+ (name != currentName ? "color: #cccccc;" : "")
|
|
|
|
|
//+ (domain.Id == currentDomain.Id ? "" : "")
|
|
|
|
|
+ "\">"
|
2020-08-06 12:59:21 +02:00
|
|
|
+"[" + domain.Id + "] " + name
|
|
|
|
|
+ (domain.IsDefaultAppDomain() ? " (default)" : "")
|
2020-07-08 15:47:26 +10:00
|
|
|
+ (domain.Id == currentDomain.Id ? " (current)" : "")
|
|
|
|
|
+ "</li>");
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
text.Append("</ul></div>");
|
|
|
|
|
|
|
|
|
|
return ContentHtml(text.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|