diff --git a/Jenkins.Net/IJenkinsClient.cs b/Jenkins.Net/IJenkinsClient.cs
index a1b17dc..f8a4596 100644
--- a/Jenkins.Net/IJenkinsClient.cs
+++ b/Jenkins.Net/IJenkinsClient.cs
@@ -32,6 +32,11 @@ public interface IJenkinsClient
///
JenkinsClientArtifacts Artifacts {get;}
+ ///
+ /// Group of methods for interacting with Jenkins Views.
+ ///
+ JenkinsClientViews Views { get; }
+
///
/// Updates the security Crumb attached to this client.
///
diff --git a/Jenkins.Net/Internal/Commands/ViewCreateCommand.cs b/Jenkins.Net/Internal/Commands/ViewCreateCommand.cs
new file mode 100644
index 0000000..0763a17
--- /dev/null
+++ b/Jenkins.Net/Internal/Commands/ViewCreateCommand.cs
@@ -0,0 +1,42 @@
+using JenkinsNET.Models;
+using System;
+
+namespace JenkinsNET.Internal.Commands
+{
+ internal class ViewCreateCommand : JenkinsHttpCommand
+ {
+ public ViewCreateCommand(IJenkinsContext context, string viewName, JenkinsProject view)
+ {
+ if (context == null)
+ throw new ArgumentNullException(nameof(context));
+
+ if (string.IsNullOrEmpty(viewName))
+ throw new ArgumentException("Value cannot be empty!", nameof(viewName));
+
+ if (view == null)
+ throw new ArgumentNullException(nameof(view));
+
+ Url = NetPath.Combine(context.BaseUrl, "createView")
+ + NetPath.Query(new { name = viewName });
+
+ UserName = context.UserName;
+ Password = context.ApiToken;
+ Crumb = context.Crumb;
+
+ OnWrite = request =>
+ {
+ request.Method = "POST";
+ request.ContentType = "application/xml";
+ WriteXml(request, view.Node);
+ };
+
+#if NET_ASYNC
+ OnWriteAsync = async (request, token) => {
+ request.Method = "POST";
+ request.ContentType = "application/xml";
+ await WriteXmlAsync(request, view.Node, token);
+ };
+#endif
+ }
+ }
+}
\ No newline at end of file
diff --git a/Jenkins.Net/JenkinsClient.cs b/Jenkins.Net/JenkinsClient.cs
index 86fd421..215b35a 100644
--- a/Jenkins.Net/JenkinsClient.cs
+++ b/Jenkins.Net/JenkinsClient.cs
@@ -65,6 +65,10 @@ public string Password {
///
public JenkinsClientArtifacts Artifacts {get;}
+ ///
+ /// Group of methods for interacting with Jenkins Views.
+ ///
+ public JenkinsClientViews Views { get; }
///
/// Creates a new Jenkins Client.
@@ -75,6 +79,7 @@ public JenkinsClient()
Builds = new JenkinsClientBuilds(this);
Queue = new JenkinsClientQueue(this);
Artifacts = new JenkinsClientArtifacts(this);
+ Views = new JenkinsClientViews(this);
}
///
diff --git a/Jenkins.Net/JenkinsClientViews.cs b/Jenkins.Net/JenkinsClientViews.cs
new file mode 100644
index 0000000..ff647f6
--- /dev/null
+++ b/Jenkins.Net/JenkinsClientViews.cs
@@ -0,0 +1,64 @@
+using JenkinsNET.Exceptions;
+using JenkinsNET.Internal.Commands;
+using JenkinsNET.Models;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace JenkinsNET
+{
+ ///
+ /// A collection of methods used for interacting with Jenkins Views API.
+ ///
+ ///
+ /// Used internally by
+ ///
+ public sealed class JenkinsClientViews
+ {
+ private readonly IJenkinsContext _context;
+
+ internal JenkinsClientViews(IJenkinsContext context)
+ {
+ _context = context;
+ }
+
+ ///
+ /// Creates a new View in Jenkins.
+ ///
+ /// The name of the View to create.
+ /// The description of the Job to create.
+ ///
+ public void Create(string viewName, JenkinsProject view)
+ {
+ try
+ {
+ new ViewCreateCommand(_context, viewName, view).Run();
+ }
+ catch (Exception error)
+ {
+ throw new JenkinsNetException($"Failed to create Jenkins View '{viewName}'!", error);
+ }
+ }
+
+#if NET_ASYNC
+ ///
+ /// Creates a new View in Jenkins asynchronously.
+ ///
+ /// The name of the View to create.
+ /// The description of the View to create.
+ /// An optional token for aborting the request.
+ ///
+ public async Task CreateAsync(string viewName, JenkinsProject view, CancellationToken token = default)
+ {
+ try
+ {
+ await new ViewCreateCommand(_context, viewName, view).RunAsync(token);
+ }
+ catch (Exception error)
+ {
+ throw new JenkinsNetException($"Failed to create Jenkins Job '{viewName}'!", error);
+ }
+ }
+#endif
+ }
+}