博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]ArcGIS Engine 10.1 如何操纵ArcGIS 10.1 for Server
阅读量:5809 次
发布时间:2019-06-18

本文共 15655 字,大约阅读时间需要 52 分钟。

第一章        使用ArcGIS Engine 管理ArcGIS Server

1.1         原因
在10版本以及之前的版本中,有一些用户通过ArcGIS Engine来管理ArcGIS Server,比如发布服务,停止服务等,对服务的管理是通过DCOM方式的,而在10.1中ArcGIS 不支持DOCM方式的连接,。如果你在代码中使用了Server库中的GISServerConnection或者GISClient库中的AGSServerConnection,在ArcGIS Server 10.1环境下,这些代码必须移除,如下面的代码:
1.png
  
如果强行执行,那么会有下面的错误:
2.png 
1.2         解决
ArcGIS Server在10.1版本中提供了ADMIN API,只要我们通过http请求构造相应的参数就行,对于ArcGIS Server的连接,我们可以看下desktop是如何连接的:
3.png
4.png
从这两个图中就可以看出,在选择连接Server的时候,选择角色,选择服务的类型(SDS和ArcGIS Server),在10版本以及之前的版本的时候跟这个有较大区别,连接ArcGIS 10.1 for Server的代码如下(注释已经写出):
public  IServerObjectAdmin ConnectAGS(string host, string username, string password)
        {
            try
            {
                IPropertySet propertySet = new PropertySetClass();
                propertySet.SetProperty("url", host);
                propertySet.SetProperty("ConnectionMode", esriAGSConnectionMode.esriAGSConnectionModeAdmin);
                propertySet.SetProperty("ServerType", esriAGSServerType.esriAGSServerTypeDiscovery);
                propertySet.SetProperty("user", username);
                propertySet.SetProperty("password", password);
                propertySet.SetProperty("ALLOWINSECURETOKENURL", true); //设置为false会弹出一个警告对话框
                IAGSServerConnectionName3 pConnectName = new AGSServerConnectionNameClass() as IAGSServerConnectionName3;//10.1新增接口
                pConnectName.ConnectionProperties = propertySet;
                IAGSServerConnectionAdmin pAGSAdmin = ((IName)pConnectName).Open() as IAGSServerConnectionAdmin;
                token = GenerateAGSToken_RESTAdmin(host, "arcgis", "arcgis");
               
                return pAGSAdmin.ServerObjectAdmin;
            }
            catch (Exception exc)
            {
                Console.WriteLine("连接失败: {0}. Message: {1}", host, exc.Message);
                return null ;
            }
        }
ConnectAGS("http://192.168.110.136:6080/arcgis/admin", "arcgis", "arcgis");
当获得了IAGSServerConnectionAdmin 这个接口我们进而可以获取IServerObjectAdmin,IServerObjectAdmin接口,
在帮助中看到了IDiscoveryServerObjectAdmin接口,该接口的方法和属性如下:
5.png
我欣喜若狂,因为这些和ArcGIS Server的Admin几乎是对应的,实现该接口的类不能被实例化,必须通过其他对象获取。但是不幸的是我在dll中并没有发现这个。
1.2.1         一个猜想
既然这个接口不能自己new,必须通过其他的实例化,那么这个对象是谁?
6.png
我们很自然的想到应该在连接成功之后就返回这个对象,该对象实现的接口如下:
7.png
我们注意下IRESTServerObjectAdmin 接口,字面意思就是通过rest方式跟Server打交道,而该接口只被一个类实现,该类就DiscoveryServerObjectAdmin
8.png
如果连接成功返回的真是DiscoveryServerObjectAdmin对象,那么我们QI到IRESTServerObjectAdmin上是没有问题的,结果正如我猜想的一样,有图为证:
9.png 
以上是我的个人猜想,但是不知道为什么dll中没找到这个接口,还是ESRI故意将这个接口隐藏起来了。
1.3         AO操作
当连接上ArcGIS Server,我们获取了IAGSServerConnectionAdmin,通过该对象我们获取了IServerObjectAdmin,通过该对象可以对Server进行管理
1.3.1         更改实例数
   private void ChangInstance(IServerObjectAdmin pSAdmin, IServerObjectConfiguration pConf, int pMin, int pMax)
        {
            IEnumServerObjectConfiguration pEnServerConf = pSAdmin.GetConfigurations();
            IServerObjectConfiguration pSConf = pEnServerConf.Next();
            IServerObjectConfiguration pSOConfig = null;
            while (pSConf != null)
            {
                if (pSConf.Name == pConf.Name && pSConf.TypeName == pConf.TypeName)
                {
                    pSOConfig = pSConf;
                    break;
                }
                pSConf = pEnServerConf.Next();
            }
            if (pSConf != null)
            {
                pSConf.MinInstances = pMin;
                pSOConfig.MaxInstances = pMax;
                pSAdmin.UpdateConfiguration(pSOConfig);
            }
        }
