VE GetToken Webservice

Coordinator
Nov 28, 2008 at 6:30 PM
I think we should move the Protyotype GetToken function to be VE specific webservice. The way we currently using GetToken in the .ASPX has some issues:
  1. A blocking call to the VE Service to GetToken is currently being made on startup.  If this call is moved to be a webservice, it could be done asynchronously while the rest of the map elements are loaded up and displayed to the user.
  2. Breaks encapusulation.  Currently, to support XAML based instanciation, we doing a bit of a hack to pass the token to the static variable on VE.TileSource.  For purposes of encapsulation, the VE.TileSource should handle details such as this for itself.
  3. As a matter of design, one TileProvide erroring shouldn't cause issue with any other TileProvider.  Currenlty, an error. or even slow startup on the Prototype's GetToken call will causes an unhandled error.  With a webservice approach, any possible issues with GetToken are contained to the VE.TileSource and we shouldn't affect usage of other TileSources.
Coordinator
Nov 28, 2008 at 11:09 PM
Very interesting.
The current architecture is very "only Virtual Earth", since you can't do anything with VE until you get token it makes sence that you can't start without a token.
This is bad for a number of reasons, it slows the request time for the control itself and therefore limits the overall serving performance of the webserver.

Imagine a situation where you were using custom imagery but the VE geocoding, why do we have to wait for the token before we load the control? I totally agree.

Totally agree with point 2, it made these very different to everything else.

Should we setup a seperate service completely (different project, different port number, cross domain policy needed) or have that service in the web project for each sample project? It could be neat to have it in a common service and not have to duplicate code but we would need to lock down the calls to a set of known domains or else anyone could get a token for their app through it.

The side effect of this is that the serving page could actually just be HTML, no longer needing any ASP.NET. We could actually serve this from Silverlight Streaming in production applications to conserve bandwidth and increase speed.

My vote is yes.

John.
Coordinator
Dec 5, 2008 at 1:18 PM
Edited Dec 5, 2008 at 1:32 PM
Great.  I'll add this as a Task.  Not sure about whether to create a separate service.  Perhaps we should start with Prototype and update others when the need is obvious.  This begs the question of the ongoing usefullness of the tile source specific projects.  As for me, the only reason I go back to the non-prototype projects is to fix them.  Just wondering if these source specific projects have now outlived their usefulness.  So if we assume we have, then the choice is easy since we need to support the single prototype project.  I kind of like that idea as it keeps things simple and encourages us to keep everything working.
Dec 9, 2008 at 11:16 PM
Hey guys, great work on this project so far!  I've been following along on the progress of DeepEarth for about month now and its been a great tool.

I've been having a problem with the code checkin for this item, revision 17551.  I've been wracking my brain trying to get the Token service moved over and usable in my own project.  It works fine for me in my checked out Example projects.

I think my ASP project must differ from yours in some way because things aren't lining up.  For instance, I'm not seeing an option to add an App_Code folder.  My project is one of the ASP.Net projects that gets generated when you create a Silverlight application.

I tried creating a new service in my project, rather than directly importing the DeepEarth code.  I then copied over the VETokenService.cs code.  This almost worked... I got screwed up on the "BeginGetClientToken()" and "EndGetClientToken()" calls.  I have been unable to get my web service proxies to generate these methods.  Instead, I'm getting the similar GetClientTokenAsync() with an associated event which gets called upon completion.

If somebody could point me in the right direction to get this working, I'd much appreciate it. Thanks!
Developer
Dec 10, 2008 at 3:25 AM
 revision 17551, is the version where "Soul Solutions" upgraded the way the VE Token is handled

"Extracted VE Token into Async WCF service, created a shared static method to call once per silverlight instance. Saved to Session on Server for reuse - eg multiple windows or refreshed the paged."

I am not sure if this is your problem but when you deploy your application you need to update the "Endpoint" url for the new async WCF service to point to your website,
this is found in the "ServiceReferences.ClientConfig" file located in the DeepEarth project

