ArcGIS 10.1 for Server 扩展开发(SOE)

原文连接:http://blog.csdn.net/arcgisserver_book/article/details/7869368

第一章为什么使用SOE

在ArcGIS 10.1中ArcGIS Server不在支持DCOM方式的连接,这也就意味着我们不能通过本地方式的连接使用ArcObjects提供的更多功能,所以我们推荐一种新的方式来实现这些功能,这种方式就是SOE服务器对象扩展,一个SOE(Server Object Extension)就是一个包含一组方法的类,这个类可以在SOC(ArcGIS 10.1 for Server进程,全称是ArcSOC.exe)中运行,并且可以被web应用程序调用。
Server Objects是粗粒度的AO组件,是一个可以执行特定操作的高级对象,它隐藏了细粒度的ArcObject。Server Objects的粗粒度接口支持对于像绘制地图或地理编码等整体性任务。Server objects也有SOAP接口,可以把server objects暴露成Web Service,从而可以被客户端使用。
 SOE是开发者的一个高级选项,使您能够将ArcGIS Server服务基本功能进行扩展。SOE具有两大优势:
  1.SOE可以作为SOAP或REST Web服务,使得用ArcGIS Web APIs建立的客户(用于JavaScript、Flex、Silverlight、iOS等)以便调用这些应用程序。事实上,您的SOE将出现在ArcGIS Services Directory之内,并将提供特性设置、基本类型等ArcGIS APIs能够理解的典型对象类型。
  2.SOE能够对ArcObjects进行有效封装,提供理想环境以快速执行您的指令。 .
可以建立一个SOE,使用动态分段获取里程标志位置,或者实现几何网络分析(在ArcGIS 10的时候,因为工具箱中没有提供几何网络的GP,因此要实现几何网络的分析,可以通过这种办法)
  SOE开发需要ArcObjects、.NET或Java以及REST与SOAP等Web服务通信技术的知识。ArcObjects SDK具有多种可供您进行校验的样本,即可用于Java也可用于.NET。
 在SOE的开发过程中,我们必须清楚,我们需要在SOE中将请求获取,然后将传入的参数转化为AO,然后通过AO处理,再将处理的结果转成json格式,传给客户端,客户端得到json格式的结果,然后解析。
下图描述了请求响应的整个过程,如下图:


 
下图描述了请求回复的整个过程,如下图:
 

第二章SOE使用

1.1 
必选接口
1.1.1 IRESTRequestHandler 接口
该接口主要有下面两个方法:
        string GetSchema();
        byte[] HandleRESTRequest()

1.1.1.1 IRESTRequestHandler.handleRESTREquest() 方法主要有下面两个作用:
? 回调资源和操作的方法
? 获取资源在实例级别的描述
该方法在识别这两个作用的时候是通过operationName参数,如果该参数是空字符产那就是第二个作用,否则是第一个作用。
该方法的参数如下: 
     1. String capabilities:一组被资源授权的操作,可以为空字符串 
     2. String resourceName: 资源名称. 空字符串表示根级别,子资源会通过‘/’ 表示 
     3. String operationName: 操作名称
     4. String operationInput: 操作的参数,JSON格式
    5. String outputFormat:客户端请求的输出格式,如JSON,AMF 
    6. String[] responseProperties: 通过操作返回的一组键值对,逗号分开
1.1.1.2 IRESTRequestHandler.getSchema() 方法
以JSON格式返回SOE的资源列表
1.1.2 IServerObjectExtension
该接口主要有个方法:Init(IServerObjectHelper pSOH)和void Shutdown();
当Server启动的时候会调用该方法,并将IServerObjectHelper对象传入,该接口是对Server对象的弱引用,可以通过IServerObjectHelper.ServerObject得到服务器对象。
Shutdown方法用在服务器关闭时调用,经常我们在该方法中释放SOE中使用的资源。

1.2 
可选接口
1.2.1 IObjectConstruct
该接口只有一个方法Construct,该方法在Init方法执行后,立即被执行,如果我们的SOE有配置属性,就可通过该方法的参数得到,该方法只调用1次,我们可以将SOE中用的的比较耗费资源的逻辑写在该方法中,比如:获取地图代码,或者你始终操作某一个图层,就可以把获取该图层的代码写在这里。
1.2.2 IObjectActivate
当init和Construct调用后,SOE的对象已经被创建,并且相应的配置信息也得到了,如果SOE的整个逻辑中需要不停的获取和释放服务器上下文,那么就必须实现改接口,改接口有两个方法: activate()和deactivate(),当客户端调用CreateServerContext()
的时候activate()方法被调用,当客户端释放服务器上下文对象时deactivate()方法被调用。