1.3.2         停止服务
pServerAdmin.StopConfiguration("Flow", "MapServer");
1.3.3         删除服务
   pServerAdmin.DeleteConfiguration("BusSimulation/DataPrep", "MapServer");//如果自己建立了目录请按照这种方式写,不然出错
1.4         REST方式操作
ArcGIS 10.1 for Server可以通过http请求的方式访问,server接到请求后,然后响应,响应的结果是json格式的,对json格式我们可以自己去解析,但是这个很麻烦,在10.1中增加了很多对json格式处理的接口IJSONReader2,IJSONWriter等很多,我在这里偷懒直接使用了AO中自带的接口,如果不用AO中的这些接口,自己借助一些json的解析工具如:JSON.NET也是可以的。
1.4.1         获取token
        public string GenerateAGSToken_RESTAdmin(string restAdmin, string username, string password)
        {
            try
            {
                if (restAdmin.EndsWith("\\"))
                {
                    restAdmin = restAdmin.Substring(0, restAdmin.Length - 1);
                }
                if (restAdmin.EndsWith("services"))
                {
                    restAdmin = restAdmin.Substring(0, restAdmin.Length - 9);
                }
                string loginUrl = restAdmin + "/generateToken";
                WebRequest request = WebRequest.Create(loginUrl);
                request.Method = "POST";
                string credential = "username=" + username + "&password=" + password + "&client=requestip&expiration=&f=json";
                byte[] content = Encoding.UTF8.GetBytes(credential);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                IJSONReader2 pJsonReader = new JSONReaderClass();
                IJSONObject pOb = pJsonReader.ParseJSONString(result) as IJSONObject;
                string token;
                if (pOb.TryGetValueAsString("token", out token))
                {
                }
            
                return token;
            }
            catch { return ""; }
        }
//""表示根目录
        public bool DeleteService_RESTAdmin(string restAdmin, string username, string password, string serviceName,string pType,string pFolder )
        {
            try
            {
                //string token = GenerateAGSToken_RESTAdmin(restAdmin, username, password);
                restAdmin = restAdmin.EndsWith("/") ? restAdmin.Substring(0, restAdmin.Length - 1) : restAdmin;
                string serviceUrl = restAdmin + "/services" +pFolder+"/"+ serviceName + "." + pType + "/delete";
                WebRequest request = WebRequest.Create(serviceUrl);
                string postcontent = "f=pjson&token=" + token;
                Byte[] content = Encoding.UTF8.GetBytes(postcontent);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                return result.Contains("success");
            }
            catch { return false; }
        }
1.4.2         停止服务
        public  bool StopService_RESTAdmin(string restAdmin, string username, string password, string serviceName, string pType, string pFolder)
        {
            try
            {
              //  string token = GenerateAGSToken_RESTAdmin(restAdmin, username, password);
                restAdmin = restAdmin.EndsWith("/") ? restAdmin.Substring(0, restAdmin.Length - 1) : restAdmin;
if (pFolder.Length > 0)
                {
                    pFolder = pFolder.StartsWith("/") ? pFolder : "/" + pFolder;
                }
                string serviceUrl = restAdmin + "/services" +pFolder+"/"+  serviceName + "." + pType + "/stop";
                WebRequest request = WebRequest.Create(serviceUrl);
                string postcontent = "f=pjson&token=" + token;
                Byte[] content = Encoding.UTF8.GetBytes(postcontent);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                return result.Contains("success");
            }
            catch { return false; }
        }
