A WCF call error occurred during the distributed computing prototype today. The error message channel is in an error state. After tracking and debugging, it is found that the cross-origin call problem occurs.
The problem scenario is as follows: client C calls the remote service through WCF, and the service s enables a new applicationProgramThe AD1 domain dynamically loads the Target Assembly, executes a Cl-like method m in the Assembly, and returns the return value (type: T1) of the method to the client C. although this application domain AD1 belongs to the same process as the primary application domain, it cannot directly access each other and must be implemented through remote calls, as long as the objects involved in this remote call are inherited from marshalobjectbyref, this remote call does not need to be implemented through remoting as usual, and DOTNET will automatically process it. DOTNET adopts the transparent proxy method (similar to the AOP Implementation Method in my previous spring technology blog), and the proxy class is dynamically generated. In general, this is no problem, but if you directly return the object returned by calling the target method to the WCF client, the problem will arise and an exception will be reported in the message channel status. Why is this happening? The reason is as follows: Because the classes involved in this process generate a proxy class dynamically, the actual type of the object returned by calling method M is not T1, it is a proxy subclass TP1 of T1. Note that because TP1 is a subclass of T1, based on the Object-oriented Inheritance principle, the parent class can be used, and all subclasses can be used, therefore, no type error occurs during compilation and running. In general, this is okay, because you can access the proxy object by using the T1 type variable, but you can directly use the returned value object as the return value of the WCF Service method, because the actual type (that is, the actual type of the object instance, which is called TP1 in the preceding call) is serialized in WCF, the server can use this type for serialization, the TP1 type exists, but it cannot be deserialized back when it arrives at the client. Because the agent TP1 is dynamically generated and only exists on the server, and the client does not exist, an error is reported. Of course, this error was reported in a general sense, which caused me to find the cause after debugging for half an hour (distributed program tuning itself is a rare event ).
To find the cause of the problem, the solution is simple: re-create an instance of the return type, clone the value of the type returned by cross-origin to this instance, and then return the newly created instance object.
This error is concealed mainly because the proxy objects accessed across application domains are dynamically generated by DOTNET and do not need to be intervened by programmers.
PS: this is also a special point to pay attention to in the C # coordination and resistance to changes.
Supplement: when you add a WCF host service, a port can only be owned by one application. If you want to start multiple host service applications on one machine, you need to perform port-level separation, the path and service name can only be distinguished in one application. Otherwise, an error such as the IP address and port listening being occupied will be reported. In addition, since a service requires a host, we recommend that you do not use the host service by yourself. It is better to use IIS and was to host the service.
Supplement (): classes involved in cross-origin calls need to be inherited from marshalbyrefobject. It is best not to use this class for WCF communication parameters or return values, which may cause inexplicable serialization errors (sometimes, yes, sometimes it does not work, but the error rate is very high ). The conclusion is that the participating classes used for cross-application domain access do not participate in WCF communication. If you really want to participate, you need to set the standard contract attribute (datacontractattribute, datememberattribute) for this type. To debug this error, I wasted more than two hours. I think this is a bug in Microsoft WCF. Either, you can, or you cannot. Sometimes the serialization is normal and sometimes the serialization is wrong (on the client proxy side ).