SOE的执行过程
在对接口介绍的时候,我们已经提到了SOE的的运行过程,我们通过下面的图可进一步了解:


 
1.3 
创建SOE
现在我们创建一个完整的SOE,在VS2010中新建一个项目,选择Server Object Extention,并在右边选择REST 模板,如下图:


 
当点了确定之后,我们可以看到VS已经为我们生成了一个RestSOETest的类,该类已经实现了了我们前面介绍过的接口,如下:

public class RestSOETest : IServerObjectExtension, IObjectConstruct, IRESTRequestHandler
    {
        private string soe_name;

private IPropertySet configProps;
        private IServerObjectHelper serverObjectHelper;
        private ServerLogger logger;
        private IRESTRequestHandler reqHandler;

public RestSOETest()
        {
            soe_name = this.GetType().Name;
            logger = new ServerLogger();
            reqHandler = new SoeRestImpl(soe_name, CreateRestSchema()) as IRESTRequestHandler;
        }

#region IServerObjectExtension Members

public void Init(IServerObjectHelper pSOH)
        {
            serverObjectHelper = pSOH;
        }

public void Shutdown()
        {
        }

#endregion

#region IObjectConstruct Members

public void Construct(IPropertySet props)
        {
            configProps = props;
        }

#endregion

#region IRESTRequestHandler Members

public string GetSchema()
        {
            return reqHandler.GetSchema();
        }

public byte[] HandleRESTRequest(string Capabilities, string resourceName, string operationName, string operationInput, string outputFormat, string requestProperties, out string responseProperties)
        {
            return reqHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);
        }

在构造函数中多了一个ServerLogger的对象,通过名称我们就可知道,该对象是一个日志记录对象,用该对象可以对我们的SOE进行信息记录,记录后的信息,最后可以通过Manager的日志查看。在构造函数中还调用了CreateRestSchema函数,如下:

private RestResource CreateRestSchema()
        {
            RestResource rootRes = new RestResource(soe_name, false, RootResHandler);

RestOperation sampleOper = new RestOperation("sampleOperation",
                                                      new string[] { "parm1", "parm2" },
                                                      new string[] { "json" },
                                                      SampleOperHandler);

rootRes.operations.Add(sampleOper);

return rootRes;
        }

在该函数中创建了Rest资源和Rest资源的操作,并且资源和Rest操作都对应一个处理函数,我们一般称作Resthandler,这里的资源和操作可能比较抽象,我们举一个例子,比如说MapService就是一个资源,而查询就是一个操作,当我们执行操作的时候,处理整个逻辑的就是Resthandler,如上图的RootResHandler和SampleOperHandler分别是处理资源和资源操作的方法,这些handler的具体实现如下:

private byte[] RootResHandler(NameValueCollection boundVariables, string outputFormat, string requestProperties, out string responseProperties)
        {
            responseProperties = null;

JsonObject result = new JsonObject();
            result.AddString("hello", "world");

return Encoding.UTF8.GetBytes(result.ToJson());
        }

private byte[] SampleOperHandler(NameValueCollection boundVariables,
                                                  JsonObject operationInput,
                                                      string outputFormat,
                                                      string requestProperties,
                                                  out string responseProperties)
        {
            responseProperties = null;

string parm1Value;
            bool found = operationInput.TryGetString("parm1", out parm1Value);
            if (!found || string.IsNullOrEmpty(parm1Value))
                throw new ArgumentNullException("parm1");

string parm2Value;
            found = operationInput.TryGetString("parm2", out parm2Value);
            if (!found || string.IsNullOrEmpty(parm2Value))
                throw new ArgumentNullException("parm2");

JsonObject result = new JsonObject();
            result.AddString("parm1", parm1Value);
            result.AddString("parm2", parm2Value);

return Encoding.UTF8.GetBytes(result.ToJson());
        }
在这里我们要注意RestOperation类,该类对应了我们SOE的一个操作,该类的参数如下:
RestOperation (string name, string[] parameters, string[] supportedFormats, OperationHandler handler),这些参数分别对应了操作的名称,参数,支持的格式,以及该操作的处理函数。