there are 4 endpoint url's in that file, 3 for the VE web services and one that points to your website that has the WCF service to get the token for you,
you need to update the one that points to your website, in the download code from codeplex it is set to  "http://localhost:52638/DeepEarthPrototypeWeb/Services/VETokenService.svc"

so you need to update it to  "http://{YOUR WEBSITE LOCATION HERE}/Services/VETokenService.svc"
or to where you have the VETokenService.svc located in your ASP.NET project

plus if you want to use the production VE tiles you will need to also update the first 3 VE endpoints to point to the VE production servers

anyway I am not sure if this is actually your issue
Coordinator
Dec 10, 2008 at 3:51 AM
There are two types of web projects in Visual Studio, a website and a web application. The default with a silverlight app is a website. You add a "Silverlight enabled WCF service" as usual, I put it under a new folder called services, but the code behind automatically goes into the app_code folder, I believe it even creates that folder if not already there. In the web application project they would be linked as usual. The difference is the website doesn't compile down to a dll, you have to deploy the actual code behind files, while I belive eerything in the app_code does get compiled?

Regardless, simply add a "Silverlight WCF service" to your website, copy the async code that I committed and then as noobie said in the "ServiceReferences.ClientConfig" file of your silverlight app you have to set full paths to the services it needs. I set the port number of the website to be static (rather then dynamic) so I could use the full path. For production this would be your actual domain and you would also change the path to the VE services to the production servers.

Before we release I'll make sure there is a simple step by step guide for this.
Dec 10, 2008 at 3:17 PM
It looks like I'm using a web application because the project has its own project file and when I create the service, it uses the code behind method.

The problem I'm running into though is with the code in App_Code\VETokenService.cs.  I haven't been able to generate a Web Reference or Service Reference to the Virtual Earth's CommonService that generates the same methods that are being called in VETokenService.  Specifically, I don't have commonservice.BeginGetClientToken(), or EndGetClientToken().

Instead of getting BeginGetClientToken(), the VE web reference is generating GetClientTokenAsync() for me.  GetClientTokenAsync() returns void, so I can't return the IAsyncResult that the DeepEarth service wants.

I guess the problem boils down to that I'm unable to produce a web reference to VE's common service in the same way that is being used in the example projects.

Thanks for your help.
Dec 12, 2008 at 2:34 PM
In searching for a solution to this problem, I came across this page from MSDN:
Accessing an XML Web Service Asynchronously in Managed Code

After reading this page, it appears that the Example projects' proxy class for VE's Common Service was generated in a .Net Framework 1.1 way.  In 1.1, the generated proxy class uses Begin...() and End...() functions to do things asynchronously.  In .Net Framework 2.0 and 3.5, asynchronous methods are started by calling ...Async(), and completed thru the firing of an event: ...Completed += new EventHandler( );

So this leaves me confused :)  How can I get a .Net 1.1 styled proxy class in a .Net 3.5 project?  And also, how did it get in the DeepEarth project?
Dec 15, 2008 at 10:56 AM
Hi

I'm facing the exact same problem.
Hope can solve it soon, as I'm sitting an testing it out trying to use it in my own application :)
Dec 15, 2008 at 11:13 AM
Edited Dec 15, 2008 at 11:14 AM
Grimus, maybe you've used this tool svcutil.exe from here: http://msdn.microsoft.com/en-us/library/cc980833.aspx
I only used VS2008. It should be the same tool, but maybe there is a difference?
Developer
Dec 15, 2008 at 1:55 PM
Why don't you guys just copy and paste the files from the DeepEarth source code into you own projects?
Dec 15, 2008 at 3:12 PM
There are more problems to actually...

Please correct me if I'm wrong, but if I want to use the Map in my own application, what I need in my solution is the following:

This is a list of projects:
  1. DeepEarth (The core project)
  2. DeepEarth.VirtualEarth ( Project that includes code to help me actually show the Tiles on the map?)
