Wednesday, February 13, 2008

.NET Remoting in non-domain enviroments

Wow, talk about a hair puller ... I hope this helps someone working on a .NET application where they need to communicate in a domain-less or workgroup situation. Basically my application is run on almost strictly Windows XP machines, but the user can choose to make their application the "server", thus starting a TCPServerChannel.



Server Code --------------

if(makeMeAServer) 
{
RemotingConfiguration.Configure("config file", true);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SomeRemoteableObject), "SomeMethod", WellKnownObjectMode.SingleCall);
}


Server Config File ------------

<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" secure="true" protectionlevel="EncryptAndSign" port="8080">
<serverproviders>
<formatter ref="binary">
</formatter>
</serverproviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
Thanks to .NET 2.0, the TCP channel can be secured, but the gotcha I ran into was that I couldn't authenticate the client (call it "WinXP Client") using a TCPClientChannel with the newly created server (call it "WinXP Server") in a workgroup enviroment.

Obviously this was because of a credentials issue. "No problem" I thought, I'll just add a new user who is valid on "WinXP Server" to "WinXP Client" with the same name and password. Pretty standard stuff to get NTLM to kick in. Guess what, it still didn't work!

WTF mate?



To make a long story short, after spending quite a bit of time on various seach engines and forums, it all boiled down to the fact that Windows XP has "Use simple file sharing (Recommended)" enabled by default for workgroup computers (maybe domained ones as well?). After I unchecked this option (Tools -> Folder Options -> View), it worked like a champ. I need to go back and see if passing username, password and domain(i.e. machine name) as parameters to the TCPClientChannel will work, but that's not necessary at the moment for me.

BTW, here is the client side config file and necessary code ...



Client Config File -----------------

<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" secure="true" impersonationlevel="Impersonation" protectionlevel="EncryptAndSign">
<clientproviders>
<formatter ref="binary" typefilterlevel="Full">
</formatter>
<serverproviders>
<formatter ref="binary" typefilterlevel="Full">
</formatter>
</serverproviders>
</clientproviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
Client Code -----------

RemotingConfiguration.Configure("Client.exe.config", true);
SomeRemoteableObject test = (SomeRemoteableObject )Activator.GetObject(typeof(SomeRemoteableObject), "tcp://remoteserver:8080/SomeMethod");
Console.WriteLine(test.LastNameOrWhateverProperty);

Friday, February 1, 2008

Some T-SQL help

This is mostly for my reference, but it might help someone else...

I needed to compile some information into an Excel spreadsheet from the main SQL DB. I needed one of the columns returned to be a concatenated value of a resultset.



For example, I wanted the end result to look like:



Column 1 Column 2

--------- ---------

Client A Account1, Account2, Account3



The normal result would have looked like:



Column 1 Column 2

--------- ---------

Client A Account1

Client A Account2

Client A Account3



After chasing around a few options, I ended up using a SQL function that took in the Client and using COALESCE + a variable, pulled the accounts into one varchar.

The function ended up looking like the following:

alter function fn_accountsforclient(@id int) returns varchar(8000) as 
begin
declare @returnVal varchar(8000)
select @returnVal = coalesce(@returnVal + ', ' + a.account, a.account)
from ACCOUNTS a
where a.clientID=@id
return @returnVal
I'm just wondering if there was another way using straight SQL Select statements (i.e could have been executed from Excel's DB Query) instead of using a function? Since T-SQL is not my main programming focus, I know I am seriously lacking at more efficient ways of doing things.