一个资源可以有子资源,并且一个资源可以对应多个操作,对于资源的handler我们可以不用关注,但是操作的handler是我们整个SOE的核心部分。
下面是我们自定义的一个操作,其中pLineOperHandler是对应我们的handler

定义的操作:    
  RestOperation pLineOper = new RestOperation("pLineOperation",
                                                     new string[] { "RouteFieldName", "RouteID", "Stationfrom", "Stationto" },
                                                     new string[] { "json" },
                                                     pLineOperHandler);

当定义好了RestOperation之后,并且成功部署,那么可以在服务目录中看到下面的页面:


 
我们可以看出,RestOperation类中的参数和这个对应,当我们点了GET或者POST操作之后,这个时候就执行PlineOperHandler操作,该函数的定义如下:
   private byte[] pLineOperHandler(NameValueCollection boundVariables,
                                                  JsonObject operationInput,
                                                      string outputFormat,
                                                      string requestProperties,
                                                  out string responseProperties)
        {
            responseProperties = "";

if (serverObjectHelper.ServerObject is IMapServer)
            {
                mapServer = (IMapServer3)serverObjectHelper.ServerObject;
            }
           // IMapServerObjects pMSO = serverObjectHelper.ServerObject as IMapServerObjects;

IMapServerDataAccess pMapServerDataAcc = null;

IFeatureClass pFeatureClass = null;

if (serverObjectHelper.ServerObject is IMapServerDataAccess)
            {
                pMapServerDataAcc = serverObjectHelper.ServerObject as IMapServerDataAccess;

pFeatureClass = pMapServerDataAcc.GetDataSource(mapServer.DefaultMapName, 0) as IFeatureClass;

}
           
         //  // IMapServer.DefaultMapName 
         ////   IMap map = pMSO.get_Map(mapServer.DefaultMapName);
         
         //   //返回参与线性参考
         //  // routeFeatureLayer = (IFeatureLayer)map.get_Layer(0);

//   //线性参考代码
         //   IFeatureLayer featureLayer = routeFeatureLayer;

string _pPKName;
            operationInput.TryGetString("RouteFieldName", out _pPKName);

if (_pPKName==null)
                throw new ArgumentNullException("StationMeasure");

long? _pID;
            operationInput.TryGetAsLong("RouteID", out _pID);

if (_pID == null)
                throw new ArgumentNullException("RouteID");

double ? _pFrom;
            operationInput.TryGetAsDouble("Stationfrom", out _pFrom);

if (_pFrom == null)
               throw new ArgumentNullException("Stationfrom");

double? _pTo;
           operationInput.TryGetAsDouble("Stationto", out _pTo);

if (_pTo == null)
                throw new ArgumentNullException("Stationto");

IPolyline pointColl = FindRoutByMeasure(pFeatureClass, _pPKName.Substring(1, _pPKName.Length - 2), _pID.Value, _pFrom.Value, _pTo.Value);

JsonObject featureJson = new JsonObject();

featureJson.AddJsonObject("geometry", Conversion.ToJsonObject(pointColl as IGeometry));

return Encoding.UTF8.GetBytes( featureJson.ToJson());
        }

在前面已经介绍过,SOE里面的很大一部分代码是和AO对象打交道,而这部分也是我们的核心功能,当我们使用Esri提供给的SOE模板之后,我们要核心要做的就是写SOE请求函数,在这个请求函数也就是handler中,我们的核心AO代码就在这里,我这个函数的核心代码如下:
IPolyline FindRoutByMeasure(IFeatureClass _pRouteFC, string _pPKName, object _pID, double _pFrom, double _pTo)
        {
            IDataset pDataset = (IDataset)_pRouteFC;
            IName pName = pDataset.FullName;
            IRouteLocatorName pRouteLocatorName = new RouteMeasureLocatorNameClass();
            pRouteLocatorName.RouteFeatureClassName = pName;
            pRouteLocatorName.RouteIDFieldName = _pPKName;
            pRouteLocatorName.RouteMeasureUnit = esriUnits.esriFeet;
            pName = (IName)pRouteLocatorName;
            IRouteLocator2 pRouteLocator = (IRouteLocator2)pName.Open();

IRouteLocation pRouteLoc = new RouteMeasureLineLocationClass();

pRouteLoc.MeasureUnit = esriUnits.esriFeet;
            pRouteLoc.RouteID = _pID;
            IRouteMeasureLineLocation rMLineLoc = (IRouteMeasureLineLocation)pRouteLoc;
            rMLineLoc.FromMeasure = _pFrom;
            rMLineLoc.ToMeasure = _pTo;

IGeometry pGeo = null;

esriLocatingError locError;
            pRouteLocator.Locate(pRouteLoc, out pGeo, out locError);

return pGeo as IPolyline;

}

