一、AGS server admin api 介紹
1.1什么是admin api
AGS Server Admin api 官方的稱呼是 AGS Server administrator api, 通過這名字也可以猜出該api的作用,通過該api可以管理arcgis server。ArcGIS Server常見的管理功能有安裝配置、server 日志、站點的監測配置等,詳細的Server管理內容,可以參考ArcGIS Server的官方幫助的管理arcgis Server。
1.2 admin api 作用
通常ArcGIS Server的管理是通過在manager頁面中進行的。但是arcgis server manager所呈現的管理功能其后台也是通過調用admin api。也就是說manager頁面的管理是esri通過調用admin api開發出來的web 端的server管理工具。有些server的管理工具在manager找不到,但是可以從admin中頁面中獲得。
通過調研admin api 完全可以開發一個管理工具來替代manager,從中根據自己的業務需求定制所需要的功能。一句話概括就是使用admin api可以二次開發出server管理系統。目前使用admin api開發比較好的產品為,捷泰天域開發的oneMap,其就是一個通過調用admin api開發出的server管理工具,通過oneMap可以方便的實現manger 已有的功能,也可以實現諸如日志統計分析、管理數據的統計,並將統計信息已圖表的形式呈現這種manger沒有呈現的功能。
如果用戶不想基於admin api 開發新的server管理系統,而想對ArcGIS server manager中的內容進行更改,可以直接進行admin頁面中,鏈接格式如下:http://localhost:6080/arcgis/admin/login,可以在這里面對manager進行管理。
Tips: 10.2 server的admin 中添加了站點的備份與恢復
1.3 admin api的實質
admin api 的實質也就是rest api,通過發送參數為json格式的http請求,實現操作。則可以看出,只要任何可以發送http請求的編程語言都可以用來調用admin api,像java,python,c# 等,本文就采用C# 調用Admin api進行示例。
二、使用C#調用admin api
admin api 通常調用遵循以下步驟:
1.獲取token
根據站點用戶名和密碼生成token和證書

private string GenerateAGSToken() { try { string urlGenerateToken = string.Format("{0}/generateToken", this.urlRestAdmin); string credential = string.Format("username={0}&password={1}&client=requestip&expiration=&f=json", this.username, this.password); string result = this.GetResult(urlGenerateToken, credential); JsonObject jsonObject = new JsonObject(result); string token = null; if (!jsonObject.Exists("token") || !jsonObject.TryGetString("token", out token)) { throw new Exception("Token not found!"); } return token; } catch(Exception ex) { return string.Empty; } }
2.構建json格式的參數
根據執行的操作所需要的參數,構建json格式的參數,這里以創建服務操作作為例子,進行json字符串的構建。這里使用的JsonObject對象為SOE開發中的鏈接庫ESRI.ArcGIS.SOESupport.dll 所帶。

