3.6 version breaks remoting support?

3.6 version breaks remoting support?

Old forum URL: forums.lhotka.net/forums/t/5939.aspx


AaronH posted on Thursday, December 04, 2008

We've recently upgraded from the CSLA 3.5 to 3.6.Latest and .NET Remoting does not appear to be working correctly.  There are actually 2 issues going on:

1.) Trying to generate WSDL is throwing an exception:

http://localhost/remotinghost/remotingportal.rem?wsdl

Generates:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Runtime.Remoting.MetadataServices.WsdlGenerator.RealSchemaType.PrintMessageWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
   at System.Runtime.Remoting.MetadataServices.WsdlGenerator.XMLNamespace.PrintMessageWsdl(TextWriter textWriter, StringBuilder sb, String indent, ArrayList refNames)
   at System.Runtime.Remoting.MetadataServices.WsdlGenerator.PrintWsdl()
   at System.Runtime.Remoting.MetadataServices.WsdlGenerator.Generate()
   at System.Runtime.Remoting.MetadataServices.MetaData.ConvertTypesToSchemaToStream(ServiceType[] serviceTypes, SdlType sdlType, Stream outputStream)
   at System.Runtime.Remoting.MetadataServices.SdlChannelSink.GenerateSdl(SdlType sdlType, IServerResponseChannelSinkStack sinkStack, ITransportHeaders requestHeaders, ITransportHeaders responseHeaders, Stream& outputStream)
   at System.Runtime.Remoting.MetadataServices.SdlChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)
   at System.Runtime.Remoting.Channels.Http.HttpHandlerTransportSink.HandleRequest(HttpContext context)
   at System.Runtime.Remoting.Channels.Http.HttpRemotingHandler.InternalProcessRequest(HttpContext context)
If we roll back to version 3.5.X, I receive the WSDL just fine.
2.) I'm assuming that this issue is tied to an issue that we're having regarding inheritance and invalid casting due to type mismatch cast exceptions when setting or retrieving values from FieldManager (GetProperty and SetProperty).  We have addressed these issues with the 'dummy' variables as recommended in the other posts, but it is still not working under 3.6 when using .NET Remoting.
Anyone have any issues with this or is the development team aware of this issue?
Thanks!

RockfordLhotka replied on Thursday, December 04, 2008

I see the same WSDL problem, though I don't know the cause.

The only meaningful change to remoting in the past few years is that the Delete() method now accepts an optional generic parameter like Create() and Fetch().

I must confess that I haven't been using (or testing) anything beyond the WCF channel for a while now. That's probably not good, but it is somewhat hard to imagine why anyone would choose to use remoting :)

I'll add this to the bug list.

AaronH replied on Thursday, December 04, 2008

Hahah, I know, I know.  I've been swamped with other learning activities (ie WPF and your latest framework ;) and haven't had a chance to figure out how to set up the WCF channel yet.  I'll get there.

Any ideas on #2?  Unfortunately we have already converted all of our GetProperty and SetProperty methods to go without specifying generic types, and I don't want to revert back to it (that would take hours).  Is that something that you can easily test on your end?

Thanks again!

RockfordLhotka replied on Thursday, December 04, 2008

I don’t understand the issue with number 2?

AaronH replied on Thursday, December 04, 2008

It's regarding this issue:

http://forums.lhotka.net/forums/thread/26402.aspx

If I run my code against local dataportal, it works.  However, running against remoting server, the index of the items don't match up, and I get type conversion errors.  In each subclass, I have implemented created the static dummy field and initialized it to 0.  This initialization occurs both in the constructor and OnDeserialized() in each subclass.

Does that make sense?

RockfordLhotka replied on Thursday, December 04, 2008

That doesn’t sound like the same issue – hence my confusion.

 

If the RegisterProperty() calls don’t work you’ll get null ref exceptions or property not registered exceptions.

 

If I understand you correctly, you are getting some sort of casting or type mismatch exception?

 

Rocky

 

AaronH replied on Thursday, December 04, 2008

Sorry for any confusion, I thought it was the same issue.  Here's what's happening in detail:

Here is my class hierarchy ClassB --> ClassA --> BusinessBase

Within ClassA...

private static PropertyInfo<string> SomeValueProperty = RegisterProperty(new PropertyInfo<string>("SomeValue"));

public string SomeValue

{

   get { return GetProperty(SomeValueProperty); }

   set { SetProperty(SomeValueProperty, value); }

}

Here is the affected statement:

ClassA.SomeValue = "I'm a string";

What's happening is that when SetValue() within the setter{} is called, it calls FieldManager.GetFieldData(propertyInfo).  Within GetFieldData(), it uses the index of the property to retrieve the field from _fieldData (_fieldData[prop.Index]).  The problem is, it's retrieving the wrong field because the _fieldData array does not contain the count that it should contain. 