其实如果在ArcGIS Engine中做过和线性参考相关的工作,那么这端代码是完全可以在ArcGIS Engine中使用的,所以说SOE的开发并不是想象中的困难,相反如果有了AO基础的话,的确是很简单。
注意:
在这里我将自己遇到的问题说一下,如果在ArcGIS 10或者之前的版本中使用过SOE,那么发现下面的代码是可以运行的,而且没有问题:
IMapServer mapServer = (IMapServer3)serverObjectHelper.ServerObject;
            IMapServerObjects3 pMSO = mapServer as IMapServerObjects3;
            IMap map = pMSO.get_Map(mapServer.DefaultMapName);
但是在10.1的时候,这句代码是不会成功的,错误的地方在IMapServerObjects3,这是因为10.1中发布的服务是使用MSD文档,而IMapServerObjects3是针对MXD文档的,因此在10.1中应避免,避免IMap,Ilayer等,那么如何访问要素类,栅格对象,表等对象呢?使用IMapServerDataAccess接口,该接口主要有两个方法,如下图:


第一个方法主要获取表,要素类,栅格数据,但是在地图文档中我们有的数据是和其他数据有关联的的比如join操作,那么通过第二个方法我们不但可以获取源表的数据,还可以获取目的表的数据。
1.4 部署SOE
当SOE写完之后,我们通过ArcGIS Manager 进行部署,在Manager中找到站点,然后找到扩展,选择添加扩展,如下图:


 
找到我们编译后的SOE文件(.soe)结尾,如下图:


部署成功之后会在Manager中看到,如下图:


 
1.5 
调试SOE
SOE的工程实际上是一个类库,对于类库的调试,我们必须要有入口,对于SOE的入口我们知道是ArcGIS Server,如果在10版本以及之前的版本,我们可以写一个控制台程序,然后通过DCOM方式连接,而现在不能使用DCOM方式连接,那么还有没有其他办法?办法肯定是有的,如果写这样的东西不能调试对开发者来说岂不是很痛苦?当启动ArcGIS Server的服务的时候,会在Windows的任务管理器中看到ArcSOC.exe这样的进程,这些进程对应的就是ArcGIS Server的服务,我们可以采用附加进程的方式对SOE进行调试,如下,我们找到所有的ArcSOC.exe,将这些附加到进程中:
 

在我们的SOE工程中添加断点,如下图:


 
这样当我们通过Rest的方式访问SOE的时候,就会进行调试,我们便可以跟踪,看哪里出现问题。