public bool CreateService() { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/createService"; JsonObject jsonObject = new JsonObject(); jsonObject.AddString("serviceName", "Test"); //服務類型 jsonObject.AddString("type", Enum.GetName(typeof(ServiceType), ServiceType.GPServer)); jsonObject.AddString("description", "This is an example"); //不同的服務類型,其capabilities是不同的,地圖服務的為Map,query和data // jsonObject.AddString("capabilities", "Map,Query,Data"); jsonObject.AddString("capabilities","Uploads");//gp 服務的capabilities jsonObject.AddString("clusterName", "default"); jsonObject.AddLong("minInstancesPerNode", 1); jsonObject.AddLong("maxInstancesPerNode", 2); jsonObject.AddLong("maxWaitTime", 60); jsonObject.AddLong("maxStartupTime", 300); jsonObject.AddLong("maxIdleTime", 1800); jsonObject.AddLong("maxUsageTime", 600); jsonObject.AddLong("recycleInterval", 24); jsonObject.AddString("loadBalancing", Enum.GetName(typeof(LoadBalancing), LoadBalancing.ROUND_ROBIN)); jsonObject.AddString("isolationLevel", Enum.GetName(typeof(IsolationLevel), IsolationLevel.HIGH)); JsonObject jsonObjectProperties = new JsonObject(); // see for a list complete http://resources.arcgis.com/en/help/server-admin-api/serviceTypes.html jsonObjectProperties.AddLong("maxBufferCount", 100); // optional 100 jsonObjectProperties.AddString("virtualCacheDir", this.urlRestServer + "/arcgiscache"); // optional jsonObjectProperties.AddLong("maxImageHeight", 2048); // optional 2048 jsonObjectProperties.AddLong("maxRecordCount", 1000); // optional 500 //10.1中服務是通過msd的形式發布的,所以創建地圖服務時候將mxd轉換成msd的形式,創建msd的形式而其他服務的數據發布形式,參考上面的鏈接 // jsonObjectProperties.AddString("filePath", @"C:\AvGis\Test\mappa\UTM_ReteFognaria.msd"); //地圖服務 required jsonObjectProperties.AddString( "toolbox",@"d:\Buffer.tbx");//gp服務使用的是路徑創建gp服務的路徑 jsonObjectProperties.AddLong("maxImageWidth", 2048); // optional 2048 jsonObjectProperties.AddBoolean("cacheOnDemand", false); // optional false jsonObjectProperties.AddString("virtualOutputDir", this.urlRestServer + "/arcgisoutput"); jsonObjectProperties.AddString("outputDir", @"C:\arcgisserver\directories\arcgisoutput"); jsonObjectProperties.AddString("jobsDirectory", @"C:\arcgisserver\directories\arcgisjobs"); // required jsonObjectProperties.AddString("supportedImageReturnTypes", "MIME+URL"); // optional MIME+URL jsonObjectProperties.AddBoolean("isCached", false); // optional false jsonObjectProperties.AddBoolean("ignoreCache", false); // optional false jsonObjectProperties.AddBoolean("clientCachingAllowed", false); // optional true jsonObjectProperties.AddString("cacheDir", @"C:\arcgisserver\directories\arcgiscache"); // optional jsonObject.AddJsonObject("properties", jsonObjectProperties); string result = this.GetResult(serviceUrl, "service=" +HttpUtility.UrlEncode(jsonObject.ToJson()) + "&f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } }
admin api中的各項參數,詳見admin api的幫助:http://resources.arcgis.com/en/help/server-admin-api/,參數分為required和optional。
3.發送http請求
admin api可以支持兩者get和post請求。server管理功能中有些操作是不支持get請求的。
get請求

private string GetResult(string url) { try { WebRequest request = WebRequest.Create(url); WebResponse response = request.GetResponse(); using (Stream responseStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { return reader.ReadToEnd(); } } } catch { throw; } }
post請求

