I built a very simple .dll in C# to call from a simple ColdFusion page. Everything works fine if I pass in literal values but as soon as I try and pass in a variable (#rollYear#) I get a message stating it can't find the method anymore.
The coldfusion page sets up my .dll like this:
<cfobject type="dotnet" name="getParcelData"
class="soapDLL.GetSecuredParcelByAPN"
assembly="{path}\soapdll.dll">
I then call it like this:
<cfset output = getParcelData.getData("46546504654","cy","#rollYear#")>
If I use the code above I get an error, "The getData method was not found.". If I replace the #rollYear# variable with a value (2017 for instance) then it works fine. In my tests I've set the #rollYear# variable via the CFSET function before I call the .dll.
I've been banging my head on this all day. Has anyone had similar experience? The .dll is very simple. It just takes 3 variables and based on those sets up what SOAP service to call to pull back some data. For reasons that are too complicated to explain I can't do the SOAP call from within ColdFusion, it has to go through a .net dll.
Any help would be appreciated, I don't have much hair left. :)
Whenever you work with Java or .NET components, you need to pay extra attention when passing ColdFusion variables/values to those methods. If the data types to not match exactly, you will encounter an error message telling you that the method does not exist or does not match the method signature.
ColdFusion offers javaCast() to explicitly cast to the required data type. Cast your arguments accordingly and it should work out in most cases.
Basic example:
A method that expects an integer will throw an error when you pass methodThatExpectsInt(123), because the 123 literal is internally stored as a string (or Double) by ColdFusion. By passing it via methodThatExpectsInt( javaCast("int", 123) ), the data type will be properly casted and match up.
Related
TDLR
After researching and testing this problem more (see the update below), I reached this answer:
What I need is to actually pass an object by reference to a DLL created with Matlab using the type-safe API, but this does not seem to be possible. Correct?
I suspect that this is the direct result of them using WCF to facilitate interprocess behind the scenes as mentioned here. The fact that it is a DLL (which essentially handles the communication) confused me very much.
So is there a quick way to achieve this (e.g. COM objects come to mind, but I have not worked with them before)?
/TDLR
I am trying to figure out how to pass a .Net object to a Matlab method and then call a method on that object. In my Matlab Code I have something like this:
DOTNET_object = DOTNET_classFactory.GetStage();
CallDOTNET_class_method_DoSomething(DOTNET_object);
Where DOTNET_classFactory and DOTNET_object are both instances of .Net classes and CallDOTNET_class_method_DoSomething would be a Matlab function defined like this:
function CallDOTNET_class_method_DoSomething(DOTNET_object)
DOTNET_object.DoSomething();
end
I now need to perform the same two lines above in from within C#, after creating a DLL with the function CallDOTNET_class_method_DoSomething. However I am unable to figure out how to pass DOTNET_object to my function in the C# code. Here is what I have:
Class1 = new Class1();
Class1.CallDOTNET_class_method_DoSomething((MWArray) DOTNET_object);
I have found this answer , but I am not sure if this is the correct way to go. Would I have to package all the .Net objects (I will need to pass a total of 3 objects) I want to pass to my Matlab function inside an object-array and that unpack the within or is there a more elegant way, where I can pass the three objects separately and explicitely?
Update:
As explained here here I have now tried using the type-safe API in Matlab and by creating an interface to define the arguments of function CallDOTNET_class_method_DoSomething(DOTNET_object). I have been able to compile it in Visual Studio. Unfortunately, when I run the it I get the following exception:
Result StackTrace:
at MathWorks.MATLAB.NET.Arrays.MWArray.ConvertObjectToMWArray(Object objIn)
at MathWorks.MATLAB.NET.Utility.MWMCR.UnpackArgArray(Object[] argArray, Object[] varArgArray)
at MathWorks.MATLAB.NET.Utility.MWMCR.EvaluateFunctionForTypeSafeCall(String functionName, Int32 numArgsOut, Object[]& argsOut, Object[] argsIn, Object[] varArgsIn)
...
... removed, because it is confidential
...
Result Message: System.IO.InvalidDataException : Input data type unsupported by MATLAB .NET Assembly
From the message I deduce, that my endeavor is in vain and that you cannot pass anything other than primitive/value types (by that I mean, int, double, bool, etc.) to a Matlab DLL as written here here?
Result Message: System.IO.InvalidDataException : Input data type unsupported by MATLAB .NET Assembly
Am I correct in that assumption or is there any workaround?! In other words/another aspect: What I need is to actually pass an object by reference to the DLL created with Matlab and this does not seem to be possible. Correct?
We have a project that uses multiple domains (with tenants) and when we need to generate an absolute url we used to do this:
var forgotUrl = Url.Action("Forgot", "Account", null, this.Request.Url.Scheme);
That worked well, and sometimes you need absolute urls when for instance sending out emails with reset password links.
However, we have now implemented SSL with reverse proxy, meaning that this.Request.Url.Scheme no longer gives us the correct domain.
Therefore we have to do something like this instead
var forgotUrl = CurrentHostWithSchemeWithoutTrailingSlash + Url.Action("Forgot", "Account");
To simplify we have made an extension method, like so
Url.AbsoluteAction("Forgot", "Account", *data*)
And that all works like expected, so everything is well, however, you can still mess upp by writing a line calling the original Url.Action and sending in this.Request.Url.Scheme.
So my question is simply: Is there any way of blocking usage of that, either hiding it, or giving compiler errors, warnings, anything?
For general case where the method is class member your real option is to find usages and update code. You can either manually find all the cases of such functions with "find all usages" (VS or VS+R#) from time to time or use automated tools. If you use VS 2015+ see Finding all references to a method with Roslyn. For older versions or build tests you can scan code e.g. by adding unit test that will load assembly, parse IL and assert wrong methods.
For this particular case Since Url.Action is extension method - additional option is to create another extension method with the same signature in another static class that is visible by default in the view (e.g. namespace System; public static class MyHack{ ...Action(UrlHelper...) so compiler will find 2 variants of the method and show an error.
Also educating developers (i.e. during code reviews) and available existing code is often enough. If there is already existing example in the project that does this correctly there is good chance that it will be simply copy-pasted.
I am hosting a .net webservice written in c#. In one of my web methods, I'm expecting a few inbound parameters, all of which are strings. The final string is actually a string of xml (I started out doing a dataset for this, but read this was a big no-no, so went this route instead).
The xml (as a string) is incredibly simple.
<FriendsArray><Friend><FriendSocialID>123456789</FriendSocialID><FriendName>Test Test</FriendName><AvatarImage>https://www.imagelocation.com</AvatarImage><FriendGender></FriendGender></Friend></FriendsArray>
With the <FriendsArray> being the bounder, and the <Friend> node being repeated n times. On the webservice side, I take this string, serialize it into xml and deal with the data.
When the webservice is run locally on the server in Visual Studio, it works perfectly, no issues. When the webservice is run locally and attached to a test calling program that simply emulates passing these parameters, including the FriendArray to the webservice, again, right as rain, no issues, works perfectly.
Real world scenario of calling the webservice foreign (either via emulation, like SoapUI or XMLSpy, or directly from the app that is meant to call it) it bombs the service. No error is returned, or empty response object, it completely fails, and returns nothing.
The second I remove this FriendArray (its optional on the codebehind), it works perfectly.
Is there some inherent issue to doing this the way I am trying to? If so, is there an easy alternate way that requires not a huge amount of recoding? Thanks!
Apparently "<" and ">" are reserved in XML. Wasn't aware of that. All I had to do was escape them with < and > in the string, and it works perfectly now.
I have written a C dll containing a function that takes 4 arguments and returns a number. Then I created a C# application and called the dll function using PInvoke. Everything works fine. Then I changed no of arguments in the dll function from 4 to 3. But I did not change the method signature (DllImport method signature) in C#. To my surprise, the call still succeeds from C# but I get some unexpected value returned from the dll function.
I was expecting an exception but the call went through. Is there any way to strictly enforce arguments count when making function calls using P/Invoke?
There is no way to enforce parameter count to match. You simply have to get it right. The same is true for calling convention, parameter types and so on.
Unlike managed code, native DLLs do not have metadata describing how they must be called.
If you enable the p/invoke stack imbalance MDA then you will at least be able to detect the error you made at runtime.
We created a soap server using php and few of the functions give a varying outcome in terms of the xml elements depending on the arguments passed through.
To explain further, a function takes in argument a and depending on the data received it can return either of the two different arrays(complextype) with distinct number of child elements.
e.g.
if a =9 then outcome is array/struct ,,,,
a[delta]=20 ,,,
a[sigma]=yellow
if a =3 ,
a[aTotallyDifferentBallgame]=Omaha ,,,
a[t]=1 ,,,
a[theNumberOfElementsCanVary]=yup
In order to explain this possible variance we utilized choice in the schema, thereby trying to intimate that the outcome can be any single element within choice be it simple or complextype.
Now theoretically it sounds logical and it works fine with php's soap client but WHEN we tried to use the add Service Reference feature of the visual studio in a form application ; the application failed to create code for it citing that the use of xs:choice is not allowed for some unfathomable reasons.
Now what I would really like to know is what changes do I need to make to my wsdl or soap server to make this work. We thought a work around was by fixing the outcome to only one possible scenario and utilizing a completely different function to determine the outcome of the other thereby abstaining from use of choice but frankly this seems too redundant and weird.
Is there anything I have missed? Please let me know any ideas you have. Thanks!
The create service reference machinery tries to map the schema to C# classes, and there is no structure in a C# class corresponding to a choice in the schema - a class cannot have a value for either one property or another one but not for both.
My suggestion would be to replace choice with sequences of optional elements, the corresponding C# class will have properties for each of the elements - and only one of them will have a value, the other will be null, because the PHP service returns a value for only one of them at a time.