So in my specific scenario, passing "SomeValueProperty" in retrieves the field "SomeOtherIntegerProperty" of type int instead of "SomeValueProperty" because the indexes don't match.

This code works fine if going against my local portal, but when using the remoting portal is when it's problematic.  I am positive that the .dll's in the remoting bin folder and in my project are the same as well.

Does this make sense?  I realize this might be confusing, but hopefully you've seen this or are able to reproduce it.

Thanks again!

RockfordLhotka replied on Thursday, December 04, 2008

It does sound like a different set of symptoms from the same problem. Interesting that this is the first encounter with this symptom.

 

Can you please use the debugger and ensure that the OnDeserialized() method is being invoked as we expect – on the client when the object graph comes back from the server?

 

My suspicion is that it isn’t being called, so the static _forceInit (or _dummy) field isn’t being set on deserialization – on either the server or the client, one of the two.

 

Thanks!

 

Rocky

AaronH replied on Thursday, December 04, 2008

Yes, OnDeserialized() is being invoked, and it is overriden in each subclass as recommended.  We thought maybe having the private constructor set the _dummy value was an issue too, but no luck there.

Aaron

RockfordLhotka replied on Thursday, December 04, 2008

And you do the force init in every one of your classes? Not just the leaf node class, but the base classes too?

 

From: AaronH [mailto:cslanet@lhotka.net]
Sent: Thursday, December 04, 2008 8:52 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: RE: 3.6 version breaks remoting support?

 

Yes, OnDeserialized() is being invoked, and it is overriden in each subclass as recommended.  We thought maybe having the private constructor set the _dummy value was an issue too, but no luck there.

Aaron



AaronH replied on Friday, December 05, 2008

Ok, so as it turns out, I believe the issues to be unrelated.  The remoting still works, but here's what I had to do (which I'm terribly embarrassed about not catching in first place):

private static int _forceInit;
private New() : base()
{
    _forceInit = 0;
}

protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
{
    _forceInit = 0;
    base.OnDeserialized(context);
}

It's important to call the base constructor and method all the way down the inheritance chain.  I was so rushed when finding the initial solution to the _dummy fix that I just copied and pasted what I found in a previous post, which didn't include the calls to base.

So to wrap things up:  I'm still getting the issue when requesting the wsdl, however, I'm able to successfully use .NET Remoting in conjunction with CSLA 3.6.Latest and a 4 level inheritance hierarchy.

Thanks for all of your ideas!

RockfordLhotka replied on Friday, December 05, 2008

Aaron, I’m glad you found the answer!!!

 

I did add the wsdl issue to the bug list – though it falls below the threshold for fixing before RTW of 3.6 since remoting actually does work regardless.

 

Rocky

 

jkellywilkerson replied on Wednesday, September 16, 2009

Greetings All,

Has there been any update on the WSDL issue? I seem to be having the same issue with version 3.7.0.

I was having a difficult time getting things working on a new machine. I went through all my standard processes that worked using previous versions, 2.x and 3.0.x, and my client would not work through remoting.

I checked for the wsdl response from the app server and got an error, so I started troubleshooting from that end. That lead me to this thread and no real answer except that remoting should continue to work.

I decided to run the client through the VS in debug mode and it worked fine. I then tried it using a shortcut to the .exe in the bin\debug folder (in order to test without VS debug mode which did not work before) and it worked as well. Not sure why it didn't work until I ran from VS. Any ideas? I know that doesn't give you much incite into how things are setup here, but I just transitioned to version 3.7.0 from 3.0.1 and have never seen this behavior before.

Thanks,

Kelly.

RockfordLhotka replied on Wednesday, September 16, 2009

Are you using Cassini for your testing? If so, you'd have needed to use VS to get Cassini running, otherwise the "server" endpoint wouldn't be there.

jkellywilkerson replied on Wednesday, September 16, 2009

Well, that's the crazy thing. I don't normally use Cassini or even run it within VS. I do if I need to set breakpoints on the client side, but I've had the app server portion of this thing running without any issues for a couple of years now. I generally publish everything to a test app server to get a general feel for an actual client experience.

Here is the app setting entry in the app.config:

add key="CslaDataPortalUrl" value="http://development-wks/BitsyRemotingHost/RemotingPortal.rem"

The "localhost:xxxx/Host/..." line has been removed for some time.

Like I said, it was just strange that as soon as I ran it from within VS, the other method worked just fine. I will copy the client completely off of this development workstation and see what the results are.

Thanks, Kelly.

ajj3085 replied on Friday, December 05, 2008

RockfordLhotka:
I must confess that I haven't been using (or testing) anything beyond the WCF channel for a while now. That's probably not good, but it is somewhat hard to imagine why anyone would choose to use remoting :)


