Calling a Java Web service from silverlight throws an exception - c#

After my previous question HERE, I found the solution (well, part of it).
Here's the code for Java part:
#WebService
public class MyWebService
{
#WebMethod
public String myMethod()
{
return "Hello World";
}
#WebMethod
public int Add(#WebParam(name="a") int a,
#WebParam(name="b") int b)
{
return a + b;
}
public static void main(String[] args)
{
String address = "http://127.0.0.1:8023/_WebServiceDemo";
Endpoint.publish(address, new MyWebService());
System.out.println("Listening: " + address);
}
}
And Here is the Silverlight part:
private void SearchResultList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MyWebServiceClient proxy = new MyWebServiceClient();
proxy.AddCompleted += proxy_AddCompleted;
proxy.AddAsync(2, 3);
}
void proxy_AddCompleted(object sender, AddCompletedEventArgs e)
{
txtSearch.Text = e.Result.ToString();
}
But when I run this, e.Result throws an exception.
What am I missing/ How should I solve it?
Note that this code runs perfectly in C# Console application (when it's not async). But when I run the async code, it doesn't work.
Thanks in advance.

I guess you are getting a System.ServiceModel.CommunicationException when trying to access the Java Webservice from Silverlight.
There is nothing basically wrong with your code, and it should also work with async calls in C# Console App.
The main problem is that Silverlight (as a browser plugin) enforces some security restrictions that prevent a Silverlight Application to talk to another server than the one loaded from (defined by server name and port) without further configuration. This behaviour can be configured as described here (also search for "silverlight cross-domain calls" or "silverlight cross domain policy").
This restrictions (normally) do not apply to desktop or console applications so they'll work fine with the same web service.
To make your code work you need to host the Silverlight Application inside the same "project" / website than your webservice (so I suppose, the self-hosting webservice won't work and you need to switch to Java web project where the webservice is to be hosted). As the Silverlight Application basically consists of an enclosing HTML file plus the referenced binaries, you can host it on any server, e.g. Apache Tomcat.
Hope this helps.

Related

Xamarin.Mac handle incoming URLs

I have added url in my Info.plist and trying to handle incoming url like described in this article.
I'm trying to add this code
public override void WillFinishLaunching(NSNotification notification)
{
NSAppleEventManager.SharedAppleEventManager.SetEventHandler(this, new ObjCRuntime.Selector("handleGetURLEvent:withReplyEvent:"), AEEventClass.Internet, AEEventID.GetUrl);
}
[Export("handleGetURLEvent:withReplyEvent:")]
private void HandleGetURLEvent(NSAppleEventDescriptor descriptor, NSAppleEventDescriptor replyEvent)
{
Logger.Info("Calling url on running app");
}
It all works fine, when my application is launched and somebody clicks on a URL (containing this custom scheme).
However, in the case, if my app isn't started then system start is (which is good). Unfortunately, handleGetURL() isn't called.

c# 4.0 service as client to connect a signalr(1.2.2) hub

I worte a server class as DLTransMonCore.cs using C# .Net 4.0.
DLTransMonCore.cs in DLTransMonCore DLL Project
public void MonStart() {
var client = new WebSignalrClient();
client.HubUrl = "http://10.20.30.40/MyApp";
client.HubName = "MyAppHub";
client.InitialSignalrHub();
}
WebSignalrClient.cs in WebSignalrClient DLL Project
public string HubUrl;
public string HubName;
public void InitialSignalrHub() {
var hubConnection = new HubConnection(HubUrl);
var hubProxy = hubConnection.CreateHubProxy(HubName);
hubConnection.Start().Wait();
}
This server will connect to a web site by using signalr(1.2.2). And listen some ports use socket as a socket server.
1st Scenario,
I use a console application (Program.cs) to instance the DLTransMonCore class and start it.
Everything is work fine.
Program.cs
static void Main(string[] args) {
var core = new DLTransMonCore();
core.MonStart();
Console.Readkey();
}
2nd Scenario,
I make a windows service (Service1.cs) to instance DLTransMonCore class and start it. When I try to launch the "Service1" in Windows Services, the "Service1" will start for about 10 seconds and then auto stopped by Windows.
Service1.cs
protected override void OnStart(string[] args) {
var core = new DLTransMonCore();
core.MonStart();
}
I wrote a log file to find which line last executed was:
hubConnection.Start().Wait(); (in WebSignalrClient.cs),
and it never reach the next line.
3rd Scenario,
I make another windows service (Service2.cs) to instance WebSignalrClient directly. And this "Service2" start successfully. (hubConnection.Start().Wait(); is executed successfully and reach the next line)
Service2.cs
protected override void OnStart(string[] args) {
var client = new WebSignalrClient();
client.HubUrl = "http://10.20.30.40/MyApp";
client.HubName = "MyAppHub";
client.InitialSignalrHub();
}
Why the Service1 be fail and the Service2 be success?
Any comment will be appreciate!
Edit:
The description of this post is simplify from my "Original Solution". The Original Solution has lots of Models, Repositories, Interfaces, Utilities, Extensions, Projects...etc.
So I have to simplify it to describe my problem.
But I just created another "New Solution", with the minimized code to test Scenario2 and Scenario3.
Then I found the "New Solution" were worked. It's really bother me...
Now I have to retest and review my code in the "Original Solution".
But if you have any suggestions or comments, please still comment it.
Thank you!
Edit 2:
Dear all, This pattern is no problem.
I found my problem in the "Original Solution".
The problem is : NullReferenceException.
The reason is : When Windows starts the Service, the working directory IS NOT where your Service.exe existed.
In my solution, I have my customize configuration file in that Service's location. And the Service will get the configuration by using the filename directly. Then, the Service will got a null object, and the NullReferenceException when Service Starting is trying to access the config.
I can't explain why but i had the same issue as i wanted a self hosted server using windows service and i never figured out why it was so unstable, what i can suggest is to use Owin selfhost as i switched to it using signalR and it's much more reliable than windows service.

Detecting Web vs Windows application

We have a library that is shared in .net between both Web and Windows (forms and console) applications. When used as a Web application, a couple of variables need to be read from cookies. Otherwise it needs to read the same variables from the Windows registry. I cannot seem to work out a good solution to doing this such that the same library compiles for all environments. Specifically, the web libraries for reading cookies would not be included in the Windows apps (and thus break the compile), let alone detecting one environment vs another. Does anyone have a solution to this?
If you host in IIS you can read Environment.GetEnvironmentVariables("APP_POOL_ID") and then act accordingly if the variable exists
Depending on architecture of your library, this information should be provided by the client code. I.e you provide some abstraction layer that will be up to client code to fill in.
I'll show a simple example of what I mean. In your library you have an interface like this:
public interface ISettingsProvider
{
public string GetSettingA();
public string GetSettingB();
}
And then your library code that needs access to settings will have to take a dependency on ISettingsProvider:
public class MyLibraryClient
{
private readonly ISettingsProvider settingsProvider;
public MyLibraryClient(ISettingsProvider settingsProvider)
{
this.settingsProvider = settingsProvider;
}
public void MyAwesomeMethod()
{
var settingA = settingsProvider.GetSettingA();
// do more stuff with your settings
}
}
Then your client code should implement ISettingsProvider:
public class WebSettingsProvider : ISettingsProvider
{
public string GetSettingA()
{
// go get the value from cookies
return Cookies["MyCookie1"];
}
public string GetSettingB()
{
// go get the value from cookies
return Cookies["MyCookie2"];
}
}
And very similar thing goes for settings stored in registry.
And when client code is accessing your library, they will have to instantite an instance of settings provider and give it to you.
This way your library does not know anything about web or Windows. You got to keep your code cleaner and it is all a lot more testable. And you don't have to take dependencies on System.Web and ultimately push that depdency on client code that does not work with web, i.e. Windows applications.
I know you have said you are limited in the amount of changes you can do. My answer to this is: you can't make an omlet without breaking eggs. This will be the most clean way to do what you want, everything else will have drawbacks.
In a Web-Environment you should have HttpContext.Current. If you are calling the same from the Console (or a WinForms-Application) this should be null instead of the Context.
To access this you need a reference to Sytem.Web. There should be no issue when you add this reference and access your backend from the Winforms-Application.
Example:
public bool ImInDaWeb() {
return System.Web.HttpContext.Current!=null;
}
Even in a web-application, HttpContext.Current can be null, but as you are needing this detection for reading/writing cookies you will have to detect this within a valid request already (and not on Application start for example).

Web service error when invoked from web form

I have a program that utilize a web service. When this web service is tested on its own (run on ie AS .asmx) runs fine but when tried to be called from inside the web form it produces the following error:
Client found response content type of 'text/html; charset=utf-8', but expected 'text/xml'.
The web servce is:
public Check1 () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public void check2(string destination)
{
Server.Transfer(destination);
}
}
And the web form from which is called is:
protected void Button1_Click1(object sender, EventArgs e)
{
localhost.Check1 new2 = new localhost.Check1();
new2.check2("Ipal_apoth_page.aspx");
}
A web service is intended to be a data interface, not a web page server, which is why XML is expected. Web service protocols use XML format for their communications, e.g. WSDL or SOAP. The .aspx page you attempt to transfer the processing to will return HTML.
It may be that when you tried it in a browser, the browser was permissive enough to interpret the repsonse from the web service in the way you wanted even though that is not how it is meant to be used.
A better thing to practise with would be something simple like adding two numbers.