1.4.3         启动服务
        public  bool StartService_RESTAdmin(string restAdmin, string username, string password, string serviceName,string pServiceType,string pFolder)
        {
            try
            {
             //  string token = GenerateAGSToken_RESTAdmin(restAdmin, username,password);
                restAdmin = restAdmin.EndsWith("/") ? restAdmin.Substring(0, restAdmin.Length - 1) : restAdmin;
if (pFolder.Length > 0)
                {
                    pFolder = pFolder.StartsWith("/") ? pFolder : "/" + pFolder;
                }
                string serviceUrl = restAdmin + "/services" + pFolder + "/" + serviceName + "." + pServiceType + "/start";//服务名称+"."+类型
                WebRequest request = WebRequest.Create(serviceUrl);
               string postcontent = "f=pjson&token=" + token;
        
                Byte[] content = Encoding.UTF8.GetBytes(postcontent);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                return result.Contains("success");
            }
            catch { return false; }
        }
1.4.4         获取服务的目录,名称和类型
        //目录,服务名称,类型
        Dictionary<string, Dictionary<string, string>>  pServiceType = new Dictionary<string, Dictionary<string, string>>();
        Dictionary<string, string> pDic = new Dictionary<string, string>();
        public Dictionary<string, Dictionary<string, string>>  ListServices_RESTAdmin(string restAdmin, string username, string password, string folder)
        {
            try
            {
               //使用WebRequest 发送请求
                restAdmin = restAdmin.EndsWith("/") ? restAdmin.Substring(0, restAdmin.Length - 1) : restAdmin;
                string serviceUrl = restAdmin + "/" + folder;
                WebRequest request = WebRequest.Create(serviceUrl);
               string postcontent = "f=json&token=" + token;
               // json格式
                Byte[] content = Encoding.UTF8.GetBytes(postcontent);
                request.ContentLength = content.Length;
                //
                request.ContentType ="application/x-www-form-urlencoded";
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                int index = result.IndexOf("services");
                Dictionary<string, string> pSer = new Dictionary<string, string>();
                IJSONReader2 pJsonReader = new JSONReaderClass();
                IJSONObject pOb = pJsonReader.ParseJSONString(result) as IJSONObject;
                //"folders":["BusSimulation","System","Utilities"]
                //根目录
                   pServiceType.Add("/", new Dictionary<string, string>());
                   IJSONArray pFodArr;
              
                    if(pOb.TryGetValueAsArray("folders",out pFodArr))
                    {
                        for (int i = 0; i < pFodArr.Count; i++)
                        {
                            pServiceType.Add(pFodArr.get_Value(i).ToString(), new Dictionary<string, string>());
                          
                        }
                       
                    }
                
                if (pOb.MemberExists("services"))
                {
                   object pJs;
                   if (pOb.TryGetValue("services", out pJs))
                   {
                       if (pJs is IJSONArray)
                       {
                           IJSONArray pArray = pJs as IJSONArray;
                           for (int i = 0; i < pArray.Count; i++)
                           {
                               if (pArray.get_Value(i) is IJSONObject)
                               {
                                   IJSONObject pType = pArray.get_Value(i) as IJSONObject;
                                  // {"folderName":"/","serviceName":"GZCache","type":"MapServer","description":""}
                                   string folderName;
                                   //服务的目录
                                   if(pType.TryGetValueAsString("folderName",out folderName))
                                   {
                                   }
                                    string serviceName;
                                    //服务的名称
                                   if(pType.TryGetValueAsString("serviceName",out serviceName))
                                   {
                                   }
                                    string AGSType;
                                    //服务的类型
                                   if(pType.TryGetValueAsString("type",out AGSType))
                                   {
                                   }
                                   pServiceType[folderName].Add(serviceName, AGSType);
                               }
                           }
                       }
                   }
                }
            }
            catch { }
            return pServiceType;
        }
