I'm making a project where I must have 3 platforms (ASP, Desktop (windows forms) and Xamarin) that must connect to a database. I've been experimenting but it seems I can't connect to the database directly. Sqlserver just closes the connection a few seconds later. So I tried the webservice way. I couldn't add a service reference.
I searched and it seems I had to: uninstall Xamarin.Forms nugget package in PCL, uncheck the Windows Phone in the solution properties, restart VS and reinstall the nugget package. And then I was able to add the service reference.
But then it said I needed the Sytem.Web.Services reference for it to work. But I can't add it...
So, after all this, how can I possibly connect to SQL Server like this? In ASP and Desktop it works fine, I connect directly, via a class library which contains all the connections. But I'm scratching my head about this one...
Any ideas?
When you have multiple applications that needs to access the same data, you're better of putting something between them that they all communicate with. This reduces the amount of duplicated logic across applications and means you only need to expose your database to a single service.
Database
|
|
|
API
/|\
/ | \
/ | \
/ | \
/ | \
Mobile--- Desktop ---Website
If you're using the .NET stack for everything, your API is probably going to be implemented in ASP.NET Web API or WCF. I recommend Web API, because it's simpler. Anything that can speak HTTP can talk to it.
Then, to communicate with your API, you generally create a wrapper around an low level client that makes it simple to communicate with your API's endpoints. This often takes the form of a class library wrapped around something like HttpClient or RestSharp. This class library is delivered via NuGet package that any .NET application can consume.
Here's some pseudo code (don't expect it to compile)
namespace MyClientAPI
{
public class MyClient
{
private readonly string _baseAddress;
public MyClient(string baseAddress)
{
_baseAddress = baseAddress;
}
public List<Customer> GetCustomers()
{
var restClient= new RestClient(_baseAddress);
var request = new RestRequest("customers/all");
var customers = restClient.Execute<List<Customer>>(request);
return Customers;
}
}
}
Related
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.
Using WCF, .NET 4.5, Visual Studio 2015, and want to use per-session instancing, not singleton. The services provided are to be full-duplex, over tcp.net.
Suppose I have two machines, A & B...
B as a client, connects to a "service" provided as a WCF service on same machine B, and starts talking to it, call it object “X”. It ALSO connects to another instance of the same service, call it object “Y”
A as a client, wants to connect to, and use, exact same objects B is talking to, objects “X” and “Y”, except now it’s remote-remote, not local-remote.
“X” and “Y” are actually a video servers, and both have “state”.
Can I do this? How, when I’m a client, do I specify WHICH service instance I want to connect to?
Obviously, on machine "B", I could kludge this by having the services just be front-ends with no "state", which communicate with some processes running on "B", but that would require I write a bunch of interprocess code, which I hate.
Machine B is expected to be running 100's of these "video server" instances, each one being talked to by a local master (singleton) service, AND being talked to by end-user machines.
I realize this question is a bit generic, but it also addresses a question I could not find asked, or answered, on the Internets.
I just thought of one possible, but kludge-y solution: since the master service is a singleton, when service instance "X" is created by the end-user, it could connect to the singleton master service, through a proxy to the singleton. Then, the singleton can talk back to instance "X" over a callback channel. Yeah, that would work! messy, but possible.
I'd still like to know if end user A and end user B can both talk to the same (non-singleton) service instance on machine C through some funky channel manipulation or something. As I understand the rules of WCF, this simply isn't possible. Perhaps maybe if you're hosting the service yourself, instead of IIS, but even then, I don't think it's possible?
I've faced the same problem and solved it by creating two service references, one for the local one for the remote. Let's call it LocalServiceClient and RemoteServiceClient.
In a class, create a property called Client (or whatever you like to call it):
public LocalServiceClient Client {
get {
return new LocalServiceClient();
}
}
Okay this is for only one of them. Just create another now, and set which one to use with a compiler flag:
#if DEBUG
public LocalServiceClient Client {
get {
return new LocalServiceClient();
}
}
#else
public RemoteServiceClient Client {
get {
return new RemoteServiceClient();
}
}
#endif
Instantiate any instances of your Client using var keyword, so it will be implicitly-typed, or just use Client directly:
var client = Client;
client.DoSomething...
//or
Client.DoSomething...
This way, when you are working locally, it will connect to the local service, and on release configuration (make sure you are on Release when publishing) it will compile for the remote one. Make sure you have the exact same signature/code for both services though at the WCF-side.
There are also methods that you can dynamically do it in code, or like in web.config, they would also work for sure, but they are usually an overkill. You probably need to connect to local one in debugging, and the remote one in production, and this is going to give you exactly what you need.
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.
I'm trying to write my own controller for a USB device instead of using the SDK that comes with the product (I feel the sdk is sub-par).
The USB Device is plugged into the SAME SERVER that this application is running on.
So I decided to head over to Nuget and grab the HidLibrary
PM> Install-Package hidlibrary
and I proceeded to follow the example found on GitHub.
First I went into my control panel to verify the VendorID and the ProductID
And I dropped it into my code.
Then I set a breakpoint on the line that grabs the device, but unfortunately it always comes back null.
using HidLibrary;
public class MyController : ApiController
{
private const int VendorId = 0x0BC7;
private const int ProductId = 0x0001;
private static HidDevice _device;
// POST api/<controller>
public string Post(CommandModel command)
{
_device = HidDevices.Enumerate(VendorId, ProductId).FirstOrDefault();
if (_device != null)
{
// getting here means the device exists
}
else
{
// ending up here means the device doesn't exist
throw new Exception("device not connected");
}
return null;
}
I'm hoping it's something silly, and not some deal-breaking permissions issue regarding connecting to a USB device directly from an IIS worker.
Despite your hopes to be something silly, it is not. You have some deal-breaking permission issues. If you will browse Mike O'Brien's code from GitHub of the Hid Library you will see that it calls Win32 API functions located in: kernel32.dll, setupapi.dll, user32.dll, hid.dll (Native.cs).
The enumeration itself it's done through setupapi.dll functions. It browse all the installed devices and filters what it's need it.
So... I think it's a security issue to execute kernel32.dll code directly from a web-app in IIS with anonymous authentication, don't you?
If you really need to communicate with that HID (who knows maybe it's a temperature sensor, or something else) I would do a separate Windows service and the IIS hosted web app would communication through WCF with this service. This service would like a proxy.
Put the same code in a console application and run it. That will help you verify if it's your code or environment.
If it's environment, try using Process Monitor to see if there are any hidden access errors. Also try enumerating all devices, not just looking for the one device you're after, just to see if you can do it in ASP.NET.
#Chase, unless this is an experiment - it is best not to attempt connecting to a device from IIS process. [It's a Pandora's box if you start down this path].
Best way to do this is to have another (WCF) service as proxy to the device and expose just what you need out of the service, hook it up with your app. Feel free to ask for an example if you think that would help.
I +1 #garzanti.
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