I have a few problems as stated above, but not long ago I discovered another thing too.
In the DeepEarth.VirtualEarth project if you look in the Reference.cs file for the TokenService, you'll see in the code:
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://codeplex.com/deepearth/VETokenService/GetToken", ReplyAction="http://codeplex.com/deepearth/VETokenService/GetTokenResponse")]
        System.IAsyncResult BeginGetToken(System.AsyncCallback callback, object asyncState);
The above code is taken from: http://www.codeplex.com/deepearth/SourceControl/changeset/view/17668

I'm pretty new to WCF, but to me this looks like trouble. This is autogenerated code that points at something on codeplex, which doesn't exists when I look it up in the browser. If I include the DeepEarth.VirtualEarth into my project, I will get an error as the calls to this TokenService doesn't work. Is it because I shouldn't include this project? If not, how should I show the actual tiles on the map?

I'm I totally of here?

Thanks in advance,
Qbus

Developer
Dec 15, 2008 at 3:37 PM
the actual "Endpoints" for the WCF webservice's are stored in the file called "ServiceReferences.ClientConfig" in the silverlight application that uses the DeepEarth control,
e.g. in the download source you will find the file in the DeepEarthPrototype project
this is where the URL's that are used by the application are stored...

what you need to make a site using the DeepEarth control is

  1. DeepEarth (The core project)
  2. DeepEarth.VirtualEarth (is the TileLayer Provider project)
  3. Your Silverlight Application that has a referance to the DeepEarth project to get the Map Control
  4. ASP.NET website or Application to host your Silverlight Application (this must have the "TokenWebReference" in it)

then you need to goto the "ServiceReferences.ClientConfig" which will be in your Silverlight Application and update the URL/Endpoint to goto the "TokenWebReference" in your ASP.NET website

Dec 15, 2008 at 7:03 PM
I'm aware of the endpoints in the ServiceReferences.ClientConfig file. The problem is that DeepEarth.VirtualEarth has it's own ServiceReferences.ClientConfig? I know I need to have a similar ServiceReferences.ClientConfig in my "main app", and I have.
But i still get an error saying "NotFound". But as I see it there is a problem that both the "main app" AND the DeepEarth.VirtualEarth have a ServiceReferences.ClientConfig, or am I wrong here?

Ok, it looks like my list of projects needed to run the DeepEarth is pretty correct. The "main app" (Silverlight) and the hosting app (the web application project) I just didn't put in the list :)

"then you need to goto the "ServiceReferences.ClientConfig" which will be in your Silverlight Application and update the URL/Endpoint to goto the "TokenWebReference" in your ASP.NET website"
This is were it get tricky, as the hole problem of this discussion is about not being able to generate an working "TokenService WebReference".

Thanks for your answers so far :)
Developer
Dec 16, 2008 at 2:29 AM
if you download the Source code and run the DeepEarthPrototype project,
you will see that you can actually delete the ServiceReferences.ClientConfig file from the DeepEarth.VirtualEarth
and just have the one in the DeepEarthPrototype project and the project will still run and load the VE maps

I still don't understand why you just do not copy the "TokenService WebReference" from the download source and paste it into your own application?
then make the updates to the ServiceReferences.ClientConfig Endpoints?

is there a reson you cannot do this?
Dec 16, 2008 at 6:53 AM
Thanks for your answers.  I will try out the copy thing, but it wouldn't be now sadly. The project I'm working on have a tight timeline, so I need to go back to the component that I know will work for now. We have a first release in january, and I need to be ready there.
But for our 2. release I will get back and look at DeepEarth again, as it's a much better solution than the component, expecially when it's done :)

Thanks for your answers.
Dec 16, 2008 at 4:22 PM

Qbus - I've used both the svcutil.exe, as directed in that link, and directly in VS 2008 to generate the refernce to VE's web service and have had pretty much the same results.