rivate string GetResult(string url, string postContent) { try { WebRequest request = WebRequest.Create(url); byte[] content = Encoding.UTF8.GetBytes(postContent); request.ContentLength = content.Length; request.ContentType = "application/x-www-form-urlencoded"; request.Method = WebRequestMethods.Http.Post; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(content, 0, content.Length); requestStream.Close(); WebResponse response = request.GetResponse(); using (Stream responseStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { return reader.ReadToEnd(); } } } } catch { throw; } }
4.接收請求
三、完整的代碼
代碼中涉及到服務的發布、刪除、文件夾的創建等

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; //// ///// namespace Studioat.ArcGIS.Server.Administrator { using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; using ESRI.ArcGIS.SOESupport; /// <summary> /// 服務類型 /// </summary> public enum ServiceType { MapServer, GeocodeServer, SearchServer, IndexingLauncher, IndexGenerator, GeometryServer, GeoDataServer, GPServer, GlobeServer, ImageServer } /// <summary> /// 負載平衡 /// </summary> public enum LoadBalancing { ROUND_ROBIN, FAIL_OVER } /// <summary> /// isolation level /// /// </summary> public enum IsolationLevel { LOW, HIGH } /// <summary> /// administrative API Rest /// </summary> public class AGSAdmin { private string username; private string password; private string urlRestAdmin; private string urlRestServer; /// <summary> /// Initializes a new instance of the <see cref="AGSAdmin"/> class. /// </summary> /// <param name="serverName">server name</param> /// <param name="port">port of server</param> /// <param name="username">username administrator</param> /// <param name="password">password administrator</param> public AGSAdmin(string serverName, int port, string username, string password) { this.username = username; this.password = password; string url = string.Format("http://{0}:{1}/arcgis", serverName, port.ToString()); this.urlRestAdmin = url + "/admin"; this.urlRestServer = url + "/server"; } /// <summary> /// Prevents a default instance of the <see cref="AGSAdmin"/> class from being created. /// </summary> private AGSAdmin() { } /// <summary> /// Create arcgis server folder /// </summary> /// <param name="folderName">Folder name</param> /// <param name="description">Description of the folder</param> /// <returns>True if successfully created</returns> public bool CreateServerFolder(string folderName, string description) { try { string token = this.GenerateAGSToken(); string folderUrl = this.urlRestAdmin + "/services/" + folderName + "?f=json&token=" + token; string resultExistsFolder = this.GetResult(folderUrl); if (!this.HasError(resultExistsFolder)) { return true; // exists } else { string createFolderUrl = this.urlRestAdmin + "/services/createFolder"; string postContent = string.Format("folderName={0}&description={1}&f=json&token={2}", folderName, description, token); string result = this.GetResult(createFolderUrl, postContent); return this.HasSuccess(result); } } catch { return false; } } /// <summary> /// Get physical Path and virtual Path from directory ags /// </summary> /// <param name="directory">directory ags</param> /// <param name="physicalPath">physical Path</param> /// <param name="virtualPath">virtual Path</param> /// <returns>True if successfully return path</returns> public bool GetServerDirectory(string directory, out string physicalPath, out string virtualPath) { physicalPath = null; virtualPath = null; try { string token = this.GenerateAGSToken(); string directoryUrl = this.urlRestAdmin + "/system/directories/" + directory + "?f=json&token=" + token; string result = this.GetResult(directoryUrl); JsonObject jsonObject = new JsonObject(result); if (!jsonObject.Exists("physicalPath") || !jsonObject.TryGetString("physicalPath", out physicalPath)) { throw new Exception(); } jsonObject = new JsonObject(result); if (!jsonObject.Exists("virtualPath") || !jsonObject.TryGetString("virtualPath", out virtualPath)) { throw new Exception(); } return true; } catch { return false; } } /// <summary> /// Delete Service /// </summary> /// <param name="serviceName">Service Name</param> /// <param name="serviceType">Server Type</param> /// <returns>True if successfully deleted</returns> public bool DeleteService(string serviceName, ServiceType serviceType) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/delete"; string result = this.GetResult(serviceUrl, "f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } } /// <summary> /// Start Service /// </summary> /// <param name="serviceName">Service Name</param> /// <param name="serviceType">Server Type</param> /// <returns>True if successfully started</returns> public bool StartService(string serviceName, ServiceType serviceType) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/start"; string result = this.GetResult(serviceUrl, "f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } } /// <summary> /// 停止服務 /// </summary> /// <param name="serviceName">Service Name</param> /// <param name="serviceType">Server Type</param> /// <returns>True if successfully stopped</returns> public bool StopService(string serviceName, ServiceType serviceType) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/stop"; string result = this.GetResult(serviceUrl, "f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } } /// <summary> /// 列舉服務 /// </summary> public void ListServices() { this.ListServices(null); } /// <summary> /// list of services in folder /// </summary> /// <param name="folder">name of folder</param> public void ListServices(string folder) { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/" + folder; string postcontent = "f=json&token=" + token; string result = this.GetResult(serviceUrl, postcontent); JsonObject jsonObject = new JsonObject(result); object[] folders = null; if (jsonObject.Exists("folders") && jsonObject.TryGetArray("folders", out folders)) { foreach (string subfolder in folders) { this.ListServices(subfolder); } } object[] services = null; if (jsonObject.Exists("services") && jsonObject.TryGetArray("services", out services)) { IEnumerable<JsonObject> jsonObjectService = services.Cast<JsonObject>(); jsonObjectService.ToList().ForEach(jo => { string serviceName; jo.TryGetString("serviceName", out serviceName); string folderName; jo.TryGetString("folderName", out folderName); Console.WriteLine(folderName + "/" + serviceName); }); } } catch { throw; } } /// <summary> /// create service type MapServer /// </summary> /// <returns>>True if successfully created</returns> public bool CreateService() { try { string token = this.GenerateAGSToken(); string serviceUrl = this.urlRestAdmin + "/services/createService"; JsonObject jsonObject = new JsonObject(); jsonObject.AddString("serviceName", "Test"); //服務類型 jsonObject.AddString("type", Enum.GetName(typeof(ServiceType), ServiceType.GPServer)); jsonObject.AddString("description", "This is an example"); //不同的服務類型,其capabilities是不同的,地圖服務的為Map,query和data // jsonObject.AddString("capabilities", "Map,Query,Data"); jsonObject.AddString("capabilities","Uploads");//gp 服務的capabilities jsonObject.AddString("clusterName", "default"); jsonObject.AddLong("minInstancesPerNode", 1); jsonObject.AddLong("maxInstancesPerNode", 2); jsonObject.AddLong("maxWaitTime", 60); jsonObject.AddLong("maxStartupTime", 300); jsonObject.AddLong("maxIdleTime", 1800); jsonObject.AddLong("maxUsageTime", 600); jsonObject.AddLong("recycleInterval", 24); jsonObject.AddString("loadBalancing", Enum.GetName(typeof(LoadBalancing), LoadBalancing.ROUND_ROBIN)); jsonObject.AddString("isolationLevel", Enum.GetName(typeof(IsolationLevel), IsolationLevel.HIGH)); JsonObject jsonObjectProperties = new JsonObject(); // see for a list complete http://resources.arcgis.com/en/help/server-admin-api/serviceTypes.html jsonObjectProperties.AddLong("maxBufferCount", 100); // optional 100 jsonObjectProperties.AddString("virtualCacheDir", this.urlRestServer + "/arcgiscache"); // optional jsonObjectProperties.AddLong("maxImageHeight", 2048); // optional 2048 jsonObjectProperties.AddLong("maxRecordCount", 1000); // optional 500 //10.1中服務是通過msd的形式發布的,所以創建地圖服務時候將mxd轉換成msd的形式,創建msd的形式而其他服務的數據發布形式,參考上面的鏈接 // jsonObjectProperties.AddString("filePath", @"C:\AvGis\Test\mappa\UTM_ReteFognaria.msd"); //地圖服務 required jsonObjectProperties.AddString( "toolbox",@"d:\Buffer.tbx");//gp服務使用的是路徑創建gp服務的路徑 jsonObjectProperties.AddLong("maxImageWidth", 2048); // optional 2048 jsonObjectProperties.AddBoolean("cacheOnDemand", false); // optional false jsonObjectProperties.AddString("virtualOutputDir", this.urlRestServer + "/arcgisoutput"); jsonObjectProperties.AddString("outputDir", @"C:\arcgisserver\directories\arcgisoutput"); jsonObjectProperties.AddString("jobsDirectory", @"C:\arcgisserver\directories\arcgisjobs"); // required jsonObjectProperties.AddString("supportedImageReturnTypes", "MIME+URL"); // optional MIME+URL jsonObjectProperties.AddBoolean("isCached", false); // optional false jsonObjectProperties.AddBoolean("ignoreCache", false); // optional false jsonObjectProperties.AddBoolean("clientCachingAllowed", false); // optional true jsonObjectProperties.AddString("cacheDir", @"C:\arcgisserver\directories\arcgiscache"); // optional jsonObject.AddJsonObject("properties", jsonObjectProperties); string result = this.GetResult(serviceUrl, "service=" +HttpUtility.UrlEncode(jsonObject.ToJson()) + "&f=json&token=" + token); return this.HasSuccess(result); } catch { return false; } } /// <summary> /// check is status is equal success /// </summary> /// <param name="result">result of request</param> /// <returns>True if status is equal success</returns> private bool HasSuccess(string result) { JsonObject jsonObject = new JsonObject(result); string status = null; if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status)) { return false; } return status == "success"; } /// <summary> ///錯誤信息判斷 /// </summary> /// <param name="result">result of request</param> /// <returns>True if status is equal error</returns> private bool HasError(string result) { JsonObject jsonObject = new JsonObject(result); string status = null; if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status)) { return false; } return status == "error"; } /// <summary> /// get請求 /// </summary> /// <param name="url">get 請求url</param> /// <returns>return response</returns> private string GetResult(string url) { try { WebRequest request = WebRequest.Create(url); WebResponse response = request.GetResponse(); using (Stream responseStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { return reader.ReadToEnd(); } } } catch { throw; } } /// <summary> /// post請求 /// </summary> /// <param name="url">請求url</param> /// <param name="postContent">post content</param> /// <returns></returns> private string GetResult(string url, string postContent) { try { WebRequest request = WebRequest.Create(url); byte[] content = Encoding.UTF8.GetBytes(postContent); request.ContentLength = content.Length; request.ContentType = "application/x-www-form-urlencoded"; request.Method = WebRequestMethods.Http.Post; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(content, 0, content.Length); requestStream.Close(); WebResponse response = request.GetResponse(); using (Stream responseStream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(responseStream)) { return reader.ReadToEnd(); } } } } catch { throw; } } /// <summary> /// 產生token /// </summary> /// <returns>返回一個toke,采用默認的過期時間令牌</returns> private string GenerateAGSToken() { try { string urlGenerateToken = string.Format("{0}/generateToken", this.urlRestAdmin); string credential = string.Format("username={0}&password={1}&client=requestip&expiration=&f=json", this.username, this.password); string result = this.GetResult(urlGenerateToken, credential); JsonObject jsonObject = new JsonObject(result); string token = null; if (!jsonObject.Exists("token") || !jsonObject.TryGetString("token", out token)) { throw new Exception("Token not found!"); } return token; } catch(Exception ex) { return string.Empty; } } } }
工程文件下載:https://github.com/myyouthlife/blog/tree/master/Studioat.ArcGIS.Server.Administrator