Web services and client DLL

I have a web service and a client DLL. The web service uses an Oracle database.
For testing the client DLL, I copied the web service and made it point to a test database. Then I copied the client DLL and added this test web service using "Add web reference".
What I would like to do is to use one web service and one client DLL but be able to tell the client DLL to use either use the test or production database rather than two identical web serivces and client DLLs.
Edit
I mis-stated the issue. What I need to do is use one client DLL and two web services (one production version, one development/test version) and be able to, somehow, tell the client DLL which web services to use.
This is a sample of how the web service, client DLL and client app are used:
public class DSSService : System.Web.Services.WebService
{
public DSSService()
{
}
[WebMethod(MessageName = "GetFacility", BufferResponse=true, Description = "blah.")]
public Facility GetFacility(string sFDBID, string sZip, string sFinNo)
{
Facility oFacility = ...;
...
return oFacility;
}
....
}
Client DLL:
namespace DSSConfig
{
string sWSURL;
public class Config
{
public Config()
{
}
public void SetWSURL(string sURL)
{
sWSURL = sURL;
}
public Facility GetFacility(string sFDBID, string sZip, string sFinNo)
{
DSSService Proxy = new DSSService();
proxy.Url = sWSURL;
Facility oFacility = Proxy.GetFacility(sFDBID, sZip, sFinNo);
return oFacility;
}
In client application, having DSSConfig DLL as reference:
DSSConfig oConfig = new DSSConfig();
oConfig.SetWSURL("http://myserver/WebService1/service.asmx");
oConfig.GetFacility("blah", "blah", "blah");
What you need to do is change the WEB Service to take a parameter that it will use to construct the connection string to the DB.
Then change client DLL to pass that parameter as part of the call or connection.
Then you can configure the Client DLL to using any technique you like to pass the parameter. My suggestion is perhaps derive a class from the generated proxy in the client DLL and use this in the client code.
Without specific implementation details I can't be more precise.

Categories

Resources