1.4.5         删除服务
     public bool DeleteService_RESTAdmin(string restAdmin, string username, string password, string serviceName,string pType,string pFolder )
        {
            try
            {
                //string token = GenerateAGSToken_RESTAdmin(restAdmin, username, password);
                restAdmin = restAdmin.EndsWith("/") ? restAdmin.Substring(0, restAdmin.Length - 1) : restAdmin;
if (pFolder.Length > 0)
                {
                    pFolder = pFolder.StartsWith("/") ? pFolder : "/" + pFolder;
                }
                string serviceUrl = restAdmin + "/services" +pFolder+"/"+ serviceName + "." + pType + "/delete";
                WebRequest request = WebRequest.Create(serviceUrl);
                string postcontent = "f=pjson&token=" + token;
                Byte[] content = Encoding.UTF8.GetBytes(postcontent);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                return result.Contains("success");
            }
            catch { return false; }
        }
1.4.6         服务是否停止
   public bool GetStatus_RESTAdmin(string restAdmin, string username, string password, string serviceName, string pServiceType, string pFolder)
        {
            try
            {
                //  string token = GenerateAGSToken_RESTAdmin(restAdmin, username,password);
                restAdmin = restAdmin.EndsWith("/") ? restAdmin.Substring(0, restAdmin.Length - 1) : restAdmin;
                string serviceUrl = restAdmin + "/services" + pFolder + "/" + serviceName + "." + pServiceType + "/status";//服务名称+"."+类型
                WebRequest request = WebRequest.Create(serviceUrl);
                string postcontent = "f=pjson&token=" + token;
                Byte[] content = Encoding.UTF8.GetBytes(postcontent);
                request.ContentLength = content.Length;
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(content, 0, content.Length);
                requestStream.Close();
                WebResponse response = request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string result = reader.ReadToEnd();
                return result.Contains("STOPPED");
            }
            catch { return false; }
        }
1.5         小结
在1.3和1.4我们分别用了AO的方式和REST的方式管理了ArcGIS 10.1 for Server,关于两种方法各有利弊,在这里我略总结如下:
       11.jpg
第二章        使用ArcGIS Engine 访问ArcGIS Server
2.1         以前是如何访问的
上面提到了我们以前通过DCOM的方式也就是本地连接来管理ArcGIS Server,而管理ArcGIS Server是通过IAGSServerConnectionAdmin接口,以前我们通过IGISServerConnection接口的connect方法来获取connect方法只有一个参数就是机器所在的位置,而该方法“隐性”的使用当前操作系统登陆用户名和密码去验证,为了保证连接的正确,当前的用户名必须在agsadmin组或者agsuser组,而前者是用来管理Server的,后者是用来访问Server的服务的,如果当前登陆的操作系统的账户不属于这两个组,那么就会报错,现在这种方式不存在了。
        private IServerObjectAdmin5 Admin()
        {
            ESRI.ArcGIS.Server.IGISServerConnection pServerConn = new ESRI.ArcGIS.Server.GISServerConnectionClass();
            pServerConn.Connect("esri-LiuYu");
            IServerObjectAdmin5 pServerAdim = pServerConn.ServerObjectAdmin as IServerObjectAdmin5;
            return pServerAdim;
        }