下图是这个SOE运行的结果如下图:


 
1.6 
使用SOE
由于这个SOE是Rest方式的,所以我们可以在Flex,Silverlight这样的客户端使用,我们只需要构造这个SOE的rest地址,然后通过WebClient对象调用(这个是Silverlight中的,Flex中可能不一样),并获取结果,详细的例子可以参照Esri官网提供的例子:http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SOEElevationLatLonJsonObject
因为在上面的这个例子中,我将几何对象转成json格式的,但是在客户端使用的时候没有将json格式转成几何对象的API,有两种解决办法,我们在客户端获取这个json格式的字符串然后解析,自己构造这个几何对象,第二种方式,我们可以借用FeatureSet.FromJson()方法,这就要求我们在SOE中返回的是一个FeatureSet的描述,我们在代码中稍微修改下即可,如下:
private byte[] pLineOperHandler(NameValueCollection boundVariables,
                                                  JsonObject operationInput,
                                                      string outputFormat,
                                                      string requestProperties,
                                                  out string responseProperties)
        {
            responseProperties = "";

if (serverObjectHelper.ServerObject is IMapServer)
            {
                mapServer = (IMapServer3)serverObjectHelper.ServerObject;
            }
           // IMapServerObjects pMSO = serverObjectHelper.ServerObject as IMapServerObjects;

IMapServerDataAccess pMapServerDataAcc = null;

IFeatureClass pFeatureClass = null;

if (serverObjectHelper.ServerObject is IMapServerDataAccess)
            {
                pMapServerDataAcc = serverObjectHelper.ServerObject as IMapServerDataAccess;

pFeatureClass = pMapServerDataAcc.GetDataSource(mapServer.DefaultMapName, 0) as IFeatureClass;

}

string _pPKName;
            operationInput.TryGetString("RouteFieldName", out _pPKName);

if (_pPKName==null)
                throw new ArgumentNullException("StationMeasure");

long? _pID;
            operationInput.TryGetAsLong("RouteID", out _pID);

if (_pID == null)
                throw new ArgumentNullException("RouteID");

double ? _pFrom;
            operationInput.TryGetAsDouble("Stationfrom", out _pFrom);

if (_pFrom == null)
               throw new ArgumentNullException("Stationfrom");

double? _pTo;
           operationInput.TryGetAsDouble("Stationto", out _pTo);

if (_pTo == null)
                throw new ArgumentNullException("Stationto");

IPolyline pointColl = FindRoutByMeasure(pFeatureClass, _pPKName.Substring(1, _pPKName.Length - 2), _pID.Value, _pFrom.Value, _pTo.Value);

JsonObject featureJson = new JsonObject();

//构造FeatureSet
            JsonObject pRest = new JsonObject();

pRest.AddString("displayFieldName","restlt");

pRest.AddString("geometryType", "esriGeometryPolyline");

JsonObject pSpatial = new JsonObject();

//空间参考

pSpatial.AddString("wkid" ,pointColl.SpatialReference.FactoryCode.ToString());
            pRest.AddJsonObject("spatialReference", pSpatial);

//属性
            JsonObject pAtt = new JsonObject();

pAtt.AddString("ID", "1");

//要素  
            featureJson.AddJsonObject("attributes", pAtt);
            featureJson.AddJsonObject("geometry", Conversion.ToJsonObject(pointColl as IGeometry));

//要素集合
            JsonObject[] pFea = new JsonObject[1];

pFea[0] = featureJson;

pRest.AddArray("features", pFea);

return Encoding.UTF8.GetBytes(pRest.ToJson());
        }

我们建立一个Silverlight工程,在Silverlight中调用这个SOE,核心代码如下:

string SOEurl = "http://192.168.110.150:6080/arcgis/rest/services/Routes/MapServer/exts/RestLinear/pLineOperation?RouteFieldName=%22ROUTE1%22&RouteID=20000013&Stationfrom=0&Stationto=25&f=pjson";

WebClient webClient = new WebClient();

FeatureSet pFeature = new FeatureSet();

webClient.OpenReadCompleted += (s, a) =>
            {
                JsonValue jsonResponse = JsonObject.Load(a.Result);

FeatureSet pFeatureSet = FeatureSet.FromJson(jsonResponse.ToString());

if (pFeatureSet.Features != null)
                {
                    SimpleLineSymbol symbol = new SimpleLineSymbol();
                    symbol.Color = new SolidColorBrush(Colors.Red);
                    GraphicsLayer gLayer = new GraphicsLayer();
                    foreach (Graphic g in pFeatureSet.Features)
                    {
                        g.Symbol = symbol;
                        gLayer.Graphics.Add(g);
                    }

myMap.Layers.Add(gLayer);
                }

};

webClient.OpenReadAsync(new Uri(SOEurl));
        }

运行结果如下图(红色部分为SOE返回的结果):

时间: 2024-10-07 05:16:19

ArcGIS 10.1 for Server 扩展开发(SOE)的相关文章

ArcGIS 10.3 for Server新特性介绍

ArcGIS10.3的正式版立即在美国Esri全球用户大会推出.中国的正式发行时间预计在Esri中国的用户大会.以下就将用户比較关心的ArcGIS 10.3 for Server的新特性给大家进行简单说明! ---------------------------------------------------------------------------------- 版权全部.文章同意转载.但必须以链接方式注明源地址,否则追究法律责任! 建议看到转载,请直接訪问正版链接获得最新的ArcGIS

ArcGIS 10.3 for Server 在windows下的安装教程

原文:ArcGIS 10.3 for Server 在windows下的安装教程 以下是10.2的教程,10.3同样适用. 许可文件: ArcGIS For Server10.3许可文件 - 下载频道 - CSDN.NET http://download.csdn.net/detail/u013172428/8606589   一.操作系统要求 Operating Systems Minimum OS Version Maximum OS Version Windows Server 2012

