Xamarin.Forms with WCF - c#

Usually I write a small topic with a question, but not today. I apologize in advance for "a lot of text", but this question exhausted me completely.
The main task was to create Xamarin.Forms application and organize communication with the database through WCF
Visual Studio 2015 pro, latest updates, Xamarin, latest updates.
Step 1.
This link became the foundation of my decision. I created the WCF Service as specified in this topic. At first - without Configuring Remote Access to IIS Express.
Add: WCF Service tested with Windows Forms Application. Test passed.
Step 2.
As I indicated earlier - Xamarin.Forms, not Xamarin.Android as in that topic. Here is my steps to create Xamarin.Forms project:
New Project - Cross-Platform - Cross Platform App(Xamarin.Forms or Native) - Blank App(UI Technology) - Xamarin.Forms, Code Sharing Strategy - PCL(Portable Class Library)
Step 3.
The first problems: Default template for Xamarin.Forms in VS2015 includes target platforms incompatible with WCF. It means we can't add Service Reference to PCL while we have this target platforms. This problem took a lot of time, and my solutions are:
Delete From NuGet Xamarin.Forms - restart VS - Open PCL Properties - Click Change Target Platforms - Remove Windows Phone and Silverlight - restart VS - Add Xamarin.Forms NuGet - the best one I found
Rename packages.config to packages.config.BAK - do the same operation with changing platforms
After one of this ways - "Add Service Reference" apears. The second way leads to crash VS when try to add service reference.
Step 4.
We can try to add Service Reference from VS as mentioned in guide from Xamarin site in " blue note " or generate Service client class with SLsvcUtil.exe
My client side:
public MainPage()
{
InitializeComponent();
BasicHttpBinding binding = CreateBasicHttp();
MyServiceClient client = new MyServiceClient(binding, new EndpointAddress("http://localhost:9607/MyService.svc"));
client.DoWorkCompleted += Client_DoWorkCompleted;
client.DoWorkAsync(10);
}
private void Client_DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
{
var result = e.Result;
}
private static BasicHttpBinding CreateBasicHttp()
{
BasicHttpBinding binding = new BasicHttpBinding
{
Name = "basicHttpBinding",
MaxBufferSize = 2147483647,
MaxReceivedMessageSize = 2147483647
};
TimeSpan timeout = new TimeSpan(0, 0, 30);
binding.SendTimeout = timeout;
binding.OpenTimeout = timeout;
binding.ReceiveTimeout = timeout;
return binding;
}
Step 5.
Run Service... Run Client... Wait for raise DoWorkComleted... get System.Reflection.TargetInvocationException in e.Result...
Anyone... Help me, please. This problem controls my life. I can't sleep, I can't eat... I just thinking about this ... problem...
Link to my DropBox for source code.
Fixed. The main problem: hocalhost for emulator isn't localhost for main workstation. Creating access for local network fixed my problem.

Related

gRPC client having lots of issues and not working

I started using gRPC with Visual Studio 2022 and never saw so many issues as now.
When I wanted to create an additional Proto file I got the error saying that I need to specify the language. That's weird, because I selected the proper option which is designed for C#. So it never worked and I simply had to copy default greeter file.
I created the console app which uses this default greeter service and it even worked. But I added the additional proto and created another fairy simple service and it did not want to compile it referring to some missing types of something. I can't remember the exact error message but I resolved it only by reducing the grpc.* package version to 2.27.I found this answer by googling and I find it weird that Microsoft releases something what does not work in the most simple case scenario.
I decided to test my new test grpc service and created the client:
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.MySimpleMethodAsync(new MyRequest { Id = 123 });
Console.WriteLine(reply.Message);
Console.ReadKey();
The MySimpleMethodAsync method is very simple, it just reads the record from the DB using Dapper, nothing special.
Surprisingly there was no compilation error, but when I tried to run it (along with the server app) I got the exception on the line var reply = await client.MySimpleMethodAsync, saying Grpc.Core.RpcException: 'Status(StatusCode=Unimplemented, Detail="Service is unimplemented.")'
I don't understand why it says so. The service is implemented, it's compilable! Googling did not help but I found that other people are having the same issue too.
Eventually I found that if I modify the grpc service and for some reason it does not like it and then I rollback the changes, it's not compilable anymore! I clearn solution, rebuild it - nothing helps! The only thing which helps is addting the brand new project and copy pasting the previous "stable" code.
I've never seen such the ...technology that never works!
Anyway, now the most important issue for me is #3 , why it says the service is not implemented?

