Mono for Android or Java and WCF - c#

I am currently using Mono for Android to develop a mobile application. I have been trying to consume a WCF web service by adding a web reference to it but I can't seem to make the call that way. I am now considering to bite the bullet and rewrite the code using Java which I am not as good at as I am with C#.
I have 2 questions:
How do I consume a WCF webservice using Mono for android.
If I am to use java how would I call a method that looks like the one below:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/MyMethod",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
void MyMethod(CustomObjectFromDataContract c_Object);
When I make the call I get a MessageBox that says Unhandled exception System.Net.WebException:. When I step into the code I see that the error happens when you call
[System.Web.Services.Protocols.SoapDocumentMethodAttribute ("http://tempuri.org/IMyService/MyMethod", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void MyMethod([System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] CustomObjectFromDataContract c_Object) {
this.Invoke("MyMethod", new object[] {
c_Object});
}
The invoke is the one throwing the exception.

I have resolved the issue. Here are the steps to make this work:
1. The service has to be a RESTful service
2. Instead of referencing Localhost (which I was in the generated code) use the IP address of the hosting machine. I think this is because Android runs in Dalvik VM which I suspect has a different local host from the one my Dev computer is using.
I did that and my service works now.

If you add a Web Reference, some references classes including a client should be generated.
You can then create an instance of the generated client and call MyMethodon the client.
So assuming you are using Visual Studio simply right click you MonoDroid project > Add Web Reference and enter the URL to your WCF service.
To call it you can do the following:
I have added a reference to a service with namespace Example.WebReference
I would then call it in the following way:
Example.WebReference.ServiceElement client = new Example.WebReference.ServiceElement();
var output = client.MyMethod(parameter);
Hope this helps.

Related

Cannot use r.net within a wcf service

I am trying to set up an R.net WCF service as a server to run R commands on.
I have set up a test WinForms application where everything works.
This is how I use it:
void init()
{
SetupPath()
engine = REngine.GetInstanceFromID("test");
if (engine == null) engine = REngine.CreateInstance("test");
engine.Initialize();
}
...
results.Add(engine.Evaluate(command).AsCharacter().ToArray());
I created an equivalent WCF service which should work exactly the same;
REngine.CreateInstance() returns a valid REngine object,
engine.Initialize() silently crashes my service. Try-Catch section is ignored so I cannot see what exactly is happening.
What is the correct way to use R.net within a WCF service?
What could be the reason of different behaviours?
Where can I see detailed logs of the crash?
Service calls which don't use R.net complete successfully.
Both winforms test application and WCF service are 64 bit (i need them to be). (I did not manage to set up a 64-bit IIS express application, so am using IIS instead).
I did not manage to find the reason of the problem, however, switching to R.NET.Community package did the trick.

Possible bug (?) xsockets.net console server

I'm trying to start development on xsockets.net service.
My server doesn't want to recognize any of CustomController implementation for a Console Application (server). Everything works fine in Web project.
I've noticed that XSocketPlugins property contains a list of plugins. My plugin is not on a list for console App and is registered for Web.
The source code is simple like in ReadMe.txt
using (var container = XSockets.Plugin.Framework.Composable.GetExport<IXSocketServerContainer>())
{
container.StartServers();
container.OnServerClientConnection+=container_OnServerClientConnection
Console.ReadLine();<br/>
}
Defining new controller
public class CustomController1 : XSocketController
{
public void OnMessage(...)
{
//do stuff
}
}
I'm able to connect to Generic controller using C# client and JS client.
Any ideas?
Env: Windows7 64-bit, VS2012, .NET 4.0
Yes, the bug is described here: known-issues and the work around is also described.
Regarding the comment, please post the code you use to connect with the Client API and maybe I can see something in there. There should not be any problems connecting from the clients API.

self host wcf add service reference

So I created winforms client and added wcf class library to the solution.
In winforms I do
ServiceHost svc = new ServiceHost(typeof(...), new Uri("net.pipe://localhost/MyNamedPipe")
and then svc.Open() which executes fine.
Now, how do I add a service reference so in same winforms I can get proxy for that wcf?
I only was able to generate that by using ASP.NET Development Server which started when winforms was ran and so I copied that url, stopped debugging (Development Server was still running) and then added a service reference from there. But that isn't correct I guess.
Of course I can reference wcf contract class directly and use it, but that is not proper either.
When you are controlling both ends like that, I prefer to use ChannelFactory:
NetNamedPipeBinding binding = new NetNamedPipeBinding();
EndpointAddress address = new EndpointAddress("net.pipe://localhost/MyNamedPipe");
ChannelFactory<YourInterface> factory = new ChannelFactory<YourInterface>(binding, address);
YourInterface yourInterface = factory.CreateChannel();
Have you tried adding a Service Reference... to the project, then entering your URI directly in the Address box of the dialog?
Note that this should be the complete URI, such as net.pipe://localhost/MyNamedPipe.
You can find step-by-step instructions from MSDN here.

Recycle App Pool on IIS6 using C#

I'm attempting to recycle an app pool on IIS6 programmatically through a web application. I have searched all over the net and found a bunch of solutions (Most involving impersonation) but none of them seem to work. The most common error I get is E_ACCESSDENIED despite entering a valid username and password. Can anybody point me in the right direction?
The solution I use for this sort of thing (Where you're trying to run a process from ASP.NET that needs administrative privileges) is the following:
Write whatever you need done as a Self hosted WCF service. Preferably an Http REST Service, so it's easy to call (even using just a browser for testing)
Make sure you service is run using an administrator account. You can use the task scheduler to make sure the service is running at all times as well as run using an Administrator account.
Execute methods on the service from your ASP.NET application using a WCF Client
And it works all the time no matter what "process" I'm trying to run from within an ASP.NET application.
Now as far are the details (code) is concerned let me know if you need help. The code below
is the code you'd have in a console application in order to make it a self hosted WCF Service.
In this case it's an Http service listening on port 7654.
static void Main(string[] args)
{
var webServiceHhost = new WebServiceHost(typeof(AppCmdService), new Uri("http://localhost:7654"));
ServiceEndpoint ep = webServiceHhost.AddServiceEndpoint(typeof(AppCmdService), new WebHttpBinding(), "");
var serviceDebugBehavior = webServiceHhost.Description.Behaviors.Find<ServiceDebugBehavior>();
serviceDebugBehavior.HttpHelpPageEnabled = false;
webServiceHhost.Open();
Console.WriteLine("Service is running");
Console.WriteLine("Press enter to quit ");
Console.ReadLine();
webServiceHhost.Close();
}
AppCmdService is a WCF Service class that looks like this (in my case). In your case you probably don't need a response from your service. In my case I'm getting a Json response. The actual implementation of what it is you're trying to do will be different obviously. But I'm assuming you already have that piece worked out. So simply call a method of that class from here.
[ServiceContract]
public class AppCmdService
{
[WebGet(UriTemplate = "/GetCurrentExcutingRequests/?", ResponseFormat= WebMessageFormat.Json)]
[OperationContract]
public IEnumerable<ExecutingRequestJson> GetCurrentExcutingRequests()
{
return CurrentExecutingRequestJsonProvider.GetCurrentExecutingRequests("localhost");
}
}
On your ASP.NET side, you don't really need a WCF client. All you need is a way to make an http call to the service. So you can simply use HttpWebRequest to make the call out to your service, which in turn execute your process.
Hope all of this makes sense?
Maybe this SO question helps you. There are several solutions (also for IIS6):
Restarting (Recycling) an Application Pool
IMHO the best you could do is to decide to go with a concrete approach an then when you run into an exception, to ask a concrete question with the source code of your approach. Otherwise it's just very vage to answer your question.

How to host a simple ASP.NET web interface in a Windows Services

For a simple appliance that runs on a Windows & .NET operating system, we need to create a simple configuration web interface to control it. Just like your router's configuration page, nothing more complicated than that.
Installing IIS or any other web server should be avoided, what we need is a self supporting process within a windows service on a basic windows XP installation + .NET.
Mono compatibility is a plus.
Thanks a million
Actually the easiest way is to use the built-in WCF stuff (.Net 3.5)... To do this you create a interface for your 'WCF' service that contains one or more methods that return Stream:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(UriTemplate = "/{*arguments}", Method="GET", BodyStyle=WebMessageBodyStyle.Bare)]
Stream Get(string arguments);
}
You can define several methods and arguments and let WFC do the work, or as the example above, push everything into a single method. The resulting implementation can access the full Uri and query parameters as follows:
public class ServiceType : IService
{
public Stream Get(string arguments)
{
UriTemplateMatch uriInfo = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;
WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
MemoryStream rawResponse = new MemoryStream();
TextWriter response = new StreamWriter(rawResponse, Encoding.UTF8);
response.Write("<html><head><title>Hello</title></head><body>");
response.Write("<b>Path</b>: {0}<br/>", arguments);
response.Write("<b>RequestUri</b>: {0}<br/>", uriInfo.RequestUri);
response.Write("<b>QueryParameters</b>: {0}<br/>", uriInfo.QueryParameters.ToString());
response.Write("</body></html>");
response.Flush();
rawResponse.Position = 0;
return rawResponse;
}
}
Now all you have to do is start up the WCF web/http self-host ...
static void Main()
{
Uri baseAddress = new Uri("http://localhost:8000/");
WebServiceHost svcHost = new WebServiceHost(typeof(ServiceType));
ServiceEndpoint svcEndpoint = svcHost.AddServiceEndpoint(typeof(IService),
new WebHttpBinding(), baseAddress);
svcEndpoint.Behaviors.Add(new WebHttpBehavior());
svcHost.Open();
Console.WriteLine("Press enter to quit...");
Console.ReadLine();
svcHost.Close();
}
NOTE: for the above example to work on Vista/Win7 you need to grant permissions with the following command-line:
netsh http add urlacl url=http://+:8000/ user=DOMAIN\USER
You can host the ASP.Net runtime in your own process. Rick Strahl has an old article about it called "Using the ASP.Net Runtime for extending desktop applications with dynamic HTML Scripts".
It should work fine for Windows XP, .Net 2.0 and up. If you combine this with the WCF code in #csharptest.net answer you should be able to use the power of ASP.Net pages and having an endpoint for it.
If you want a simple solutions, I would suggest you try Kayak.
From the site:
Kayak HTTP is a simple web server. It
listens for connections, creates an
in-memory representation of requests,
and allows you to easily generate
responses. It can be used in any C#
program. Your code loads Kayak into
its process spaceā€”not the other way
around!
It works well with mono also. Give it a shot! :)
Update
Your can also try aspnet serve
You could use UtilDev Cassini with your windows service. It is based on the original MS casini that is bult into visual studio and is free and redistributable.
If you were using Windows 7 you could use IIS7's Hostable Web Core feature to host a subset of IIS inside your service, without installing IIS7 itself.
What you are looking for is an embedded web server. While you can write your own, I suggest you check C# WebServer, an embedded web server written in C#.
Consider one of the Cassini builds or the new Hostable Web Core HWC

Categories

Resources