dotnetnoobie - I'd like to copy in the "TokenService WebReference", but I don't know what to actually copy.  I have been unable to locate the definition of "BeginGetClientToken", "EndGetClientToken", or even just the "CommonService" class, which are all required in the VETokenService.cs.

Please do the following:  Open the DeepEarth solution, then open VETokenService.cs in \DeepEarthPrototypeWeb\App_Code\.  On line 15, right click on "CommonService", and select "Go To Definition".
If your solution is working the same as mine, it will take you to a metadata file located in an arbitrary temp folder.  As you can see, I haven't been able to add this code because I have no idea where it is coming from.

If you can tell us how to re-create the "TokenWebReference" as its being used in DeepEarth, or how to import it from the solution's code, our problems should be easily solved.  By "TokenWebReference", I am referring literally to the namespace defined in DeepEarth and the code in it that is being used to contact VE's servers and get a client token.  (Just trying to make sure I'm being clear, I apologize if I'm insulting your intelligence.)

Dec 20, 2008 at 4:31 AM
I am having trouble with the token service. 

The DeepEarthPrototype works (so my VE credentials are OK), but my own app does not -- I am always getting the "Error getting token..." in EndGetToken. 
I noticed that in BeginGetToken that the UserHostAddress is "::1", which doesn't seem right.

My app is hosted on my local machine with IIS7 and I have changed the endpoint urls to point to my website "http://localhost/MyAppName/WebServices/VETokenService.svc". 
I can navigate to those urls with no problems.

Any ideas?
Dec 20, 2008 at 12:55 PM
I got it working. I had to add a new method to TokenService.cs:

 

private static string GetIP4Address()
{
    string strIP4Address = String.Empty;
    foreach (IPAddress objIP in Dns.GetHostAddresses(Dns.GetHostName()))
    {
        if (objIP.AddressFamily.ToString() == "InterNetwork")
        {
            strIP4Address = objIP.ToString();
            break;
        }
    }
    return strIP4Address;
}

Then I call that from BeginGetToken:

ClientIPAddress = GetIP4Address(), //HttpContext.Current.Request.UserHostAddress,

 

Dec 21, 2008 at 2:38 AM

I'm as confused as the others on this subject. soulsolutions promised a step by step guide before the release. Any chance we can get something soon?

As has has been stated above, VS 2008 is not generating the same code as you have in the DeepEarth source code.

Thanks in advance,
Richard

Developer
Dec 21, 2008 at 3:51 AM
do you still have this issue in the release?

this services are all wrapped up into a .dll, all I need to do it update the endpoint in the ServiceReferences.ClientConfig it works
Dec 21, 2008 at 5:21 PM
Just updating the endpoint does not work in all environments.

Apart from the required change described in my last post, there is a problem running in medium trust -- BeginGetToken throws a SecurityException.
Dec 22, 2008 at 4:26 PM

dotnetnoobie: Yes, I've been trying everything in the released version.

Here's what I have tried and still cannot view VE imagery. (skipping the many false tangents along the way)

- Copy the DeepEarth.VirtualEarth.Services assembly to my web app's Bin folder
- Update the web.config service endpoints and service behaviours
- Update the clientconfig endpoint and bindings to reference my localhost service
- Add the VETokenServiceUrl key to the web.config appSettings (this key is referenced in TokenService.cs but is not set in the prototype project - without setting this the webservice never even gets called) and point it to my localhost website service address, e.g. http://localhost:1243/Services/VETokenService.svc
-

Now, in EndGetToken, I get the following error:
The message with Action 'http://s.mappoint.net/mappoint-30/GetClientToken' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

I'm clearly missing something here. Any help is appreciated.
Richard

 

Dec 22, 2008 at 6:17 PM
Update: I finally got this working.

The steps I describe above will work. In my case, there were some outdated endpoint references (VEImageryService.IImageryService) from a pre-release version of the DeepEarth code. So even after I'd worked out the kinks with the token service, I was still getting the identical result, but from a different bug in our code.

I'd still like to understand what is going on with the VETokenServiceUrl.