how to host silverlight project local

i want to debug my program but i can't host my silverlight project in VS 2010
here is the message that the VS send to me:
"the Silverlight project you are about to debug uses web service. Call to the web service will fail unless the Silverlight is host and launched from the same web project contains the web service"
when I search about it in the web i saw that the problem is that I'm not doing it local
so when I tried to change this line
endpoint address="http://xxx.xx.x.x/WebService/Service1.svc"
to
endpoint address="http://localhost/WebService/Service1.svc"
on this file:
ServiceReferences.ClientConfig
update!!
i tried now to do it like this:
endpoint address="http://localhost:54502/Service1.svc"
and i got and error that says:
the remote server returned an error:NotFound
here:
public int EndAddParticipant(System.IAsyncResult result) {
object[] _args = new object[0];
int _result = ((int)(base.EndInvoke("AddParticipant", _args, result)));
return _result;
what should i do to change it?
i saw that i need to turn on the debug in web.config file but it was already on.
You didn't explain well so here are a bunch of answers:
When you created your solution, you should have told it to host in a web site.
You can do this after the fact but it is a lot of work (for a new guy), you're better off starting over and copying your code from your silverlight project.
If you did but you are trying to connect to another web site as your web service, you will have to implement a Cross Domain configuration file. This opens a big security hole though.
If you have the 2 projects, but your issue is just the "ServiceReferences.ClientConfig" file not pointing the the right server, you need to include the PORT when debugging locally. It should look something like this:
http://localhost:12345/Service1.svc
Where 12345 is the port of your local web service. You can find this out by looking at the "Web" tab of your project properties.
Hope one of these does it. If not, please provide a little more info, like all the important stuff behind the phrase, "it didn't work"!

Mono WCF issue on OSX

I've written a mono compatible application that works fine on a Windows machine and mostly works on my mac. The area that currently doesn't work is the layer that uses the WCF (ChannelFactory) to communicate between server and client.
The issue appears to be when I try and open the ChannelFactory on the Server, here is a code snippet:
string address = "21"; // added this for simplicity in conveying the problem...
string server_address = "net.tcp://192.168.1.122:4505/DeviceServer/";
string serviceAddress = string.Format(server_address, address);
ThreadedServiceHost<DeviceService, IDeviceContract> DeviceHost =
new ThreadedServiceHost<DeviceService, IDeviceContract>(serviceAddress, address, new NetTcpBinding());
EndpointAddress endPoint = new EndpointAddress(
new Uri(string.Format(serviceaddress, address) + address));
System.ServiceModel.Channels.Binding binding = new NetTcpBinding();
teeGlobal.ServerDeviceFactory = new ChannelFactory<IDeviceChannel>(binding, endPoint);
teeGlobal.ServerDeviceFactory.Open();
The issue is with the .Open() call - it just appears to hang on my mac. Creating the endpoint takes a lot longer to create than on my PC (about 3-4 seconds) but I can live with this if I can get the WCF layer to function.
Does anyone have any suggestions on how to progress with this issue?
The most recent stable release of Mono is 2.8.2 (http://www.go-mono.com/mono-downloads/download.html)
You really need to try with this version before doing anything else. The WCF stack in 2.6.x was more of a 'preview' than anything else, and only some common scenarios actually worked. 2.8 is much more complete.

Control IIS 7 server from Windows 2003 server programmatically

We run various jobs using a Windows 2003 server. Some of these jobs send app pool commands to web servers running IIS 6 (recycle, start, stop). Now we have a Windows 2008 web server running IIS 7, and we want to send the same commands. This is all done using C#.
This is the code we use to send commands for IIS 6:
var methodToInvoke = "Stop"; // could be "Stop", "Start", or "Recycle"
var co = new ConnectionOptions
{
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.PacketPrivacy
};
var objPath = string.Format("IISApplicationPool.Name='W3SVC/AppPools/{0}'", appPoolName);
var scope = new ManagementScope(string.Format(#"\\{0}\root\MicrosoftIISV2", machineName), co);
using (var mc = new ManagementObject(objPath))
{
mc.Scope = scope;
mc.InvokeMethod(methodToInvoke, null, null);
}
This code doesn't work for IIS 7 due to underlying changes, so we're currently trying this:
using (ServerManager serverManager = ServerManager.OpenRemote(machineName))
{
var appPool = serverManager.ApplicationPools[appPoolName];
if (appPool != null)
{
appPool.Stop(); // or app.Start() or app.Recycle()
serverManager.CommitChanges();
}
}
The above code works fine on my workstation, which runs Windows 7 (and, thus, IIS 7.5). However, it does not work when I deploy this code to our application server. It get this error:
System.InvalidCastException:
Unable to cast COM object of type 'System.__ComObject' to interface type
'Microsoft.Web.Administration.Interop.IAppHostWritableAdminManager'.
This operation failed because the QueryInterface call on the COM component for the
interface with IID '{FA7660F6-7B3F-4237-A8BF-ED0AD0DCBBD9}' failed due to the following error:
Interface not registered (Exception from HRESULT: 0x80040155).
From my research, this is due to the fact that IIS 7 is not available on the Windows Server 2003 server. (I did include the Microsoft.Web.Administration.dll file.)
So my questions are:
Is it possible for the above code for IIS 7 to work at all from a Windows 2003 server?
If no to #1, is there a better way of doing this?
From reading around it doesn't appear to be possible to do what you're looking for. It's not enough to include the dll files.
According to http://forums.iis.net/t/1149274.aspx..
In order to use Microsoft.Web.Administration you need to have IIS installed, at the bare minimum you need to install the Configuration API's which are brought through installing the Management Tools.
Unfortunately there is no SDK that enables this and it has several dependencies on other components that wouldn't let you just take it to another machine and make it work (such as COM objects, DLL's, etc).
I'd be interested in knowing if you've found a way round this.
Thanks
Try controlling the IIS pool with DirectoryEntry instead.
See this topic:
Check the status of an application pool (IIS 6) with C#
Microsoft.Web.Administration, it relies on System.Web.dll which was provided by framework 4, not client profile.

How to consume Windows Communication Foundation (WCF) by a Windows Service

When i create a Windows Service for getting information from a Web Application(ASP.NET c#) for scheduling some task in the client machine.
To consume WCF from the web application. I added WCF reference
to Window Service project as a service reference, everything seems fine. It
updated app.config file, added service reference etc.
it was not working. Any idea will be very helpful.
My Code is shown below
string result = string.Empty;
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://test.com/Service.svc/DevicesService");
using (ChannelFactory<IDevicesService> myChannelFactory = new ChannelFactory<IDevicesService>(myBinding, myEndpoint))
{
IDevicesService wcfClient1 = myChannelFactory.CreateChannel();
result = wcfClient1.CheckNetworkConnection(IPLocalHost);
if (!string.IsNullOrEmpty(result) && result.Equals(IPLocalHost))
{
EventLog.WriteEntry("Test connection succeeded");
}
else
{
EventLog.WriteEntry("No live connection currently available");
}
((IClientChannel)wcfClient1).Close();
}
I find it easier, when building a windows service, to build a console application that performs the same work as the service will. I abstract out the actual working code (e.g. your code snippet above) into a separate assembly and then just invoke it from either my service's start method or the console's main method.
If you move your code above into a console application, does it work? If it doesn't, can you step through it and let us know where it fails. And when it fails, what exception information are you seeing?
Let us know and we'll help!

Categories