ArcGIS 10.4 for Server 服务安全设计策略

培训内容: 1:理解ArcGIS 10.4 for Server 的用户和角色2:掌握基于角色的访问控制3:理解ArcGIS Token的原理4:理解ArcGIS Token的申请使用流程5:掌握使用ArcGIS Token访问服务6:掌握限制跨域访问请求7:重要目录文件的保护禁用服务目录帐号的保护限制文件的访问禁用缓存虚拟目录8:掌握设置反向代理9:Oracle数据实现表级别的用户访问设置10:Oracle数据实现行级别的用户访问设置11:掌握HTTP和HTTPS的使用和访问 邮件咨询:[em

[ArcGIS 10.3重磅来袭]ArcGIS 10.3 惊艳登场,打造新一代Web GIS最强“芯”

今天是2015年的第一个工作日,咱来重磅出击一下. 美国时间2014年12月10日,ArcGIS 10.3正式发布.这是Esri自2012年发布ArcGIS 10.2之后,历时两年的成果结晶.ArcGIS 10.3,隆重推出以用户为中心(Named User)的全新授权模式,超强的三维"内芯",革新性的桌面GIS应用,可配置的服务器门户,即拿即用的Apps,更多应用开发新选择,数据开放新潮 流,为构建新一代Web GIS应用提供了更强有力的核"芯"支持. 现将Arc

ArcGIS 10.3 惊艳登场,打造新一代Web GIS最强“芯”

美国时间2014年12月10日,ArcGIS 10.3正式发布.这是Esri自2012年发布ArcGIS 10.2之后,历时两年的成果结晶.ArcGIS 10.3,隆重推出以用户为中心(Named User)的全新授权模式,超强的三维"内芯",革新性的桌面GIS应用,可配置的服务器门户,即拿即用的Apps,更多应用开发新选择,数据开放新潮流,为构建新一代Web GIS应用提供了更强有力的核"芯"支持. 惊艳1:以用户为中心(Named User)的授权模式 ArcG

【ArcGIS 10.2新特性】ArcGIS 10.2将PostgreSQL原生数据发布为要素服务

1.ArcGIS 10.2支持原生数据发布为要素服 有没有将自己已有的空间数据发布为要素服务的需求?有没有将非Esri空间数据类型的数据作为服务在Web端展示的需求?    ArcGIS 10.2 for Server增加了这方面的能力,ArcGIS 10.2 for Server 可以将原生数据库中的空间数据发布为要素服务.    想必都知道现在的关系型数据库,也都对空间数据有一定的支持,如postgreSQL的pg_geometry,Oracle的sdo_geometry,SQL Serve

ArcGIS 10.3 for Desktop新特性介绍

ArcGIS 10.3是一个完整公布的ArcGIS平台,它包含新的产品(ArcGIS Pro),针对10.2版本号产品进行了功能增强和稳定性的改进. ArcGIS 10.3 for Server新特性介绍 http://blog.csdn.net/linghe301/article/details/31358733 ------------------------------------------------------------------ 版权全部,文章同意转载,但必须以链接方式注明源地

[SOE] ArcGIS Server对象扩展(SOE)开发注意事项

ArcGIS  Server对象扩展(SOE)开发注意事项 1.SOE介绍 在ArcGIS 10.1中ArcGIS Server不在支持DCOM方式的连接,这也就意味着我们不能通过本地方式的连接使用ArcObjects提供的更多功能,所以我们推荐一种新的方式来实现这些功能,这种方式就是SOE服务器对象扩展.SOE存在于整个服务对象的生存期内,可以利用服务对象的资源并对其进行扩展.一个SOE通常在服务对象创建是初始化,并且在整个服务对象的生存期内只会被创建一次.SOE支持SOAP和REST两种访问

Window Server 2003 安装ArcGIS 10相关问题

服务器上之前装的是ArcGIS 9.3,这次想升级到ArcGIS 10,此文主要记录一下安装和遇到的问题和注意事项. 1.卸载ArcGIS 9.3 在安装新的ArcGIS之前必须要卸载旧版本,之前在网上搜了很多,都没用,感觉卸载没有那么麻烦,按顺序将ArcGIS License Manager,ArcGIS Desktop和Server卸载,删掉安装目录下的文件.关于注册表可以先不用管. 2.安装ArcGIS License Manager和ArcGIS Desktop 这个没有什么问题,直接安