Richard
Coordinator
Dec 23, 2008 at 7:27 PM
VETokenServiceUrl is for setting the url to the VE token service. If it is not set, then it will default to the developer/staging token service. However, to point to the production token service, you will need to change this in the web.config.

Staging Environment: https://staging.common.virtualearth.net/find-30/common.asmx
Production Environment: https://common.virtualearth.net/find-30/common.asmx
Dec 29, 2008 at 5:51 PM
FYI: The way to add an old-style web reference in Visual Studio 2008 is to choose Add Service Reference and then click the Advanced button at the bottom of the Add Service Reference form. At the bottom of the new form is a Add Web Reference button.
Dec 29, 2008 at 7:20 PM
@rmatsu, could you please clarify your 'what i've tried' steps?

all, is there any update on plans to release some basic setup documentation? i must say that despite the rich functionality in this product, the documentation is woefully lacking.
Dec 29, 2008 at 10:40 PM
Hi All,

I wanted to quickly say that I was able to get the release version working today.  The separation of the Token service into its own project was a huge help.
If people are interested, I can go into details of whats needed to get it to work, but not today.  I'm spent for today :)
Dec 29, 2008 at 10:45 PM
@grimus: Yes, please! That would be greatly appreciated. Today has been a writeoff due to struggling with trying to get this configured.
Dec 30, 2008 at 3:35 PM
I hear ya on the struggle.  It took me most of yesterday to get it working... thus the being spent...

Most of the problems I ran into getting the release version working were actually not DeepEarth's fault but just caused by stupid oversights, and Visual Studio fighting me on debugging.
A lot of my problems also came from the fact that I was upgrading from an older prerelease version to the release, and the endpoints I had setup in the ServiceReferences.ClientConfig weren't quite right for the release version.

If you're upgrading from a prerelease version, I would suggest you start with a fresh new project and try to get that working with DeepEarth by itself.  I was able to get a fresh project working much more quickly and was then able to figure out my other errors in the main project.

Here's how I got the Token Service to work:
Make sure you have the username and password defined in your web.config for the VE service.

Add a reference to the DeepEarth.VirtualEarth.Services project in the ASP web application project.  I'm using the DeepEarth source and have the DeepEarth projects included in my solution.  If you're using binaries, I guess you'll have to add a reference to those.

Add a new WCF service.  I added mine to a folder named Services to mimic the prototype project.  Then delete any file it autogenerates, except keep for the .svc file.  Overwrite the contents of the .svc file with the contents of VETokenService.svc in the Prototype project.  The .svc file should now be indicating that it is using the DeepEarth Token Service for its functionality.

In web.config, replace the configurations that were generated for the WCF service with the configuration for the Token service from the web.config file of the Prototype project.  These configurations will be inside the <system.serviceModel> tags.

In ServiceReferences.ClientConfig in the Silverlight project, copy over the binding and endpoint configurations for the token service from the Prototype project.  Change the address to reflect your own server.  Mine came out to be "http://localhost:4177/Services/VETokenService.svc"  Make sure you have the port set to the port of your ASP web server.

After I got the token service to finally work, I was still having problems with the map.  It turned out the other endpoints and bindings in my ServiceReferences.ClientConfig file were incorrect.  They must have been changed from my prerelease version in the release version.  It took my awhile to realize this because they looked so similar to what was in the prototype project that I didn't notice the slight differences.  Also, the DeepEarth code suppressed the exceptions relating to this problem, so it took me awhile to find out what the problem was.  If you see first chance exceptions getting caught in your Output tab, this may be what's happening.  I finally figured everything out after stepping into the code that handled the creation of the TileLayer, in TileLayer.cs in DeepEarth.VirtualEarth.  (And getting the debugger to work again was another hassle from VS.)

A helpful tool here was the Web Development Helpeer, http://projects.nikhilk.net/WebDevHelper/.  You can use this to check that all the web requests are happening correctly.

So hopefully this all gets you working.  If not, ask away.