diff --git a/NzbDrone.Core/Datastore/DbProviderFactory.cs b/NzbDrone.Core/Datastore/DbProviderFactory.cs index 5e4d18898..4e94284d3 100644 --- a/NzbDrone.Core/Datastore/DbProviderFactory.cs +++ b/NzbDrone.Core/Datastore/DbProviderFactory.cs @@ -1,8 +1,8 @@ using System; using System.Data.Common; using System.Data.SqlServerCe; -using MvcMiniProfiler; -using MvcMiniProfiler.Data; +using StackExchange.Profiling; +using StackExchange.Profiling.Data; namespace NzbDrone.Core.Datastore { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 3fbdebb49..7dedf5250 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -156,9 +156,8 @@ False ..\Libraries\Migrator.NET\Migrator.Providers.dll - - False - ..\packages\MiniProfiler.1.9\lib\net40\MvcMiniProfiler.dll + + ..\packages\MiniProfiler.2.0.2\lib\net40\MiniProfiler.dll False diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config index d9651c9ed..28e5af301 100644 --- a/NzbDrone.Core/packages.config +++ b/NzbDrone.Core/packages.config @@ -5,7 +5,7 @@ - + diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 211ae6028..74005fcb6 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -68,7 +68,8 @@ True ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - + + False ..\packages\MiniProfiler.2.0.2\lib\net40\MiniProfiler.dll @@ -549,6 +550,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/NzbDrone.Web/Views/Shared/_MINIPROFILER UPDATED Layout.cshtml b/NzbDrone.Web/Views/Shared/_MINIPROFILER UPDATED Layout.cshtml new file mode 100644 index 000000000..87b393155 --- /dev/null +++ b/NzbDrone.Web/Views/Shared/_MINIPROFILER UPDATED Layout.cshtml @@ -0,0 +1,45 @@ +@* Required so you have extention methods for client timings *@ +@using StackExchange.Profiling; + + + + @* optional (enable client timing framework) *@ + @this.InitClientTimings() + + @ViewBag.Title + + @* optional time scripts in the header *@ + @this.TimeScript("Content Site.css", + @) + @this.TimeScript("jQuery 1.5.1", + @) + @this.TimeScript("modernizr", + @) + + + +
+
+
+

My MVC Application

+
+
+ @Html.Partial("_LogOnPartial") +
+ +
+
+ @RenderBody() +
+
+
+
+ @* Make sure you've added this one line to your LAYOUT or MASTER PAGE *@ + @MiniProfiler.RenderIncludes() + + diff --git a/packages/MiniProfiler.1.9/MiniProfiler.1.9.nupkg b/packages/MiniProfiler.1.9/MiniProfiler.1.9.nupkg deleted file mode 100644 index 245ccfcdd..000000000 Binary files a/packages/MiniProfiler.1.9/MiniProfiler.1.9.nupkg and /dev/null differ diff --git a/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.dll b/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.dll deleted file mode 100644 index 98f7259bf..000000000 Binary files a/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.dll and /dev/null differ diff --git a/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.pdb b/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.pdb deleted file mode 100644 index fab3f2cdd..000000000 Binary files a/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.pdb and /dev/null differ diff --git a/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.xml b/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.xml deleted file mode 100644 index a2baacbbd..000000000 --- a/packages/MiniProfiler.1.9/lib/net40/MvcMiniProfiler.xml +++ /dev/null @@ -1,1512 +0,0 @@ - - - - MvcMiniProfiler - - - - - Takes a SqlTiming and returns a formatted SQL string, for parameter replacement, etc. - - - - - Return SQL the way you want it to look on the in the trace. Usually used to format parameters - - - Formatted SQL - - - - A single MiniProfiler can be used to represent any number of steps/levels in a call-graph, via Step() - - Totally baller. - - - - A callback for ProfiledDbConnection and family - - - - - Called when a command starts executing - - - - - - - Called when a reader finishes executing - - - - - - - - Called when a command finishes executing - - - - - - - Called when a reader is done iterating through the data - - - - - - True if the profiler instance is active - - - - - Returns all currently open commands on this connection - - - - - Starts when this profiler is instantiated. Each step will use this Stopwatch's current ticks as - their starting time. - - - - - - - - - - Creates and starts a new MiniProfiler for the root , filtering steps to . - - - - - Obsolete - used for serialization. - - - - - Walks the hierarchy contained in this profiler, starting with , and returns each Timing found. - - - - - Returns all results contained in all child steps. - - - - - Returns milliseconds based on Stopwatch's Frequency. - - - - - Starts a new MiniProfiler based on the current . This new profiler can be accessed by - - - - - - Ends the current profiling session, if one exists. - - - When true, clears the for this HttpContext, allowing profiling to - be prematurely stopped and discarded. Useful for when a specific route does not need to be profiled. - - - - - Returns an that will time the code between its creation and disposal. Use this method when you - do not wish to include the MvcMiniProfiler namespace for the extension method. - - A descriptive name for the code that is encapsulated by the resulting IDisposable's lifetime. - This step's visibility level; allows filtering when is called. - - - - Returns the css and javascript includes needed to display the MiniProfiler results UI. - - Which side of the page the profiler popup button should be displayed on (defaults to left) - Whether to show trivial timings by default (defaults to false) - Whether to show time the time with children column by default (defaults to false) - The maximum number of trace popups to show before removing the oldest (defaults to 15) - xhtml rendering mode, ensure script tag is closed ... etc - Script and link elements normally; an empty string when there is no active profiling session. - - - - Renders the current to json. - - - - - Renders the parameter to json. - - - - - Deserializes the json string parameter to a . - - - - - Create a DEEP clone of this object - - - - - - Identifies this Profiler so it may be stored/cached. - - - - - A display name for this profiling session. - - - - - When this profiler was instantiated. - - - - - Where this profiler was run. - - - - - Allows filtering of steps based on what - the steps are created with. - - - - - The first that is created and started when this profiler is instantiated. - All other s will be children of this one. - - - - - A string identifying the user/client that is profiling this request. Set - with an -implementing class to provide a custom value. - - - If this is not set manually at some point, the implementation will be used; - by default, this will be the current request's ip address. - - - - - Returns true when this MiniProfiler has been viewed by the that recorded it. - - - Allows POSTs that result in a redirect to be profiled. implementation - will keep a list of all profilers that haven't been fetched down. - - - - - Contains information about queries executed during this profiling session. - - - - - Milliseconds, to one decimal place, that this MiniProfiler ran. - - - - - Milliseconds, to one decimal place, that this MiniProfiler was executing sql. - - - - - Returns true when we have profiled queries. - - - - - Returns true when any child Timings have duplicate queries. - - - - - Returns true when or any of its are . - - - - - Returns true when all child s are . - - - - - Any Timing step with a duration less than or equal to this will be hidden by default in the UI; defaults to 2.0 ms. - - - - - Ticks since this MiniProfiler was started. - - - - - Points to the currently executing Timing. - - - - - Gets the currently running MiniProfiler for the current HttpContext; null if no MiniProfiler was ed. - - - - - Various configuration properties. - - - - - Excludes the specified assembly from the stack trace output. - - The short name of the assembly. AssemblyName.Name - - - - Excludes the specified type from the stack trace output. - - The System.Type name to exclude - - - - Excludes the specified method name from the stack trace output. - - The name of the method - - - - Make sure we can at least store profiler results to the http runtime cache. - - - - - Assemblies to exclude from the stack trace report. - - - - - Types to exclude from the stack trace report. - - - - - Methods to exclude from the stack trace report. - - - - - The max length of the stack string to report back; defaults to 120 chars. - - - - - Any Timing step with a duration less than or equal to this will be hidden by default in the UI; defaults to 2.0 ms. - - - - - Dictates if the "time with children" column is displayed by default, defaults to false. - For a per-page override you can use .RenderIncludes(showTimeWithChildren: true/false) - - - - - Dictates if trivial timings are displayed by default, defaults to false. - For a per-page override you can use .RenderIncludes(showTrivial: true/false) - - - - - Determines how many traces to show before removing the oldest; defaults to 15. - For a per-page override you can use .RenderIncludes(maxTracesToShow: 10) - - - - - Dictates on which side of the page the profiler popup button is displayed; defaults to left. - For a per-page override you can use .RenderIncludes(position: RenderPosition.Left/Right) - - - - - By default, SqlTimings will grab a stack trace to help locate where queries are being executed. - When this setting is true, no stack trace will be collected, possibly improving profiler performance. - - - - - When is called, if the current request url contains any items in this property, - no profiler will be instantiated and no results will be displayed. - Default value is { "/mini-profiler-", "/content/", "/scripts/", "/favicon.ico" }. - - - - - The path under which ALL routes are registered in, defaults to the application root. For example, "~/myDirectory/" would yield - "/myDirectory/mini-profiler-includes.js" rather than just "/mini-profiler-includes.js" - Any setting here should be in APP RELATIVE FORM, e.g. "~/myDirectory/" - - - - - Understands how to save and load MiniProfilers. Used for caching between when - a profiling session ends and results can be fetched to the client, and for showing shared, full-page results. - - - The normal profiling session life-cycle is as follows: - 1) request begins - 2) profiler is started - 3) normal page/controller/request execution - 4) profiler is stopped - 5) profiler is cached with 's implementation of - 6) request ends - 7) page is displayed and profiling results are ajax-fetched down, pulling cached results from - 's implementation of - - - - - The formatter applied to the SQL being rendered (used only for UI) - - - - - Provides user identification for a given profiling request. - - - - - Assembly version of this dank MiniProfiler. - - - - - The provider used to provider the current instance of a provider - This is also - - - - - A function that determines who can access the MiniProfiler results url. It should return true when - the request client has access, false for a 401 to be returned. HttpRequest parameter is the current request and - MiniProfiler parameter is the results that were profiled. - - - Both the HttpRequest and MiniProfiler parameters that will be passed into this function should never be null. - - - - - Execute parameterized SQL - - Number of rows affected - - - - Return a list of dynamic objects, reader is closed after the call - - - - - Execute a command that returns multiple result sets, and access each in turn - - - - - Return a typed list of objects, reader is closed after the call - - - - - Maps a query to objects - - The return type - - - - - - - - The Field we should split and read the second object from (default: id) - Number of seconds before command execution timeout - - - - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - Read the next grid of results - - - - - Wraps a database connection, allowing sql execution timings to be collected when a session is started. - - - - - Current unwrapped connection - - - - - The current profiler instance - - - - - Returns a new that wraps , - providing query execution profiling. If profiler is null, no profiling will occur. - - Your provider-specific flavor of connection, e.g. SqlConnection, OracleConnection - The currently started or null. - - - - The raw connection this is wrapping - - - - - Understands how to save MiniProfiler results to a MSSQL database, allowing more permanent storage and - querying of slow results. - - - - - Provides saving and loading s to a storage medium. - - - - - Stores under its . - - The results of a profiling session. - - Should also ensure the profiler is stored as being unviewed by its profiling . - - - - - Returns a from storage based on , which should map to . - - - Should also update that the resulting profiler has been marked as viewed by its profiling . - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Returns a new SqlServerDatabaseStorage object that will insert into the database identified by connectionString. - - - - - Saves 'profiler' to a database under its . - - - - - Returns the MiniProfiler identified by 'id' from the database or null when no MiniProfiler exists under that 'id'. - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Returns a DbConnection for your specific provider. - - - - - Returns a DbConnection already opened for execution. - - - - - Giving freshly selected collections, this method puts them in the correct - hierarchy under the 'result' MiniProfiler. - - - - - How we connect to the database used to save/load MiniProfiler results. - - - - - Formats SQL server queries with a DECLARE up top for parameter values - - - - - Formats the SQL in a SQL-Server friendly way, with DECLARE statements for the parameters up top. - - The SqlTiming to format - A formatted SQL string - - - - Wrapper for a db provider factory to enable profiling - - - - - Every provider factory must have an Instance public field - - - - - Used for db provider apis internally - - - - - Allow to re-init the provider factory. - - - - - - - proxy - - - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - proxy - - - - - BaseProfilerProvider. This providers some helper methods which provide access to - internals not otherwise available. - To use, override the , and - methods. - - - - - A provider used to create instances and maintain the current instance. - - - - - Starts a new MiniProfiler and sets it to be current. By the end of this method - should return the new MiniProfiler. - - - - - Ends the current profiling session, if one exists. - - - When true, clears the for this HttpContext, allowing profiling to - be prematurely stopped and discarded. Useful for when a specific route does not need to be profiled. - - - - - Returns the current MiniProfiler. This is used by . - - - - - - Starts a new MiniProfiler and sets it to be current. By the end of this method - should return the new MiniProfiler. - - - - - Stops the current MiniProfiler (if any is currently running). - should be called if is false - - If true, any current results will be thrown away and nothing saved - - - - Returns the current MiniProfiler. This is used by . - - - - - - Sets to be active (read to start profiling) - This should be called once a new MiniProfiler has been created. - - The profiler to set to active - If is null - - - - Stops the profiler and marks it as inactive. - - The profiler to stop - True if successful, false if Stop had previously been called on this profiler - If is null - - - - Calls to save the current - profiler using the current storage settings - - - - - - This filter can be applied globally to hook up automatic action profiling - - - - - Happens before the action starts running - - - - - Happens after the action executes - - - - - Categorizes individual steps to allow filtering. - - - - - Default level given to Timings. - - - - - Useful when profiling many items in a loop, but you don't wish to always see this detail. - - - - - Dictates on which side of the page the profiler popup button is displayed; defaults to left. - - - - - Profiler popup button is displayed on the left. - - - - - Profiler popup button is displayed on the right. - - - - - Contains helper methods that ease working with null s. - - - - - Wraps in a call and executes it, returning its result. - - The current profiling session or null. - Method to execute and profile. - The step name used to label the profiler results. - - - - - Returns an that will time the code between its creation and disposal. - - The current profiling session or null. - A descriptive name for the code that is encapsulated by the resulting IDisposable's lifetime. - This step's visibility level; allows filtering when is called. - - - - Adds 's hierarchy to this profiler's current Timing step, - allowing other threads, remote calls, etc. to be profiled and joined into this profiling session. - - - - - Returns an html-encoded string with a text-representation of ; returns "" when profiler is null. - - The current profiling session or null. - - - - Gets part of a stack trace containing only methods we care about. - - - - - Gets the current formatted and filted stack trace. - - Space separated list of methods - - - - Understands how to store a to the with absolute expiration. - - - - - The string that prefixes all keys that MiniProfilers are saved under, e.g. - "mini-profiler-ecfb0050-7ce8-4bf1-bf82-2cb38e90e31e". - - - - - Returns a new HttpRuntimeCacheStorage class that will cache MiniProfilers for the specified duration. - - - - - Saves to the HttpRuntime.Cache under a key concated with - and the parameter's . - - - - - Returns the saved identified by . Also marks the resulting - profiler to true. - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Syncs access to runtime cache when adding a new list of ids for a user. - - - - - How long to cache each for (i.e. the absolute expiration parameter of - ) - - - - - HttpContext based profiler provider. This is the default provider to use in a web context. - The current profiler is associated with a HttpContext.Current ensuring that profilers are - specific to a individual HttpRequest. - - - - - Public constructor. This also registers any UI routes needed to display results - - - - - Starts a new MiniProfiler and associates it with the current . - - - - - Ends the current profiling session, if one exists. - - - When true, clears the for this HttpContext, allowing profiling to - be prematurely stopped and discarded. Useful for when a specific route does not need to be profiled. - - - - - Makes sure 'profiler' has a Name, pulling it from route data or url. - - - - - Returns the current profiler - - - - - - Gets the currently running MiniProfiler for the current HttpContext; null if no MiniProfiler was ed. - - - - - WebRequestProfilerProvider specific configurations - - - - - Provides user identification for a given profiling request. - - - - - An individual profiling step that can contain child steps. - - - - - Rebuilds all the parent timings on deserialization calls - - - - - Offset from parent MiniProfiler's creation that this Timing was created. - - - - - Creates a new Timing named 'name' in the 'profiler's session, with 'parent' as this Timing's immediate ancestor. - - - - - Obsolete - used for serialization. - - - - - Returns this Timing's Name. - - - - - Adds arbitrary string 'value' under 'key', allowing custom properties to be stored in this Timing step. - - - - - Completes this Timing's duration and sets the MiniProfiler's Head up one level. - - - - - Add the parameter 'timing' to this Timing's Children collection. - - - Used outside this assembly for custom deserialization when creating an implementation. - - - - - Adds the parameter 'sqlTiming' to this Timing's SqlTimings collection. - - A sql statement profiling that was executed in this Timing step. - - Used outside this assembly for custom deserialization when creating an implementation. - - - - - Unique identifer for this timing; set during construction. - - - - - Text displayed when this Timing is rendered. - - - - - How long this Timing step took in ms; includes any Timings' durations. - - - - - The offset from the start of profiling. - - - - - All sub-steps that occur within this Timing step. Add new children through - - - - - Stores arbitrary key/value strings on this Timing step. Add new tuples through . - - - - - Any queries that occurred during this Timing step. - - - - - Needed for database deserialization and JSON serialization. - - - - - Which Timing this Timing is under - the duration that this step takes will be added to its parent's duration. - - This will be null for the root (initial) Timing. - - - - Gets the ellapsed milliseconds in this step without any children's durations. - - - - - Gets the aggregate ellapsed milliseconds of all SqlTimings executed in this Timing, excluding Children Timings. - - - - - Returns true when this is less than the configured - , by default 2.0 ms. - - - - - Reference to the containing profiler, allowing this Timing to affect the Head and get Stopwatch readings. - - - - - Returns true when this Timing has inner Timing steps. - - - - - Returns true if this Timing step collected sql execution timings. - - - - - Returns true if any s executed in this step are detected as duplicate statements. - - - - - Returns true when this Timing is the first one created in a MiniProfiler session. - - - - - How far away this Timing is from the Profiler's Root. - - - - - How many sql data readers were executed in this Timing step. - - - - - How many sql scalar queries were executed in this Timing step. - - - - - How many sql non-query statements were executed in this Timing step. - - - - - Categories of sql statements. - - - - - Unknown - - - - - DML statements that alter database state, e.g. INSERT, UPDATE - - - - - Statements that return a single record - - - - - Statements that iterate over a result set - - - - - Profiles a single sql execution. - - - - - Creates a new SqlTiming to profile 'command'. - - - - - Obsolete - used for serialization. - - - - - Called when command execution is finished to determine this SqlTiming's duration. - - - - - Called when database reader is closed, ending profiling for SqlTimings. - - - - - To help with display, put some space around sammiched commas - - - - - Unique identifier for this SqlTiming. - - - - - Category of sql statement executed. - - - - - The sql that was executed. - - - - - The sql that was executed. - - - - - The command string with special formatting applied based on MiniProfiler.Settings.SqlFormatter - - - - - Roughly where in the calling code that this sql was executed. - - - - - Offset from main MiniProfiler start that this sql began. - - - - - How long this sql statement took to execute. - - - - - When executing readers, how long it took to come back initially from the database, - before all records are fetched and reader is closed. - - - - - Stores any parameter names and values used by the profiled DbCommand. - - - - - Id of the Timing this statement was executed in. - - - Needed for database deserialization. - - - - - The Timing step that this sql execution occurred in. - - - - - True when other identical sql statements have been executed during this MiniProfiler session. - - - - - If the underlying command supports BindByName, this sets/clears the underlying - implementation accordingly. This is required to support OracleCommand from dapper-dot-net - - - - - Formats any SQL query with inline parameters, optionally including the value type - - - - - Creates a new Inline SQL Formatter, optionally including the parameter type info in comments beside the replaced value - - whether to include a comment after the value, indicating the type, e.g. /* @myParam DbType.Int32 */ - - - - Formats the SQL in a generic frieldly format, including the parameter type information in a comment if it was specified in the InlineFormatter constructor - - The SqlTiming to format - A formatted SQL string - - - - Returns a string representation of the parameter's value, including the type - - The parameter to get a value for - - - - - Identifies users based on ip address. - - - - - Provides functionality to identify which user is profiling a request. - - - - - Returns a string to identify the user profiling the current 'request'. - - The current HttpRequest being profiled. - - - - Returns the paramter HttpRequest's client ip address. - - - - - This is a micro-cache; suitable when the number of terms is controllable (a few hundred, for example), - and strictly append-only; you cannot change existing values. All key matches are on **REFERENCE** - equality. The type is fully thread-safe. - - - - - NOT IMPLEMENTED - will format statements with paramters in an Oracle friendly way - - - - - Does NOTHING, implement me! - - - - - Understands how to store a to a MSSQL database. - - - - - Creates needed tables. Run this once on your database. - - - Works in sql server and sqlite (with documented removals). - TODO: add indexes - - - - - Returns a new . - - - - - Stores to dbo.MiniProfilers under its ; - stores all child Timings and SqlTimings to their respective tables. - - - - - Saves parameter Timing to the dbo.MiniProfilerTimings table. - - - - - Saves parameter SqlTiming to the dbo.MiniProfilerSqlTimings table. - - - - - Saves any SqlTimingParameters used in the profiled SqlTiming to the dbo.MiniProfilerSqlTimingParameters table. - - - - - Loads the MiniProfiler identifed by 'id' from the database. - - - - - Returns a list of s that haven't been seen by . - - User identified by the current . - - - - Returns a connection to Sql Server. - - - - - Contains helper code to time sql statements. - - - - - Returns a new SqlProfiler to be used in the 'profiler' session. - - - - - Tracks when 'command' is started. - - - - - Returns all currently open commands on this connection - - - - - Finishes profiling for 'command', recording durations. - - - - - Called when 'reader' finishes its iterations and is closed. - - - - - The profiling session this SqlProfiler is part of. - - - - - Helper methods that allow operation on SqlProfilers, regardless of their instantiation. - - - - - Tracks when 'command' is started. - - - - - Finishes profiling for 'command', recording durations. - - - - - Called when 'reader' finishes its iterations and is closed. - - - - - Information about a DbParameter used in the sql statement profiled by SqlTiming. - - - - - Which SqlTiming this Parameter was executed with. - - - - - Parameter name, e.g. "@routeName" - - - - - The value submitted to the database. - - - - - System.Data.DbType, e.g. "String", "Bit" - - - - - How large the type is, e.g. for string, size could be 4000 - - - - - You can wrap your view engines with this view to enable profiling on views and partial - - - - - Wrap your view engines with this to allow profiling - - - - - - Find a partial - - - - - Find a view - - - - - Find a partial - - - - - Understands how to route and respond to MiniProfiler UI urls. - - - - - Returns this to handle . - - - - - Returns either includes' css/javascript or results' html. - - - - - Handles rendering static content files. - - - - - Handles rendering a previous MiniProfiler session, identified by its "?id=GUID" on the query. - - - - - Embedded resource contents keyed by filename. - - - - - Helper method that sets a proper 404 response code. - - - - - Try to keep everything static so we can easily be reused. - - - - - Common extension methods to use only in this project - - - - - Answers true if this String is either null or empty. - - - - - Answers true if this String is neither null or empty. - - - - - Removes trailing / characters from a path and leaves just one - - - - - Removes any leading / characters from a path - - - - - Removes any leading / characters from a path - - - - - Serializes to a json string. - - - -