0

My organization is in the process of overhauling our self-hosted ArcGIS setup and as such we are moving from the 3.27 JSAPI to the 4.24 JSAPI with all our of in-house web apps. We are using the following code below to create a basic map application to begin working with.

IdentityManager.registerToken({
    expires: namespace.VueModel.ArcGISToken.expires,
    token: namespace.VueModel.ArcGISToken.token,
    ssl: true,
    userid: "username",
    server: "https://arcgisserver.ourdomain.com:6443/arcgis/rest/services"
});

let basemapLayer = new MapImageLayer({
    url: https://arcgisserver.ourdomain.com:6443/arcgis/rest/services/2022/BasemapBasic/MapServer"
});

let map = new Map({
    basemap: new Basemap({
        baseLayers: [
            basemapLayer
        ],
        referenceLayers: [
            basemapLayer
        ]
    }),
    minScale: 204800
});

let mapView = new MapView({
    background: {
        type: "color",
        color: [255, 255, 255, 1]
    },
    extent: basemapLayer.fullExtent,
    map: map,
    container: "scene",
    ui: {
        components: []
    }
});

The above code works exactly as expected when the app is being accessed from a web browser on the same machine it is hosted on. The app URL looks like the following example:

http://hosted_machine_name/GIS/2022/Map.aspx

However, when we try to access the app using the same URL but on a different machine, the application is found but the map/mapview component fails to load entirely and the following is logged in the web browser's console:

[esri.layers.MapImageLayer] #load() Failed to load layer (title: 'BasemapBasic', id: '1846228f0f5-layer-0') 
[esri.views.View] #spatialReference no spatial reference could be derived from the currently added map layers

When we use one of ESRI's built in basemaps, the app does load when accessed remotely but the moment we try to add a new map layer using the same map service URL as before, we get the following in the web browsers console:

[esri.views.LayerViewManager] Failed to create layerview for layer title:'BasemapBasic', id:'1846230de8c-layer-3' of type 'map-image'.
Uncaught (in promise) l {name: 'request:server', details: {…}, message: "Cannot read properties of null (reading 'trim')"}

We checked our CORS settings and the hosted machine the app is on is allowed to make CORS requests to the ArcGIS server for its map services/data regardless, so unless we are missing something else that is CORS related, we have ruled CORS out. We then thought it might be our ArcGIS server version but we ruled that out as the app does run fine on the host machine.

Does anyone have any idea as to what we are missing here as this is truly a puzzling behavior we are seeing?

Update 1

It appears the issue has something to due with the Identity Manager API. After doing some deeper investigation, the following line is given as the faulting component:

u._checkProtocol (https://.../esri/identity/IdentityManager.js:49:166)

By commenting out the Identity Manager code, the app prompts for logging in and at which point, it will work on remote machines. We are handling token security in the APSX code behind to users can access our services without having to log in by a server to server handshake, obtaining a token and storing it in the session.

1 Answer 1

1

So as it turns out, the issue was indeed with how we were obtaining the token required to access the map service. In our ASPX code behind, it was making a call to the token service but was doing so using "RequestIP" instead of just "IP". This is why the app would only work on the machine in which it was hosted. We corrected the C# code to using 'IP' along with the 'UserHostAddress' and that resolved the issue.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["PathToGenerateToken"]);

string postData = "username=" + Uri.EscapeDataString(ConfigurationManager.AppSettings["TokenUsername"]);
postData += "&password=" + Uri.EscapeDataString(ConfigurationManager.AppSettings["TokenPassword"]);
postData += "&expiration=" + Math.Floor((decimal)(DateTime.Today.AddDays(1).AddHours(4) - DateTime.Now).TotalMinutes);
postData += "&client=ip"; // MUST BE 'IP' AND NOT 'REQUESTIP'
postData += "&ip=" + this.Request.UserHostAddress;
postData += "&f=json";

byte[] data = Encoding.ASCII.GetBytes(postData);
...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.