hi
is it possible to change the DataPortalURL in code?
As I want to the option to change the Server in my application loginform.
No, it is not possible to change the URL in code using the existing data portal channels.
However, the data portal is specifically designed to be extensible - and that means you have the ability to write your own channel that could (for instance) allow dynamic changes to the server URL.
Each of the four existing channels are discussed in Chapter 4, and you could use any of them as a base for building your own channel. You can also look at the prototype WcfChannel (http://www.lhotka.net/Articles.aspx?id=0eec56bb-2a61-47c4-a9ca-f98371db1cad) to see how an external channel assembly is created.
I think there are all sorts of interesting possibilities here. Not only could you create a channel that allowed dynamic URL changes, but you could create a channel that had different rules for local vs remote calls, which is another very common request (online/offline mode switching).
Hi sune42
Have you got anywhere with this? Our application needs the option of running against multiple dataportal servers, as we have different "Environments" available to a user e.g. Live, Training, Test. Each environment has its own Server and Database, and the user needs to be able to select the environment on startup. Has anyone else done anything like this?
TIA.
I have not had to deal with changing the Server but do have to give the user the ablity to select different databases. Here is what I wrote on another post a while back:
We have a similar situation where we have 3 Regions each with their own seperate database due to distance between locations. Additionally we have a development copy of the database for our own testing.
It may not be eligant but it works.
I have the following in my app.config file because until I get the connection string I can't get to a server.
<add key="ConfigRegionCount" value="3" />
<add key="ConfigRegion1" value="Calgary" />
<add key="ConfigRegion2" value="Edmonton" />
<add key="ConfigRegion3" value="Regina" />
On my login form the user selects the region they wish to log into. Additionally I have a check box option for development database, but I wont go into that here.
Then based on which region they select I know which encrypted connection string to get from the database which looks like this.
<
add key="DB:Calgary" value="bbNSKIAS8yO7...=" />This allows for any number of connection strings, if you have to add another you only have to add tow lines to your app.config file. Based on the region selected it knows what connection string to use. If the user wants to switch database they simply logoff which brings up the logon screen again and they select a different database. I store the users last logged on region to start with as the user is likely logging into the same database all the time. I don't have to worry about users logging into the wrong database as this is cared for by the security model we have implemented.
Additionally the connections string is encrypted multiple times embedding both the data database connection string as well as the security database connection string together. But that another story.
Hi odie.
Thanks very much for the info. Perhaps I'd better clarify. When I said "Each environment has its own Server and Database" I meant that each environment has its own DataPortal Server that will always connect to the Database associated with that environment e.g. Test DataPortal Server will connect to database TestDB and Training DataPortal Serverwill always connect tp database TrainDB. So the ability to switch DataPortalURL is the critical part for me.
I have a similar issue. I need to allow data portal changes on the fly based on which account a user is viewing. If some criteria of that record is true, then use one dp for access, otherwise use another.
I can see how a channel can be written for your own needs, but I am having trouble seeing how you could make it dynamic on the fly based on the data. Has anyone already done this or can give me a theoretical idea of how to do it? I'd be happy to share my results.
Thanks,
Mike
Wbmstrmjb:I can see how a channel can be written for your own needs
Mike
Hi Mike.
I wish I could understand how to do this. I looked at the Csla code extensively today and couldn't figure out what part Rocky was suggesting I write a custom version of. Maybe you can clear that up for me?
Thanks.
Xal really helped me out on this one, so I need to give him credit for this, but I'll try to go into more detail.
The DataPortal.Client folder contains the Proxies for different channels. I am taking the RemotingProxy and creating a DynamicRemotingProxy that will allow for switching between URLs based on data. Since it is only changing the URL, the Host will still be the RemotingPortal.
I'm changing the CslaDataPortalUrl in the config to be a list of servers that I will parse out. You could probably do this a few different ways, but a simple parse means that I don't have to change the access method in ApplucationContext. Inside the new DynamicRemotingProxy class, I have added a DynamicRemotingProxyLocation enumeration to specify the various choices and those are associated to the config file servers. Here is my code for the changed Portal() method (used to be a property):
private
Server.IDataPortalServer Portal(DynamicRemotingProxyLocation location){
string dataPortalURL; // still need to parse out the serversdataPortalURL =
ApplicationContext.DataPortalUrl.ToString(); if (_portal == null)_portal = (Server.
IDataPortalServer)Activator.GetObject(typeof(Server.Hosts.RemotingPortal), dataPortalURL); return _portal;}
Now in the methods of the Proxy such as Create, Fetch, Update, I am changing it to look at the object's interfaces to see if it has a new interface that I call IDynamicRemotingHelper. If so, it will call that function on the object to get the location. Here is that code for the Update:
public
Server.DataPortalResult Update(object obj, Server.DataPortalContext context){
DynamicRemotingProxyLocation location; if (obj is IDynamicRemotingHelper)location = ((
IDynamicRemotingHelper)obj).PortalLocation; else// my default location
location =
DynamicRemotingProxyLocation.EUR; return Portal.Update(obj, context);}
I hope this helps. If you need more clarification on an issue, let me know. When I finish, I will post changes and/or issues that I came across.
Mike.
This is great! Exactly the sort of idea I was looking for. I seem to be missing part of the picture though. Could you show me an example of how the IDynamicRemotingHelper.PortalLocation method is implemented and also what the DynamicRemotingProxyLocation enum looks like. Also, how are you parsing out the appropriate Url and what does the relevant section in your config file look like. Sorry for all the questions <g>.
Thanks!
No problem. I know sometimes I also can't figure out how certain things work.
First a little background on my environment. We have 4 offices (I'll call them E, M, BR, and P - abbreviated of course). Each office could potentially have a portal but for now we just want to add a second. Currently E has a portal and we're adding P as a second.
The IDyanmicRemotingHelper.PortalLocation would be up to you. For me I need to base it on data in the object, so if my object Foo implements it and I base it going to a particular location on whether Bar is "sober" or something else, I could implement Portal Location as
public DynamicRemotingProxyLocation PortalLocation()
{
if (this.Bar == "sober")
return DynamicRemotingProxylocation.E;
else
return DynamicRemotingProxyLocation.P;
}
As for the DynamicRemotingProxyLocation enum, it's just a enum with E, M, BR, and P. Nothing special.
The URL is up to you how you want to parse it. Like I said you could probably modify things further and make room for multiple keys in the config file, but I didn't want to change ApplicationContext. You could just change your key to something like "{E}http://www.locationofE.com:{M}http://www.locationofM.com:{BR}http://www.locationofBR.com:{P}http://www.locationofP.com" and then just parse it with regualr expressions or something similar based on the return of PortalLocation.
Hope this helps!
Interesting. My experiments led my down the path of adding to ApplicationContext rather than modifying it. I have a added a new configuration section, DataPortalURLs to the app.config file. This is a set of name value pairs i.e. Environment Name and URL. ApplicationContext then has a new property DynamicDataPortalURLs that retrieves this config section and sets another new property DynamicDataPortalURL by retrieving the corresponding URL from the list that matches the environment the user has selected.
The beauty of the DynamicRemotingProxy I wrote based on your code is that the changes I have made will only make a difference if the application is specifically set to use the new proxy type. If it is to use the new type then I simply force the application to specify an environment before allowing any DataPortal calls. Once the user selects the environment from the list, the selected value is stored in a third new ApplicationContext property.
I now have been told there maybe a requirement for having different forms within an application access different dataportals - Sigh! On the face of it this doesn't seem impossible as I could just provide some method to reset the proxy object. However, I am a little concerned of the performance aspect here.... Anyway that is another story. Many thanks for your help, I think I have an acceptable solution now!
We had this exact same requirement, only with hosted controls in the browser. The control had to talk back to he web server environment it was hosted from. All we did was pass in the url we wanted from the server to the control. Then the value in the config file was updated with the new url passed in. It works well and was really easy. I don't understand Rocky's comment about not being able to change it on the fly...
From: DancesWithBamboo [mailto:cslanet@lhotka.net]
Sent: Friday, July 14, 2006 1:23 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] is it possible to change the DataPortalURL in code?
Copyright (c) Marimer LLC