在管理ArcGIS 10.1 for Server的时候我们必须”显性”的指定用户名和密码,所以该接口在10.1的时候肯定是不能用,正如我们开始提到的那样,会报错。
2.2         IAGSServerConnection接口还能用吗?
IAGSServerConnection这个接口也是可以用来连接,该接口被AGSServerConnectionClass类实现,但是这个类是不可以自己实例化的,必须通过其他类创建,这个类实现的接口如下:
我们现在用user的身份连接,代码如下:
   public  List<IAGSServerObjectName>  ConnectUserAGS(string host, string username, string password)
      {
          try
          {
              List<IAGSServerObjectName> pList = new List<IAGSServerObjectName>();
              IPropertySet propertySet = new PropertySetClass();
              propertySet.SetProperty("url", host);
              propertySet.SetProperty("ConnectionMode", esriAGSConnectionMode.esriAGSConnectionModeConsumer);
              propertySet.SetProperty("user", username);
              propertySet.SetProperty("password", password);
          
              //打开连接
             // IAGSServerConnectionFactory pFactory = new AGSServerConnectionFactory();
              //Type factoryType = Type.GetTypeFromProgID(
              //    "esriGISClient.AGSServerConnectionFactory");
              //IAGSServerConnectionFactory agsFactory = (IAGSServerConnectionFactory)
              //    Activator.CreateInstance(factoryType);
              IAGSServerConnectionName3 pConnectName = new AGSServerConnectionNameClass() as IAGSServerConnectionName3;//10.1新增接口
              pConnectName.ConnectionProperties = propertySet;
              IAGSServerConnection pConnection = ((IName)pConnectName).Open() as IAGSServerConnection;
              //IAGSServerConnection pConnection = pFactory.Open(propertySet, 0);
              IAGSEnumServerObjectName pServerObjectNames = pConnection.ServerObjectNames;
              pServerObjectNames.Reset();
              IAGSServerObjectName agsServerObjectName = pServerObjectNames.Next();
              while (agsServerObjectName != null)
              {
                  pList.Add(agsServerObjectName);
                  agsServerObjectName = pServerObjectNames.Next();
              }
              return pList;
          }
在这里我取回List中的第一个,然后在MapControl中显示,代码如下:
    List<IAGSServerObjectName> pList = pServerMnt.ConnectUserAGS("http://192.168.110.136:6080/arcgis/rest/services", "", "");
          //  IRESTServerObjectAdmin pRest = pServerAdmin as IRESTServerObjectAdmin;
            ESRI.ArcGIS.Carto.IMapServerLayer pMapServerLayer = new ESRI.ArcGIS.Carto.MapServerLayerClass();
            IName pName = (IName)pList[0];
            IAGSServerObject pServerObject = (IAGSServerObject)pName.Open();
            IMapServer pMapServer = (IMapServer)pServerObject;
            pMapServerLayer.ServerConnect(pList[0], pMapServer.DefaultMapName);
            axMapControl1.AddLayer(pMapServerLayer as ILayer);
            axMapControl1.Refresh();
效果如下:
10.png
看到结果,这个问题已经有了答案了,对于以用户的身份连接ArcGIS Server的话,我们只需要修改下IPropertySet属性即可 。

 

文章来源:

转载于:https://www.cnblogs.com/yuanyl/p/3276862.html

你可能感兴趣的文章
修改ecshop购买按钮显示商品库存无货状态
查看>>
Disruptor和LinkedBlockingQueue性能对比以及分析
查看>>
android 的短息发声阅读软件源码
查看>>
Android播放器代码
查看>>
不需要重新安装ASP2.0,配置ASP2.0到IIS的方法
查看>>
Android 给应用定制皮肤
查看>>
Linux文件内容查阅命令
查看>>
linux十二周一次课(4月23日)笔记
查看>>
div 显示文字,超出部分点号代替
查看>>
编程十年
查看>>
我的友情链接
查看>>
phpstorm类似Eclipse的outline功能
查看>>
设计模式22——Visitor设计模式
查看>>
借道公众号实现新订单推送
查看>>
php 安装redis 4.0 扩展
查看>>
Android学习笔记(二九):嵌入浏览器
查看>>
sql 查询性能的问题 有order by 和无order by 速度竟然相差百倍
查看>>
奇怪的问题:telnet无法连接另一台server的正常的开放端口
查看>>
摘抄《手机软件最佳实践》--手机游戏应用的测试思路
查看>>
开发环境任务启动失败的定位-Yarn
查看>>