Renormalize
This commit is contained in:
@@ -1,145 +1,145 @@
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Dialogs");
|
||||
|
||||
(function ($) {
|
||||
|
||||
// register AssignDomain dialog
|
||||
Umbraco.Dialogs.AssignDomain2 = base2.Base.extend({
|
||||
|
||||
_opts: null,
|
||||
|
||||
_isRepeated: function (element) {
|
||||
var inputs = $('form input.domain');
|
||||
var elementName = element.attr('name');
|
||||
var repeated = false;
|
||||
inputs.each(function() {
|
||||
var input = $(this);
|
||||
if (input.attr('name') != elementName && input.val() == element.val())
|
||||
repeated = true;
|
||||
});
|
||||
return repeated;
|
||||
},
|
||||
|
||||
// constructor
|
||||
constructor: function (opts) {
|
||||
// merge options with default
|
||||
this._opts = $.extend({
|
||||
invalidDomain: 'Invalid domain.',
|
||||
duplicateDomain: 'Domain has already been assigned.'
|
||||
}, opts);
|
||||
},
|
||||
|
||||
// public methods/variables
|
||||
|
||||
languages: null,
|
||||
language: null,
|
||||
domains: null,
|
||||
|
||||
addDomain: function () {
|
||||
this.domains.push({
|
||||
Name: "",
|
||||
Lang: ""
|
||||
});
|
||||
},
|
||||
|
||||
init: function () {
|
||||
var self = this;
|
||||
|
||||
self.domains = ko.observableArray(self._opts.domains);
|
||||
self.languages = self._opts.languages;
|
||||
self.language = self._opts.language;
|
||||
self.removeDomain = function() { self.domains.remove(this); };
|
||||
|
||||
ko.applyBindings(self);
|
||||
|
||||
$.validator.addMethod("domain", function (value, element, param) {
|
||||
// beware! encode('test') == 'test-'
|
||||
// read eg https://rt.cpan.org/Public/Bug/Display.html?id=94347
|
||||
value = punycode.encode(value);
|
||||
// that regex is best-effort and certainly not exact
|
||||
var re = /^(http[s]?:\/\/)?([-\w]+(\.[-\w]+)*)(:\d+)?(\/[-\w]*|-)?$/gi;
|
||||
var isopt = this.optional(element);
|
||||
var retest = re.test(value);
|
||||
var ret = isopt || retest;
|
||||
return ret;
|
||||
}, self._opts.invalidDomain);
|
||||
|
||||
function getDuplicateMessage(val, el) {
|
||||
var other = $(el).nextAll('input').val();
|
||||
var msg = self._opts.duplicateDomain
|
||||
if (other != "" && other != "!!!")
|
||||
msg = msg + ' (' + other + ')';
|
||||
return msg;
|
||||
}
|
||||
|
||||
$.validator.addMethod("duplicate", function (value, element, param) {
|
||||
return $(element).nextAll('input').val() == "" && !self._isRepeated($(element));
|
||||
}, getDuplicateMessage);
|
||||
|
||||
$.validator.addClassRules({
|
||||
domain: { domain: true },
|
||||
duplicate: { duplicate: true }
|
||||
});
|
||||
|
||||
$('form').validate({
|
||||
debug: true,
|
||||
focusCleanup: true,
|
||||
onkeyup: false
|
||||
});
|
||||
|
||||
$('form input.domain').on('focus', function(event) {
|
||||
if (event.type != 'focusin') return;
|
||||
$(this).nextAll('input').val("");
|
||||
});
|
||||
|
||||
// force validation *now*
|
||||
$('form').valid();
|
||||
|
||||
$('#btnSave').click(function () {
|
||||
if (!$('form').valid())
|
||||
return false;
|
||||
|
||||
var mask = $('#komask');
|
||||
var masked = mask.parent();
|
||||
mask.height(masked.height());
|
||||
mask.width(masked.width());
|
||||
mask.show();
|
||||
|
||||
var data = { nodeId: self._opts.nodeId, language: self.language ? self.language : 0, domains: self.domains };
|
||||
$.post(self._opts.restServiceLocation + 'PostSaveLanguageAndDomains', ko.toJSON(data), function (json) {
|
||||
mask.hide();
|
||||
|
||||
if (json.Valid) {
|
||||
UmbClientMgr.closeModalWindow();
|
||||
}
|
||||
else {
|
||||
var inputs = $('form input.domain');
|
||||
inputs.each(function() { $(this).nextAll('input').val(""); });
|
||||
for (var i = 0; i < json.Domains.length; i++) {
|
||||
var d = json.Domains[i];
|
||||
if (d.Duplicate)
|
||||
inputs.each(function() {
|
||||
var input = $(this);
|
||||
if (input.val() == d.Name)
|
||||
input.nextAll('input').val(d.Other ? d.Other : "!!!");
|
||||
});
|
||||
}
|
||||
$('form').valid();
|
||||
}
|
||||
})
|
||||
.fail(function (xhr, textStatus, errorThrown) {
|
||||
mask.css('opacity', 1).css('color', "#ff0000").html(xhr.responseText);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// set defaults for jQuery ajax calls
|
||||
$.ajaxSetup({
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
contentType: 'application/json; charset=utf-8'
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
Umbraco.Sys.registerNamespace("Umbraco.Dialogs");
|
||||
|
||||
(function ($) {
|
||||
|
||||
// register AssignDomain dialog
|
||||
Umbraco.Dialogs.AssignDomain2 = base2.Base.extend({
|
||||
|
||||
_opts: null,
|
||||
|
||||
_isRepeated: function (element) {
|
||||
var inputs = $('form input.domain');
|
||||
var elementName = element.attr('name');
|
||||
var repeated = false;
|
||||
inputs.each(function() {
|
||||
var input = $(this);
|
||||
if (input.attr('name') != elementName && input.val() == element.val())
|
||||
repeated = true;
|
||||
});
|
||||
return repeated;
|
||||
},
|
||||
|
||||
// constructor
|
||||
constructor: function (opts) {
|
||||
// merge options with default
|
||||
this._opts = $.extend({
|
||||
invalidDomain: 'Invalid domain.',
|
||||
duplicateDomain: 'Domain has already been assigned.'
|
||||
}, opts);
|
||||
},
|
||||
|
||||
// public methods/variables
|
||||
|
||||
languages: null,
|
||||
language: null,
|
||||
domains: null,
|
||||
|
||||
addDomain: function () {
|
||||
this.domains.push({
|
||||
Name: "",
|
||||
Lang: ""
|
||||
});
|
||||
},
|
||||
|
||||
init: function () {
|
||||
var self = this;
|
||||
|
||||
self.domains = ko.observableArray(self._opts.domains);
|
||||
self.languages = self._opts.languages;
|
||||
self.language = self._opts.language;
|
||||
self.removeDomain = function() { self.domains.remove(this); };
|
||||
|
||||
ko.applyBindings(self);
|
||||
|
||||
$.validator.addMethod("domain", function (value, element, param) {
|
||||
// beware! encode('test') == 'test-'
|
||||
// read eg https://rt.cpan.org/Public/Bug/Display.html?id=94347
|
||||
value = punycode.encode(value);
|
||||
// that regex is best-effort and certainly not exact
|
||||
var re = /^(http[s]?:\/\/)?([-\w]+(\.[-\w]+)*)(:\d+)?(\/[-\w]*|-)?$/gi;
|
||||
var isopt = this.optional(element);
|
||||
var retest = re.test(value);
|
||||
var ret = isopt || retest;
|
||||
return ret;
|
||||
}, self._opts.invalidDomain);
|
||||
|
||||
function getDuplicateMessage(val, el) {
|
||||
var other = $(el).nextAll('input').val();
|
||||
var msg = self._opts.duplicateDomain
|
||||
if (other != "" && other != "!!!")
|
||||
msg = msg + ' (' + other + ')';
|
||||
return msg;
|
||||
}
|
||||
|
||||
$.validator.addMethod("duplicate", function (value, element, param) {
|
||||
return $(element).nextAll('input').val() == "" && !self._isRepeated($(element));
|
||||
}, getDuplicateMessage);
|
||||
|
||||
$.validator.addClassRules({
|
||||
domain: { domain: true },
|
||||
duplicate: { duplicate: true }
|
||||
});
|
||||
|
||||
$('form').validate({
|
||||
debug: true,
|
||||
focusCleanup: true,
|
||||
onkeyup: false
|
||||
});
|
||||
|
||||
$('form input.domain').on('focus', function(event) {
|
||||
if (event.type != 'focusin') return;
|
||||
$(this).nextAll('input').val("");
|
||||
});
|
||||
|
||||
// force validation *now*
|
||||
$('form').valid();
|
||||
|
||||
$('#btnSave').click(function () {
|
||||
if (!$('form').valid())
|
||||
return false;
|
||||
|
||||
var mask = $('#komask');
|
||||
var masked = mask.parent();
|
||||
mask.height(masked.height());
|
||||
mask.width(masked.width());
|
||||
mask.show();
|
||||
|
||||
var data = { nodeId: self._opts.nodeId, language: self.language ? self.language : 0, domains: self.domains };
|
||||
$.post(self._opts.restServiceLocation + 'PostSaveLanguageAndDomains', ko.toJSON(data), function (json) {
|
||||
mask.hide();
|
||||
|
||||
if (json.Valid) {
|
||||
UmbClientMgr.closeModalWindow();
|
||||
}
|
||||
else {
|
||||
var inputs = $('form input.domain');
|
||||
inputs.each(function() { $(this).nextAll('input').val(""); });
|
||||
for (var i = 0; i < json.Domains.length; i++) {
|
||||
var d = json.Domains[i];
|
||||
if (d.Duplicate)
|
||||
inputs.each(function() {
|
||||
var input = $(this);
|
||||
if (input.val() == d.Name)
|
||||
input.nextAll('input').val(d.Other ? d.Other : "!!!");
|
||||
});
|
||||
}
|
||||
$('form').valid();
|
||||
}
|
||||
})
|
||||
.fail(function (xhr, textStatus, errorThrown) {
|
||||
mask.css('opacity', 1).css('color', "#ff0000").html(xhr.responseText);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// set defaults for jQuery ajax calls
|
||||
$.ajaxSetup({
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
contentType: 'application/json; charset=utf-8'
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,79 +1,79 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Xml;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for UrlHelper
|
||||
/// </summary>
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility method for checking for valid proxy urls or redirect urls to prevent Open Redirect security issues
|
||||
/// </summary>
|
||||
/// <param name="urlHelper"></param>
|
||||
/// <param name="url">The url to validate</param>
|
||||
/// <param name="callerUrl">The url of the current local domain (to ensure we can validate if the requested url is local without dependency on the request)</param>
|
||||
/// <returns>True if it's an allowed url</returns>
|
||||
public static bool ValidateProxyUrl(this UrlHelper urlHelper, string url, string callerUrl)
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.StartsWith("//"))
|
||||
return false;
|
||||
|
||||
Uri requestUri;
|
||||
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out requestUri))
|
||||
{
|
||||
if (string.IsNullOrEmpty(callerUrl) == false)
|
||||
{
|
||||
Uri localUri;
|
||||
if (Uri.TryCreate(callerUrl, UriKind.RelativeOrAbsolute, out localUri))
|
||||
{
|
||||
// check for local urls
|
||||
|
||||
//Cannot start with // since that is not a local url
|
||||
if (requestUri.OriginalString.StartsWith("//") == false
|
||||
//cannot be non-absolute and also contain the char : since that will indicate a protocol
|
||||
&& (requestUri.IsAbsoluteUri == false && requestUri.OriginalString.Contains(":") == false)
|
||||
//needs to be non-absolute or the hosts must match the current request
|
||||
&& (requestUri.IsAbsoluteUri == false || requestUri.Host == localUri.Host))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//we cannot continue if the url is not absolute
|
||||
if (requestUri.IsAbsoluteUri == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for valid proxy urls
|
||||
var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
|
||||
if (feedProxyXml != null &&
|
||||
feedProxyXml.SelectSingleNode(string.Concat("//allow[@host = '", requestUri.Host, "']")) != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Xml;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for UrlHelper
|
||||
/// </summary>
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility method for checking for valid proxy urls or redirect urls to prevent Open Redirect security issues
|
||||
/// </summary>
|
||||
/// <param name="urlHelper"></param>
|
||||
/// <param name="url">The url to validate</param>
|
||||
/// <param name="callerUrl">The url of the current local domain (to ensure we can validate if the requested url is local without dependency on the request)</param>
|
||||
/// <returns>True if it's an allowed url</returns>
|
||||
public static bool ValidateProxyUrl(this UrlHelper urlHelper, string url, string callerUrl)
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.StartsWith("//"))
|
||||
return false;
|
||||
|
||||
Uri requestUri;
|
||||
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out requestUri))
|
||||
{
|
||||
if (string.IsNullOrEmpty(callerUrl) == false)
|
||||
{
|
||||
Uri localUri;
|
||||
if (Uri.TryCreate(callerUrl, UriKind.RelativeOrAbsolute, out localUri))
|
||||
{
|
||||
// check for local urls
|
||||
|
||||
//Cannot start with // since that is not a local url
|
||||
if (requestUri.OriginalString.StartsWith("//") == false
|
||||
//cannot be non-absolute and also contain the char : since that will indicate a protocol
|
||||
&& (requestUri.IsAbsoluteUri == false && requestUri.OriginalString.Contains(":") == false)
|
||||
//needs to be non-absolute or the hosts must match the current request
|
||||
&& (requestUri.IsAbsoluteUri == false || requestUri.Host == localUri.Host))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//we cannot continue if the url is not absolute
|
||||
if (requestUri.IsAbsoluteUri == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for valid proxy urls
|
||||
var feedProxyXml = XmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
|
||||
if (feedProxyXml != null &&
|
||||
feedProxyXml.SelectSingleNode(string.Concat("//allow[@host = '", requestUri.Host, "']")) != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,193 +1,193 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Management.Instrumentation;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using ClientDependency.Core.Config;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web.WebServices;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for UrlHelper
|
||||
/// </summary>
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the base path (not including the 'action') of the MVC controller "ExamineManagementController"
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetExamineManagementServicePath(this UrlHelper url)
|
||||
{
|
||||
// TODO: Possibly remove this method, I think it's unused...
|
||||
var result = url.GetUmbracoApiService<ExamineManagementController>("GetIndexerDetails");
|
||||
return result.TrimEnd("GetIndexerDetails").EnsureEndsWith('/');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService<T>(this UrlHelper url, string actionName, RouteValueDictionary routeVals = null)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
return url.GetUmbracoApiService(actionName, typeof(T), routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Base Url (not including the action) for a Web Api service
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, string actionName)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
return url.GetUmbracoApiService<T>(actionName).TrimEnd(actionName);
|
||||
}
|
||||
|
||||
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
|
||||
if (method == null)
|
||||
{
|
||||
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
|
||||
}
|
||||
return url.GetUmbracoApiService<T>(method.Name).TrimEnd(method.Name);
|
||||
}
|
||||
|
||||
public static string GetUmbracoApiService<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
|
||||
if (method == null)
|
||||
{
|
||||
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
|
||||
}
|
||||
var parameters = Core.ExpressionHelper.GetMethodParams(methodSelector);
|
||||
var routeVals = new RouteValueDictionary(parameters);
|
||||
return url.GetUmbracoApiService<T>(method.Name, routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="apiControllerType"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
|
||||
if (apiControllerType == null) throw new ArgumentNullException(nameof(apiControllerType));
|
||||
|
||||
var area = "";
|
||||
|
||||
var apiController = Current.UmbracoApiControllerTypes
|
||||
.SingleOrDefault(x => x == apiControllerType);
|
||||
if (apiController == null)
|
||||
throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName);
|
||||
var metaData = PluginController.GetMetadata(apiController);
|
||||
if (!metaData.AreaName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//set the area to the plugin area
|
||||
area = metaData.AreaName;
|
||||
}
|
||||
return url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area, routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
return url.GetUmbracoApiService(actionName, controllerName, "", routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="area"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, string area, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullOrEmptyException(nameof(controllerName));
|
||||
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
|
||||
|
||||
if (routeVals == null)
|
||||
{
|
||||
routeVals = new RouteValueDictionary(new {httproute = "", area = area});
|
||||
}
|
||||
else
|
||||
{
|
||||
var requiredRouteVals = new RouteValueDictionary(new { httproute = "", area = area });
|
||||
requiredRouteVals.MergeLeft(routeVals);
|
||||
//copy it back now
|
||||
routeVals = requiredRouteVals;
|
||||
}
|
||||
|
||||
return url.Action(actionName, controllerName, routeVals);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for an action with a cache-busting hash appended
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUrlWithCacheBust(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
var applicationJs = url.Action(actionName, controllerName, routeVals);
|
||||
applicationJs = applicationJs + "?umb__rnd=" + GetCacheBustHash();
|
||||
return applicationJs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetCacheBustHash()
|
||||
{
|
||||
//make a hash of umbraco and client dependency version
|
||||
//in case the user bypasses the installer and just bumps the web.config or clientdep config
|
||||
|
||||
//if in debug mode, always burst the cache
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
return DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture).GenerateHash();
|
||||
}
|
||||
|
||||
var version = Current.RuntimeState.SemanticVersion.ToSemanticString();
|
||||
return $"{version}.{ClientDependencySettings.Instance.Version}".GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Management.Instrumentation;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using ClientDependency.Core.Config;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Umbraco.Web.WebServices;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for UrlHelper
|
||||
/// </summary>
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the base path (not including the 'action') of the MVC controller "ExamineManagementController"
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetExamineManagementServicePath(this UrlHelper url)
|
||||
{
|
||||
// TODO: Possibly remove this method, I think it's unused...
|
||||
var result = url.GetUmbracoApiService<ExamineManagementController>("GetIndexerDetails");
|
||||
return result.TrimEnd("GetIndexerDetails").EnsureEndsWith('/');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService<T>(this UrlHelper url, string actionName, RouteValueDictionary routeVals = null)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
return url.GetUmbracoApiService(actionName, typeof(T), routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Base Url (not including the action) for a Web Api service
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, string actionName)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
return url.GetUmbracoApiService<T>(actionName).TrimEnd(actionName);
|
||||
}
|
||||
|
||||
public static string GetUmbracoApiServiceBaseUrl<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
|
||||
if (method == null)
|
||||
{
|
||||
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
|
||||
}
|
||||
return url.GetUmbracoApiService<T>(method.Name).TrimEnd(method.Name);
|
||||
}
|
||||
|
||||
public static string GetUmbracoApiService<T>(this UrlHelper url, Expression<Func<T, object>> methodSelector)
|
||||
where T : UmbracoApiController
|
||||
{
|
||||
var method = Core.ExpressionHelper.GetMethodInfo(methodSelector);
|
||||
if (method == null)
|
||||
{
|
||||
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) + " or the result ");
|
||||
}
|
||||
var parameters = Core.ExpressionHelper.GetMethodParams(methodSelector);
|
||||
var routeVals = new RouteValueDictionary(parameters);
|
||||
return url.GetUmbracoApiService<T>(method.Name, routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="apiControllerType"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService(this UrlHelper url, string actionName, Type apiControllerType, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
|
||||
if (apiControllerType == null) throw new ArgumentNullException(nameof(apiControllerType));
|
||||
|
||||
var area = "";
|
||||
|
||||
var apiController = Current.UmbracoApiControllerTypes
|
||||
.SingleOrDefault(x => x == apiControllerType);
|
||||
if (apiController == null)
|
||||
throw new InvalidOperationException("Could not find the umbraco api controller of type " + apiControllerType.FullName);
|
||||
var metaData = PluginController.GetMetadata(apiController);
|
||||
if (!metaData.AreaName.IsNullOrWhiteSpace())
|
||||
{
|
||||
//set the area to the plugin area
|
||||
area = metaData.AreaName;
|
||||
}
|
||||
return url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area, routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
return url.GetUmbracoApiService(actionName, controllerName, "", routeVals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="area"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUmbracoApiService(this UrlHelper url, string actionName, string controllerName, string area, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullOrEmptyException(nameof(controllerName));
|
||||
if (string.IsNullOrEmpty(actionName)) throw new ArgumentNullOrEmptyException(nameof(actionName));
|
||||
|
||||
if (routeVals == null)
|
||||
{
|
||||
routeVals = new RouteValueDictionary(new {httproute = "", area = area});
|
||||
}
|
||||
else
|
||||
{
|
||||
var requiredRouteVals = new RouteValueDictionary(new { httproute = "", area = area });
|
||||
requiredRouteVals.MergeLeft(routeVals);
|
||||
//copy it back now
|
||||
routeVals = requiredRouteVals;
|
||||
}
|
||||
|
||||
return url.Action(actionName, controllerName, routeVals);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for an action with a cache-busting hash appended
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="actionName"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="routeVals"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetUrlWithCacheBust(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeVals = null)
|
||||
{
|
||||
var applicationJs = url.Action(actionName, controllerName, routeVals);
|
||||
applicationJs = applicationJs + "?umb__rnd=" + GetCacheBustHash();
|
||||
return applicationJs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetCacheBustHash()
|
||||
{
|
||||
//make a hash of umbraco and client dependency version
|
||||
//in case the user bypasses the installer and just bumps the web.config or clientdep config
|
||||
|
||||
//if in debug mode, always burst the cache
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
return DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture).GenerateHash();
|
||||
}
|
||||
|
||||
var version = Current.RuntimeState.SemanticVersion.ToSemanticString();
|
||||
return $"{version}.{ClientDependencySettings.Instance.Version}".GenerateHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,154 +1,154 @@
|
||||
using System;
|
||||
using Umbraco.Core.Security;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Script.Services;
|
||||
using System.Web.Services;
|
||||
using System.Web.UI;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using umbraco.controls.Tree;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.WebServices;
|
||||
|
||||
namespace umbraco.controls.Tree
|
||||
{
|
||||
/// <summary>
|
||||
/// Client side ajax utlities for the tree
|
||||
/// </summary>
|
||||
[ScriptService]
|
||||
[WebService]
|
||||
public class CustomTreeService : UmbracoWebService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns some info about the node such as path and id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[WebMethod]
|
||||
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
||||
public NodeInfo GetNodeInfo(int id)
|
||||
{
|
||||
Authorize();
|
||||
|
||||
//var node = new CMSNode(id);
|
||||
var node = Services.EntityService.Get(id);
|
||||
return new NodeInfo()
|
||||
{
|
||||
Id = node.Id,
|
||||
Path = node.Path,
|
||||
PathAsNames = string.Join("->",
|
||||
GetPathNames(node.Path.Split(',')
|
||||
.Select(x => int.Parse(x))
|
||||
.ToArray()))
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the node names for each id passed in
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
private string[] GetPathNames(int[] ids)
|
||||
{
|
||||
return ids
|
||||
.Where(x => x != -1)
|
||||
//.Select(x => new CMSNode(x).Text).ToArray();
|
||||
.Select(x => Services.EntityService.Get(x).Name).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a key/value object with: json, app, js as the keys
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[WebMethod]
|
||||
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
||||
public Dictionary<string, string> GetInitAppTreeData(string app, string treeType, bool showContextMenu, bool isDialog, TreeDialogModes dialogMode, string functionToCall, string nodeKey)
|
||||
{
|
||||
Authorize();
|
||||
|
||||
var treeCtl = new TreeControl()
|
||||
{
|
||||
ShowContextMenu = showContextMenu,
|
||||
IsDialog = isDialog,
|
||||
DialogMode = dialogMode,
|
||||
App = app,
|
||||
TreeType = string.IsNullOrEmpty(treeType) ? "" : treeType, //don't set the tree type unless explicitly set
|
||||
NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey,
|
||||
//StartNodeID = -1, //TODO: set this based on parameters!
|
||||
FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall
|
||||
};
|
||||
|
||||
var returnVal = new Dictionary<string, string>();
|
||||
|
||||
if (string.IsNullOrEmpty(treeType))
|
||||
{
|
||||
//if there's not tree type specified, then render out the tree as per normal with the normal
|
||||
//way of doing things
|
||||
returnVal.Add("json", treeCtl.GetJSONInitNode());
|
||||
}
|
||||
else
|
||||
{
|
||||
//since 4.5.1 has a bug in it, it ignores if the treeType is specified and will always only render
|
||||
//the whole APP not just a specific tree.
|
||||
//this is a work around for this bug until it is fixed (which should be fixed in 4.5.2
|
||||
|
||||
//get the tree that we need to render
|
||||
var tree = TreeDefinitionCollection.Instance.FindTree(treeType).CreateInstance();
|
||||
tree.ShowContextMenu = showContextMenu;
|
||||
tree.IsDialog = isDialog;
|
||||
tree.DialogMode = dialogMode;
|
||||
tree.NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey;
|
||||
tree.FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall;
|
||||
|
||||
//now render it's start node
|
||||
var xTree = new XmlTree();
|
||||
|
||||
//we're going to hijack the node name here to make it say content/media
|
||||
var node = tree.RootNode;
|
||||
if (node.Text.Equals("[FilteredContentTree]")) node.Text = Services.TextService.Localize("content");
|
||||
else if (node.Text.Equals("[FilteredMediaTree]")) node.Text = Services.TextService.Localize("media");
|
||||
xTree.Add(node);
|
||||
|
||||
returnVal.Add("json", xTree.ToString());
|
||||
}
|
||||
|
||||
returnVal.Add("app", app);
|
||||
returnVal.Add("js", treeCtl.JSCurrApp);
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
internal void Authorize()
|
||||
{
|
||||
if (ValidateCurrentUser() == false)
|
||||
throw new Exception("Client authorization failed. User is not logged in");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validates the currently logged in user and ensures they are not timed out
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool ValidateCurrentUser()
|
||||
{
|
||||
var identity = Context.GetCurrentIdentity(
|
||||
//DO NOT AUTO-AUTH UNLESS THE CURRENT HANDLER IS WEBFORMS!
|
||||
// Without this check, anything that is using this legacy API, like ui.Text will
|
||||
// automatically log the back office user in even if it is a front-end request (if there is
|
||||
// a back office user logged in. This can cause problems becaues the identity is changing mid
|
||||
// request. For example: http://issues.umbraco.org/issue/U4-4010
|
||||
HttpContext.Current.CurrentHandler is Page);
|
||||
|
||||
if (identity != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Umbraco.Core.Security;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Script.Services;
|
||||
using System.Web.Services;
|
||||
using System.Web.UI;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.cms.presentation.Trees;
|
||||
using umbraco.controls.Tree;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Security;
|
||||
using Umbraco.Web.WebServices;
|
||||
|
||||
namespace umbraco.controls.Tree
|
||||
{
|
||||
/// <summary>
|
||||
/// Client side ajax utlities for the tree
|
||||
/// </summary>
|
||||
[ScriptService]
|
||||
[WebService]
|
||||
public class CustomTreeService : UmbracoWebService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns some info about the node such as path and id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[WebMethod]
|
||||
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
||||
public NodeInfo GetNodeInfo(int id)
|
||||
{
|
||||
Authorize();
|
||||
|
||||
//var node = new CMSNode(id);
|
||||
var node = Services.EntityService.Get(id);
|
||||
return new NodeInfo()
|
||||
{
|
||||
Id = node.Id,
|
||||
Path = node.Path,
|
||||
PathAsNames = string.Join("->",
|
||||
GetPathNames(node.Path.Split(',')
|
||||
.Select(x => int.Parse(x))
|
||||
.ToArray()))
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the node names for each id passed in
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
private string[] GetPathNames(int[] ids)
|
||||
{
|
||||
return ids
|
||||
.Where(x => x != -1)
|
||||
//.Select(x => new CMSNode(x).Text).ToArray();
|
||||
.Select(x => Services.EntityService.Get(x).Name).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a key/value object with: json, app, js as the keys
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[WebMethod]
|
||||
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
||||
public Dictionary<string, string> GetInitAppTreeData(string app, string treeType, bool showContextMenu, bool isDialog, TreeDialogModes dialogMode, string functionToCall, string nodeKey)
|
||||
{
|
||||
Authorize();
|
||||
|
||||
var treeCtl = new TreeControl()
|
||||
{
|
||||
ShowContextMenu = showContextMenu,
|
||||
IsDialog = isDialog,
|
||||
DialogMode = dialogMode,
|
||||
App = app,
|
||||
TreeType = string.IsNullOrEmpty(treeType) ? "" : treeType, //don't set the tree type unless explicitly set
|
||||
NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey,
|
||||
//StartNodeID = -1, //TODO: set this based on parameters!
|
||||
FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall
|
||||
};
|
||||
|
||||
var returnVal = new Dictionary<string, string>();
|
||||
|
||||
if (string.IsNullOrEmpty(treeType))
|
||||
{
|
||||
//if there's not tree type specified, then render out the tree as per normal with the normal
|
||||
//way of doing things
|
||||
returnVal.Add("json", treeCtl.GetJSONInitNode());
|
||||
}
|
||||
else
|
||||
{
|
||||
//since 4.5.1 has a bug in it, it ignores if the treeType is specified and will always only render
|
||||
//the whole APP not just a specific tree.
|
||||
//this is a work around for this bug until it is fixed (which should be fixed in 4.5.2
|
||||
|
||||
//get the tree that we need to render
|
||||
var tree = TreeDefinitionCollection.Instance.FindTree(treeType).CreateInstance();
|
||||
tree.ShowContextMenu = showContextMenu;
|
||||
tree.IsDialog = isDialog;
|
||||
tree.DialogMode = dialogMode;
|
||||
tree.NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey;
|
||||
tree.FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall;
|
||||
|
||||
//now render it's start node
|
||||
var xTree = new XmlTree();
|
||||
|
||||
//we're going to hijack the node name here to make it say content/media
|
||||
var node = tree.RootNode;
|
||||
if (node.Text.Equals("[FilteredContentTree]")) node.Text = Services.TextService.Localize("content");
|
||||
else if (node.Text.Equals("[FilteredMediaTree]")) node.Text = Services.TextService.Localize("media");
|
||||
xTree.Add(node);
|
||||
|
||||
returnVal.Add("json", xTree.ToString());
|
||||
}
|
||||
|
||||
returnVal.Add("app", app);
|
||||
returnVal.Add("js", treeCtl.JSCurrApp);
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
internal void Authorize()
|
||||
{
|
||||
if (ValidateCurrentUser() == false)
|
||||
throw new Exception("Client authorization failed. User is not logged in");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validates the currently logged in user and ensures they are not timed out
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool ValidateCurrentUser()
|
||||
{
|
||||
var identity = Context.GetCurrentIdentity(
|
||||
//DO NOT AUTO-AUTH UNLESS THE CURRENT HANDLER IS WEBFORMS!
|
||||
// Without this check, anything that is using this legacy API, like ui.Text will
|
||||
// automatically log the back office user in even if it is a front-end request (if there is
|
||||
// a back office user logged in. This can cause problems becaues the identity is changing mid
|
||||
// request. For example: http://issues.umbraco.org/issue/U4-4010
|
||||
HttpContext.Current.CurrentHandler is Page);
|
||||
|
||||
if (identity != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.WebServices;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace umbraco.dialogs
|
||||
{
|
||||
public partial class AssignDomain2 : UmbracoEnsuredPage
|
||||
{
|
||||
protected override void OnInit(EventArgs e)
|
||||
{
|
||||
base.OnInit(e);
|
||||
|
||||
var nodeId = GetNodeId();
|
||||
CheckPathAndPermissions(nodeId, UmbracoObjectTypes.Document, ActionAssignDomain.Instance);
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
var nodeId = GetNodeId();
|
||||
var node = Services.ContentService.GetById(nodeId);
|
||||
|
||||
if (node == null)
|
||||
{
|
||||
feedback.Text = Services.TextService.Localize("assignDomain/invalidNode");
|
||||
pane_language.Visible = false;
|
||||
pane_domains.Visible = false;
|
||||
p_buttons.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pane_language.Title = Services.TextService.Localize("assignDomain/setLanguage");
|
||||
pane_domains.Title = Services.TextService.Localize("assignDomain/setDomains");
|
||||
prop_language.Text = Services.TextService.Localize("assignDomain/language");
|
||||
|
||||
var nodeDomains = Services.DomainService.GetAssignedDomains(nodeId, true).ToArray();
|
||||
var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("languages: [");
|
||||
var i = 0;
|
||||
foreach (var language in Current.Services.LocalizationService.GetAllLanguages())
|
||||
sb.AppendFormat("{0}{{ \"Id\": {1}, \"Code\": \"{2}\" }}", (i++ == 0 ? "" : ","), language.Id, language.IsoCode);
|
||||
sb.Append("]\r\n");
|
||||
|
||||
sb.AppendFormat(",language: {0}", wildcard == null ? "undefined" : wildcard.LanguageId.ToString());
|
||||
|
||||
sb.Append(",domains: [");
|
||||
i = 0;
|
||||
foreach (var domain in nodeDomains.Where(d => d.IsWildcard == false))
|
||||
sb.AppendFormat("{0}{{ \"Name\": \"{1}\", \"Lang\": \"{2}\" }}", (i++ == 0 ? "" :","), domain.DomainName, domain.LanguageId);
|
||||
sb.Append("]\r\n");
|
||||
|
||||
data.Text = sb.ToString();
|
||||
}
|
||||
|
||||
protected int GetNodeId()
|
||||
{
|
||||
int nodeId;
|
||||
if (int.TryParse(Request.QueryString["id"], out nodeId) == false)
|
||||
nodeId = -1;
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
protected string GetRestServicePath()
|
||||
{
|
||||
const string action = "ListDomains";
|
||||
var path = Url.GetUmbracoApiService<ContentController>(action);
|
||||
return path.TrimEnd(action).EnsureEndsWith('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.UI.Pages;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.WebServices;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
|
||||
namespace umbraco.dialogs
|
||||
{
|
||||
public partial class AssignDomain2 : UmbracoEnsuredPage
|
||||
{
|
||||
protected override void OnInit(EventArgs e)
|
||||
{
|
||||
base.OnInit(e);
|
||||
|
||||
var nodeId = GetNodeId();
|
||||
CheckPathAndPermissions(nodeId, UmbracoObjectTypes.Document, ActionAssignDomain.Instance);
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
var nodeId = GetNodeId();
|
||||
var node = Services.ContentService.GetById(nodeId);
|
||||
|
||||
if (node == null)
|
||||
{
|
||||
feedback.Text = Services.TextService.Localize("assignDomain/invalidNode");
|
||||
pane_language.Visible = false;
|
||||
pane_domains.Visible = false;
|
||||
p_buttons.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pane_language.Title = Services.TextService.Localize("assignDomain/setLanguage");
|
||||
pane_domains.Title = Services.TextService.Localize("assignDomain/setDomains");
|
||||
prop_language.Text = Services.TextService.Localize("assignDomain/language");
|
||||
|
||||
var nodeDomains = Services.DomainService.GetAssignedDomains(nodeId, true).ToArray();
|
||||
var wildcard = nodeDomains.FirstOrDefault(d => d.IsWildcard);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("languages: [");
|
||||
var i = 0;
|
||||
foreach (var language in Current.Services.LocalizationService.GetAllLanguages())
|
||||
sb.AppendFormat("{0}{{ \"Id\": {1}, \"Code\": \"{2}\" }}", (i++ == 0 ? "" : ","), language.Id, language.IsoCode);
|
||||
sb.Append("]\r\n");
|
||||
|
||||
sb.AppendFormat(",language: {0}", wildcard == null ? "undefined" : wildcard.LanguageId.ToString());
|
||||
|
||||
sb.Append(",domains: [");
|
||||
i = 0;
|
||||
foreach (var domain in nodeDomains.Where(d => d.IsWildcard == false))
|
||||
sb.AppendFormat("{0}{{ \"Name\": \"{1}\", \"Lang\": \"{2}\" }}", (i++ == 0 ? "" :","), domain.DomainName, domain.LanguageId);
|
||||
sb.Append("]\r\n");
|
||||
|
||||
data.Text = sb.ToString();
|
||||
}
|
||||
|
||||
protected int GetNodeId()
|
||||
{
|
||||
int nodeId;
|
||||
if (int.TryParse(Request.QueryString["id"], out nodeId) == false)
|
||||
nodeId = -1;
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
protected string GetRestServicePath()
|
||||
{
|
||||
const string action = "ListDomains";
|
||||
var path = Url.GetUmbracoApiService<ContentController>(action);
|
||||
return path.TrimEnd(action).EnsureEndsWith('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,262 +1,262 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Web.Script.Services;
|
||||
using System.Web.Services;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
namespace umbraco.presentation.webservices
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for nodeSorter
|
||||
/// </summary>
|
||||
[WebService(Namespace = "http://umbraco.org/")]
|
||||
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
|
||||
[ToolboxItem(false)]
|
||||
[ScriptService]
|
||||
public class nodeSorter : UmbracoAuthorizedWebService
|
||||
{
|
||||
[WebMethod]
|
||||
public SortNode GetNodes(string ParentId, string App)
|
||||
{
|
||||
if (AuthorizeRequest())
|
||||
{
|
||||
var nodes = new List<SortNode>();
|
||||
|
||||
// "hack for stylesheet"
|
||||
if (App == "settings")
|
||||
{
|
||||
var stylesheet = Services.FileService.GetStylesheetByName(ParentId.EnsureEndsWith(".css"));
|
||||
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + ParentId);
|
||||
|
||||
var sort = 0;
|
||||
foreach (var child in stylesheet.Properties)
|
||||
{
|
||||
nodes.Add(new SortNode(child.Name.GetHashCode(), sort, child.Name, DateTime.Now));
|
||||
sort++;
|
||||
}
|
||||
|
||||
return new SortNode()
|
||||
{
|
||||
SortNodes = nodes.ToArray()
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var asInt = int.Parse(ParentId);
|
||||
|
||||
var parent = new SortNode { Id = asInt };
|
||||
|
||||
var entityService = Services.EntityService;
|
||||
|
||||
// Root nodes?
|
||||
if (asInt == -1)
|
||||
{
|
||||
if (App == "media")
|
||||
{
|
||||
var rootMedia = entityService.GetRootEntities(UmbracoObjectTypes.Media);
|
||||
nodes.AddRange(rootMedia.Select(media => new SortNode(media.Id, media.SortOrder, media.Name, media.CreateDate)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var rootContent = entityService.GetRootEntities(UmbracoObjectTypes.Document);
|
||||
nodes.AddRange(rootContent.Select(content => new SortNode(content.Id, content.SortOrder, content.Name, content.CreateDate)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var children = entityService.GetChildren(asInt);
|
||||
nodes.AddRange(children.Select(child => new SortNode(child.Id, child.SortOrder, child.Name, child.CreateDate)));
|
||||
}
|
||||
|
||||
|
||||
parent.SortNodes = nodes.ToArray();
|
||||
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("User not logged in");
|
||||
}
|
||||
|
||||
public void UpdateSortOrder(int ParentId, string SortOrder)
|
||||
{
|
||||
UpdateSortOrder(ParentId.ToString(), SortOrder);
|
||||
}
|
||||
|
||||
[WebMethod]
|
||||
public void UpdateSortOrder(string ParentId, string SortOrder)
|
||||
{
|
||||
if (AuthorizeRequest() == false) return;
|
||||
if (SortOrder.Trim().Length <= 0) return;
|
||||
|
||||
var isContent = Context.Request.GetItemAsString("app") == "content" | Context.Request.GetItemAsString("app") == "";
|
||||
var isMedia = Context.Request.GetItemAsString("app") == "media";
|
||||
|
||||
//ensure user is authorized for the app requested
|
||||
if (isContent && AuthorizeRequest(Constants.Applications.Content.ToString()) == false) return;
|
||||
if (isMedia && AuthorizeRequest(Constants.Applications.Media.ToString()) == false) return;
|
||||
|
||||
var ids = SortOrder.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (isContent)
|
||||
{
|
||||
SortContent(ids, int.Parse(ParentId));
|
||||
}
|
||||
else if (isMedia)
|
||||
{
|
||||
SortMedia(ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
SortStylesheetProperties(ParentId, ids);
|
||||
}
|
||||
}
|
||||
|
||||
private void SortMedia(string[] ids)
|
||||
{
|
||||
var mediaService = Services.MediaService;
|
||||
var sortedMedia = new List<IMedia>();
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < ids.Length; i++)
|
||||
{
|
||||
var id = int.Parse(ids[i]);
|
||||
var m = mediaService.GetById(id);
|
||||
sortedMedia.Add(m);
|
||||
}
|
||||
|
||||
// Save Media with new sort order and update content xml in db accordingly
|
||||
var sorted = mediaService.Sort(sortedMedia);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<nodeSorter>("Could not update media sort order", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SortStylesheetProperties(string stylesheetName, string[] names)
|
||||
{
|
||||
var stylesheet = Services.FileService.GetStylesheetByName(stylesheetName.EnsureEndsWith(".css"));
|
||||
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + stylesheetName);
|
||||
|
||||
var currProps = stylesheet.Properties.ToArray();
|
||||
//remove them all first
|
||||
foreach (var prop in currProps)
|
||||
{
|
||||
stylesheet.RemoveProperty(prop.Name);
|
||||
}
|
||||
|
||||
//re-add them in the right order
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
{
|
||||
var found = currProps.Single(x => x.Name == names[i]);
|
||||
stylesheet.AddProperty(found);
|
||||
}
|
||||
|
||||
Services.FileService.SaveStylesheet(stylesheet);
|
||||
}
|
||||
|
||||
private void SortContent(string[] ids, int parentId)
|
||||
{
|
||||
var contentService = Services.ContentService;
|
||||
try
|
||||
{
|
||||
// Save content with new sort order and update db+cache accordingly
|
||||
var intIds = new List<int>();
|
||||
foreach (var stringId in ids)
|
||||
{
|
||||
int intId;
|
||||
if (int.TryParse(stringId, out intId))
|
||||
intIds.Add(intId);
|
||||
}
|
||||
var sorted = contentService.Sort(intIds.ToArray());
|
||||
|
||||
// refresh sort order on cached xml
|
||||
// but no... this is not distributed - solely relying on content service & events should be enough
|
||||
//content.Instance.SortNodes(parentId);
|
||||
|
||||
//send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here
|
||||
if (parentId > 0)
|
||||
{
|
||||
Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<nodeSorter>("Could not update content sort order", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SortNode
|
||||
{
|
||||
public SortNode()
|
||||
{
|
||||
}
|
||||
|
||||
private SortNode[] _sortNodes;
|
||||
|
||||
public SortNode[] SortNodes
|
||||
{
|
||||
get { return _sortNodes; }
|
||||
set { _sortNodes = value; }
|
||||
}
|
||||
|
||||
public int TotalNodes
|
||||
{
|
||||
get { return _sortNodes != null ? _sortNodes.Length : 0; }
|
||||
set { int test = value; }
|
||||
}
|
||||
|
||||
public SortNode(int Id, int SortOrder, string Name, DateTime CreateDate)
|
||||
{
|
||||
_id = Id;
|
||||
_sortOrder = SortOrder;
|
||||
_name = Name;
|
||||
_createDate = CreateDate;
|
||||
}
|
||||
|
||||
private DateTime _createDate;
|
||||
|
||||
public DateTime CreateDate
|
||||
{
|
||||
get { return _createDate; }
|
||||
set { _createDate = value; }
|
||||
}
|
||||
|
||||
private string _name;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
private int _sortOrder;
|
||||
|
||||
public int SortOrder
|
||||
{
|
||||
get { return _sortOrder; }
|
||||
set { _sortOrder = value; }
|
||||
}
|
||||
|
||||
private int _id;
|
||||
|
||||
public int Id
|
||||
{
|
||||
get { return _id; }
|
||||
set { _id = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Web.Script.Services;
|
||||
using System.Web.Services;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web._Legacy.Actions;
|
||||
|
||||
namespace umbraco.presentation.webservices
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for nodeSorter
|
||||
/// </summary>
|
||||
[WebService(Namespace = "http://umbraco.org/")]
|
||||
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
|
||||
[ToolboxItem(false)]
|
||||
[ScriptService]
|
||||
public class nodeSorter : UmbracoAuthorizedWebService
|
||||
{
|
||||
[WebMethod]
|
||||
public SortNode GetNodes(string ParentId, string App)
|
||||
{
|
||||
if (AuthorizeRequest())
|
||||
{
|
||||
var nodes = new List<SortNode>();
|
||||
|
||||
// "hack for stylesheet"
|
||||
if (App == "settings")
|
||||
{
|
||||
var stylesheet = Services.FileService.GetStylesheetByName(ParentId.EnsureEndsWith(".css"));
|
||||
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + ParentId);
|
||||
|
||||
var sort = 0;
|
||||
foreach (var child in stylesheet.Properties)
|
||||
{
|
||||
nodes.Add(new SortNode(child.Name.GetHashCode(), sort, child.Name, DateTime.Now));
|
||||
sort++;
|
||||
}
|
||||
|
||||
return new SortNode()
|
||||
{
|
||||
SortNodes = nodes.ToArray()
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var asInt = int.Parse(ParentId);
|
||||
|
||||
var parent = new SortNode { Id = asInt };
|
||||
|
||||
var entityService = Services.EntityService;
|
||||
|
||||
// Root nodes?
|
||||
if (asInt == -1)
|
||||
{
|
||||
if (App == "media")
|
||||
{
|
||||
var rootMedia = entityService.GetRootEntities(UmbracoObjectTypes.Media);
|
||||
nodes.AddRange(rootMedia.Select(media => new SortNode(media.Id, media.SortOrder, media.Name, media.CreateDate)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var rootContent = entityService.GetRootEntities(UmbracoObjectTypes.Document);
|
||||
nodes.AddRange(rootContent.Select(content => new SortNode(content.Id, content.SortOrder, content.Name, content.CreateDate)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var children = entityService.GetChildren(asInt);
|
||||
nodes.AddRange(children.Select(child => new SortNode(child.Id, child.SortOrder, child.Name, child.CreateDate)));
|
||||
}
|
||||
|
||||
|
||||
parent.SortNodes = nodes.ToArray();
|
||||
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("User not logged in");
|
||||
}
|
||||
|
||||
public void UpdateSortOrder(int ParentId, string SortOrder)
|
||||
{
|
||||
UpdateSortOrder(ParentId.ToString(), SortOrder);
|
||||
}
|
||||
|
||||
[WebMethod]
|
||||
public void UpdateSortOrder(string ParentId, string SortOrder)
|
||||
{
|
||||
if (AuthorizeRequest() == false) return;
|
||||
if (SortOrder.Trim().Length <= 0) return;
|
||||
|
||||
var isContent = Context.Request.GetItemAsString("app") == "content" | Context.Request.GetItemAsString("app") == "";
|
||||
var isMedia = Context.Request.GetItemAsString("app") == "media";
|
||||
|
||||
//ensure user is authorized for the app requested
|
||||
if (isContent && AuthorizeRequest(Constants.Applications.Content.ToString()) == false) return;
|
||||
if (isMedia && AuthorizeRequest(Constants.Applications.Media.ToString()) == false) return;
|
||||
|
||||
var ids = SortOrder.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (isContent)
|
||||
{
|
||||
SortContent(ids, int.Parse(ParentId));
|
||||
}
|
||||
else if (isMedia)
|
||||
{
|
||||
SortMedia(ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
SortStylesheetProperties(ParentId, ids);
|
||||
}
|
||||
}
|
||||
|
||||
private void SortMedia(string[] ids)
|
||||
{
|
||||
var mediaService = Services.MediaService;
|
||||
var sortedMedia = new List<IMedia>();
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < ids.Length; i++)
|
||||
{
|
||||
var id = int.Parse(ids[i]);
|
||||
var m = mediaService.GetById(id);
|
||||
sortedMedia.Add(m);
|
||||
}
|
||||
|
||||
// Save Media with new sort order and update content xml in db accordingly
|
||||
var sorted = mediaService.Sort(sortedMedia);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<nodeSorter>("Could not update media sort order", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SortStylesheetProperties(string stylesheetName, string[] names)
|
||||
{
|
||||
var stylesheet = Services.FileService.GetStylesheetByName(stylesheetName.EnsureEndsWith(".css"));
|
||||
if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + stylesheetName);
|
||||
|
||||
var currProps = stylesheet.Properties.ToArray();
|
||||
//remove them all first
|
||||
foreach (var prop in currProps)
|
||||
{
|
||||
stylesheet.RemoveProperty(prop.Name);
|
||||
}
|
||||
|
||||
//re-add them in the right order
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
{
|
||||
var found = currProps.Single(x => x.Name == names[i]);
|
||||
stylesheet.AddProperty(found);
|
||||
}
|
||||
|
||||
Services.FileService.SaveStylesheet(stylesheet);
|
||||
}
|
||||
|
||||
private void SortContent(string[] ids, int parentId)
|
||||
{
|
||||
var contentService = Services.ContentService;
|
||||
try
|
||||
{
|
||||
// Save content with new sort order and update db+cache accordingly
|
||||
var intIds = new List<int>();
|
||||
foreach (var stringId in ids)
|
||||
{
|
||||
int intId;
|
||||
if (int.TryParse(stringId, out intId))
|
||||
intIds.Add(intId);
|
||||
}
|
||||
var sorted = contentService.Sort(intIds.ToArray());
|
||||
|
||||
// refresh sort order on cached xml
|
||||
// but no... this is not distributed - solely relying on content service & events should be enough
|
||||
//content.Instance.SortNodes(parentId);
|
||||
|
||||
//send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here
|
||||
if (parentId > 0)
|
||||
{
|
||||
Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<nodeSorter>("Could not update content sort order", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SortNode
|
||||
{
|
||||
public SortNode()
|
||||
{
|
||||
}
|
||||
|
||||
private SortNode[] _sortNodes;
|
||||
|
||||
public SortNode[] SortNodes
|
||||
{
|
||||
get { return _sortNodes; }
|
||||
set { _sortNodes = value; }
|
||||
}
|
||||
|
||||
public int TotalNodes
|
||||
{
|
||||
get { return _sortNodes != null ? _sortNodes.Length : 0; }
|
||||
set { int test = value; }
|
||||
}
|
||||
|
||||
public SortNode(int Id, int SortOrder, string Name, DateTime CreateDate)
|
||||
{
|
||||
_id = Id;
|
||||
_sortOrder = SortOrder;
|
||||
_name = Name;
|
||||
_createDate = CreateDate;
|
||||
}
|
||||
|
||||
private DateTime _createDate;
|
||||
|
||||
public DateTime CreateDate
|
||||
{
|
||||
get { return _createDate; }
|
||||
set { _createDate = value; }
|
||||
}
|
||||
|
||||
private string _name;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
private int _sortOrder;
|
||||
|
||||
public int SortOrder
|
||||
{
|
||||
get { return _sortOrder; }
|
||||
set { _sortOrder = value; }
|
||||
}
|
||||
|
||||
private int _id;
|
||||
|
||||
public int Id
|
||||
{
|
||||
get { return _id; }
|
||||
set { _id = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user