Well, I'm on 3.6 and still using remoting, and haven't encountered this issue.

Not to high-jack the thread... but is there a simple way to switch from remoting to Wcf?  Currently my deploy process copies the clickonce files to a known location, and copies business layer files to the wwwroot/RemotingHost/ location.  If switching is as simple as changing the configuration files, that would be great. 

RockfordLhotka replied on Friday, December 05, 2008

I don’t believe the problem is due to remoting. I suspect there’s a missing bit of code to trigger static field initialization on either server or client. I’m seriously considering adding a bit of reflection code to avoid this static field issue. Unfortunately I can only do so in .NET, because in SL the reflection is too limited. So the use of _forceInit appears totally unavoidable in SL L

 

To answer your question about switching to WCF, the answer is that it is purely a config thing – from the CSLA perspective.

 

You simply need to do this:

 

1.       Upgrade your server to .NET 3.5 SP1 (assuming CSLA 3.6)

2.       Add a svc file to your data portal host web site

3.       Add a few lines of config to web.config – mostly boiler-plate

 

Now your server is ready to go. Then you do this on the client:

 

1.       Add a few lines of config to app.config – mostly boiler-plate

2.       Change the CslaDataPortalProxy to use the WcfProxy

 

That should be it.

 

The only caveat I’ll throw out, is that WCF has a bajillion configuration options. Actually getting it configured and running in a production setting can take some time, because you need to get all the options set as you need them. The big help with this is that Microsoft Patterns and Practices put a guidance book on codeplex a while back, and it is invaluable in getting WCF properly configured.

 

That’s not really a CSLA thing – the steps above will make CSLA happy – it is a WCF thing.

 

Rocky

 

ajj3085 replied on Friday, December 05, 2008

Ok, sounds simple enough.  I'll have to update my deployment setup to make sure to include the svc file, but that shouldn't be difficult.

I'll check for that book... the configuration is one of the reasons I've steered clear for now... but I can't let sit using remoting forever..

Thanks!

AaronH replied on Friday, December 05, 2008

Actually, I suspected that WCF setup would be easy as the only thing that truly differs (aside from config settings) is the addition of the .svc file.  I managed to create a local web application in IIS (7.0), copy the PTracker WcfHost files into that, and point the PTracker WPF app config to it.  Worked without a hitch.

I then copied my project's remoting host contents into a new web app, and created the svc file.  Pulled up the svc file in the browser without a hitch. 

BUT, we're using Windows Authentication, not CSLA, and I received the CommunicationException:

The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.

I'm not looking for you to debug this for me, just wanted to point out that moving from .NET Remoting to WCF is not as easy as it seems (without having a decent grasp on WCF and authentication). 

Of course, if you're familiar with this issue and have a quick fix that you can share, I'll accept it :)

ajj3085 replied on Friday, December 05, 2008

Ha... sorry, I wish I did.  As Rocky said, it's probably a configuration problem.  That seems to be the huge issue, and why I haven't really looked into Wcf yet.  Complicating things for me would be that I'd also need to figure out how to compress the traffic as I'm doing now using the CompressedDataPortal from the community.  I have an office in another town that communicates with our database server here over a T1 link, so I need to keep things over the network as quick as possible.

JoeFallon1 replied on Friday, December 05, 2008

RockfordLhotka:
 
 I’m seriously considering adding a bit of reflection code to avoid this static field issue. Unfortunately I can only do so in .NET, because in SL the reflection is too limited. So the use of _forceInit appears totally unavoidable in SL L
Rocky 

Please do. I am about to upgrade to 3.6 and I hate the idea of tweaking every single class in a deep inheritance hierarchy to deal with this issue.

Joe

 

RockfordLhotka replied on Friday, December 05, 2008

My only fear with this, is that it will introduce a difference between .NET and SL that could cause confusion. People with .NET classes that move to SL would need to go add the _forceInit code throughout, because there's simply no way to get SL to reflect against private fields.

To be clear, the reflection I'm talking about is a bit of code that would trigger in the field manager on the very first request for the property list for a given type. The code would loop through each type in the inheritance hierarchy, reading one static field value from each type (which ever one it finds first).

This should have no meaningful perf impact, and would solve the _forceInit issue rather entirely. But it only works if you can reflect against a static field - which you can't in SL :(

JoeFallon1:

RockfordLhotka:
 
 I’m seriously considering adding a bit of reflection code to avoid this static field issue. Unfortunately I can only do so in .NET, because in SL the reflection is too limited. So the use of _forceInit appears totally unavoidable in SL L
Rocky 

Please do. I am about to upgrade to 3.6 and I hate the idea of tweaking every single class in a deep inheritance hierarchy to deal with this issue.

Joe

 

Copyright (c) Marimer LLC