Xamarin forms app Connection to Asp.net core web Api - asp.net-core

I have a xamarin forms app that uses a (local) web api (using asp.net core) to connect to Sql Server Database.
i tried the demo provided here https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client to make a client api calls but it uses a console app instead of mobile app and it worked fine.
using both Microsoft.AspNet.WebApi.Client
and Newtonsoft.Json Nuget Packages
Xamarin forms client code
client.BaseAddress = new Uri("http://myIP:port/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = await client.PostAsJsonAsync("api/users", user);
response.EnsureSuccessStatusCode();
return response.IsSuccessStatusCode;
}
catch (Exception ex)
{
Debug.WriteLine("Post Api Exception Msg: " + ex.Message, Class_Name);
return false;
}
and my web-Api code
public IActionResult Post([FromBody] User user)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
bool result= repository.Create(user);
if(result)
{
return Ok();
}
else
{
return StatusCode(500);
}
}
and i have tested the api code and it's working fine.
but whenever i try to make calls from my xamarin app
first) i placed a breake point in the web-api code it never gets hit
second) i keep getting the exception
[monodroid-net] --- End of managed Java.Net.SocketException stack trace ---
[monodroid-net] java.net.SocketException: Socket closed
[monodroid-net] at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:394)
[monodroid-net] at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
[monodroid-net] at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
[monodroid-net] at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
[monodroid-net] at java.net.Socket.connect(Socket.java:621)
[monodroid-net] at com.android.okhttp.internal.Platform.connectSocket(Platform.java:145)
[monodroid-net] at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:141)
[monodroid-net] at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
[monodroid-net] at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
[monodroid-net] at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
[monodroid-net] at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
[monodroid-net] at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
[monodroid-net] at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
[monodroid-net] at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
[monodroid-net] at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
I think it means that there is a problem with the connection socket but I have no idea what the problem is and how to resolve it.

You need change this:
client.BaseAddress = new Uri("http://10.0.2.2:port/");
instead of:
client.BaseAddress = new Uri("http://myIP:port/");
for more information, see the official documentation:
https://learn.microsoft.com/en-us/xamarin/cross-platform/deploy-test/connect-to-local-web-services

In order to access your location machine's web API in the android emulator, you must use the IP 10.0.2.2, see the link below for assistance
https://developer.android.com/studio/run/emulator-networking#networkaddresses

I finally solved the problem by using the Conveyor Extension here is the steps:
open visual studio and select from the tool bar extensions -> manage extension.
in online section search for Conveyor By Keyoti.
after installing the extension restart your Visual studio and it will resume installing.
after that you need to Add a firewall rule for your api to use.
open the windows defender firewall with advanced security form the start menu or type in the search box wf.mfc whatever works for you.
for full steps watch this brief tutorial.
Conveyor: Remote access to IIS Express web application [Updated]
after making all firewall configuration except the part of access over the internet (because in my case both my api and my android device are connected on the same network )
i did not work so i tried this:
5) click on tools -> conveyor allow remote access it will open up this window click on options.
on the far right side there option I clicked on FireWall check to check any issue with the firewall
afterwards it will open a window display the issues with the firewall
and you'll have two option to apply firewall rules automatically or to apply firewall rules manually

Related

VSTO-specific web request not working (System.Net.WebException)

I wrote a 2013/2016 VSTO app for Microsoft Word using C#. My app creates a new toolbar with buttons. One such button runs my app, which launches a basic Windows Form.
Before the user can work with my app, they need to enter information like their license code and email address. My code in turns sends a basic request to my licensing server and awaits a response.
All my code has been running just fine and now it no longer is. Now, when I run the code, I receive the following two error messages:
System.Net.WebException: 'The underlying connection was closed: An
unexpected error occurred on a send.' Inner Exception: IOException:
Unable to read data from the transport connection: An existing
connection was forcibly closed by the remote host.
and
System.Net.WebException: 'The underlying connection was closed: An
unexpected error occurred on a send.' Inner Exception:
SocketException: An existing connection was forcibly closed by the
remote host
I decided to run the code using a standard console app to see if I received the same error message, and sure enough, it worked great! Now I am wondering if Word or the Microsoft VSTO technology is blocking my app from accessing my server.
Here is the code in VSTO that does not work
Note 1: Created a basic 2013/2016 C# VSTO add-in, added a toolbar, and added
Note 2: Added a reference to System.Web.
Note 3: Modified the website link and the query strings as I did not want to publish them on this public forum.
using System;
using Microsoft.Office.Tools.Ribbon;
using System.Web;
using System.Net;
namespace WordAddIn3
{
public partial class Ribbon1
{
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
}
private void button1_Click(object sender, RibbonControlEventArgs e)
{
// Attempt to activate the product using the licensing server on the website.
Console.WriteLine("** ActivateLicense");
//build the url to call the website's software licensing component.
var builder = new UriBuilder("https://validwebsite.com");
builder.Port = -1;
//build the query string.
var query = HttpUtility.ParseQueryString(builder.Query);
query["license_key"] = "validactivationcdode";
query["product_id"] = "validproductid";
query["email"] = "validemailaddress";
builder.Query = query.ToString();
string url = builder.ToString();
Console.WriteLine("activation request:");
Console.WriteLine(url); //display the REST endpoint.
//make the synchronous call to the web service.
var syncClient = new WebClient();
var responseStream = syncClient.DownloadString(url);
Console.WriteLine("Response stream:");
Console.WriteLine(responseStream); //display the server json response.
}
}
}
Here is what is pretty much the same exact code in a console app that does work
Note 1: Created a basic C# console app.
Note 2: Added a reference to System.Web.
Note 3: Modified the website link and the query strings as I did not want to publish them on this public forum. You will receive an error, but that is due to the sample website not having a licensing server.
using System;
using System.Net;
using System.Web;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// Attempt to activate the product using the licensing server on the website.
Console.WriteLine("** ActivateLicense");
//build the url to call the website's software licensing component.
var builder = new UriBuilder("https://validwebsite.com");
builder.Port = -1;
//build the query string.
var query = HttpUtility.ParseQueryString(builder.Query);
query["license_key"] = "validactivationcdode";
query["product_id"] = "validproductid";
query["email"] = "validemailaddress";
builder.Query = query.ToString();
string url = builder.ToString();
Console.WriteLine("activation request:");
Console.WriteLine(url); //display the REST endpoint.
//make the synchronous call to the web service.
var syncClient = new WebClient();
var responseStream = syncClient.DownloadString(url);
Console.WriteLine("Response stream:");
Console.WriteLine(responseStream); //display the server json response.
Console.ReadKey();
}
}
}
Can you help me determine why the code is no longer working in the add-in where it did before (with no code changes)?
I read a lot online and there seem to be too many reasons why this might happen. As an FYI, the website with the licensing server is running. It is (and always has been) a little slow, but when running the code with VSTO, the response is immediate (suggesting no timeout). The Console code runs and there is never a timeout.. I always get a response from the licensing server.
On another thread for a similar problem, someone recommended running WireShark. I am not really familiar with the product, but during my working console run, I received no error messages and instead I got messages like these:
Standard query 0x626a AAAA mywebsite.com
and
Standard query response 0x626a AAAA mywebsite.com
However, if I run the same code in VSTO, I get additional messages that are errors (this one shows up twice):
TCP 60 443 → 50308 [RST, ACK] Seq=1 Ack=125 Win=32768 Len=0

Issue with SSH.NET UWP

I am having issues using SSh.net in a UWP App. This app will run on Win10.
I get the following error:
An attempt was made to access a socket in a way forbidden by its access permissions. I have looked online and there is no one actually dealing with this.The exact same code works in a standard Desktop App (WPF)
The key is the key string and I had to replace \r with \n because the PrivateKeyFile creation gave an error message and I tracked this down to carriage return placed instead of new line (by the textbox).
key = key.Replace("\r", "\n");
PrivateKeyFile(stringToStream(key));
client = new SshClient(ip, port, username, pkf);
if (!client.IsConnected)
{
try
{
client.Connect();
connected = true;
}
catch (Exception ex)
{
exception = ex.Message.ToString();
connected = false;
}
}
Finally resolved this issue - Look here: An attempt was made to access a socket in a way forbidden by its access permissions
Go down to the following line:
If you're getting the same error in Windows 8 development, it could be that you haven't enabled access over Private Networks in your Package.appxmanifest file:
Select the Private Networks (Client & Server) option as shown on the image.
Click here for the image

HTTP could not register URL (remote debugging)

C#, Windows 7.
I write an AutoCAD plugin and use the remote debuging (MS Visual Studio). My plugin must work as a WCF service. AutoCAD is unmanaged application and must to be as a host for my service. I am reading a book about WCF, and I try use it. I can't use acad.exe.config for my service settings: I have not permission. So I do it myself (I will read them from my xml file, but later, after refactoring). Code of my "server" (this code start by AutoCAD):
private static void RunServices() {
Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
try {
Uri address = new Uri("http://localhost:8000/CadService");
BasicHttpBinding binding = new BasicHttpBinding();
binding.Name = "httpBinding";
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.Security.Mode = BasicHttpSecurityMode.None;
host = new ServiceHost(typeof(CadService));
host.AddServiceEndpoint(typeof(ICadService), binding, address);
host.Open(); // I get an Exception here...
if (doc != null) {
doc.Editor.WriteMessage("Service launched.\n");
}
}
catch (Exception ex) {
if (doc != null) {
doc.Editor.WriteMessage("Exception: {0}\n", ex.Message);
}
}
}
I get an exception (look the code comment):
Exception: HTTP could not register URL http://+:8000/CadServices/.
Your process does not have access rights to this namespace
(see http://go.microsoft.com/fwlink/?LinkId=70353 for details).
But the http://go.microsoft.com/fwlink/?LinkId=70353 page is not exist. I try launch MS Visual Studio 2013 as admin (I read about this here), but It is not help me (look P.S.2 bellow).
P.S. If I launch AutoCAD as admin - all works fine.
P.S.2 If I launch the remote debugger as admin - all works fine too.
But I need use it as a usual user. Can I start my service (hosted in the AutoCAD) without the admin rights?
This is probably because AutoCad does not have the required rights to register the port in HTTP.SYS. In that case you have two options:
Start Autocad in Admin mode
Register the port / endpoint in HTTP.SYS manually. For this, there are several tools available. This is the one I would use : http://www.codeproject.com/Articles/437733/Demystify-http-sys-with-HttpSysManager
Let me know if this works

flex 4.6 : Application crash if no internet connection

My mobile application is interact with WCF web services i build it in flash builder with Data/Services then put the url in the WSDL services
my issue is if the mobile starts with no internet connection it crashed
the error message in the console
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/getChildIndex()
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::rawChildren_getChildIndex()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:2187]
at mx.managers::SystemRawChildrenList/getChildIndex()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemRawChildrenList.as:181]
at spark.components.supportClasses::StyleableStageText/getFormIndex()[E:\dev\4.y\frameworks\projects\mobilecomponents\src\spark\components\supportClasses\StyleableStageText.as:1956]
at spark.components.supportClasses::StyleableStageText/findTopmostForm()[E:\dev\4.y\frameworks\projects\mobilecomponents\src\spark\components\supportClasses\StyleableStageText.as:1933]
at spark.components.supportClasses::StyleableStageText/updateProxyImageForTopmostForm()[E:\dev\4.y\frameworks\projects\mobilecomponents\src\spark\components\supportClasses\StyleableStageText.as:2172]
at spark.components.supportClasses::StyleableStageText/commitProperties()[E:\dev\4.y\frameworks\projects\mobilecomponents\src\spark\components\supportClasses\StyleableStageText.as:1510]
at mx.core::UIComponent/validateProperties()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:8219]
at mx.managers::LayoutManager/validateClient()
at mx.managers::LayoutManager/validateClient()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\LayoutManager.as:950]
at mx.managers::PopUpManagerImpl/addPopUp()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\PopUpManagerImpl.as:382]
at mx.managers::PopUpManager$/addPopUp()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\PopUpManager.as:193]
at spark.components::SkinnablePopUpContainer/open()[E:\dev\4.y\frameworks\projects\spark\src\spark\components\SkinnablePopUpContainer.as:450]
at debug.ondevice.util::EnterDebugHostIPDialog/show()[/ndepot/fb_46_release_branch/ide_builder/com.adobe.flashbuilder.launching.multiplatform.contributor/utilswcs/src/debug/ondevice/util/EnterDebugHostIPDialog.mxml:47]
at debug.ondevice.util::DebuggerHostInfo$/showIPErrorDialog()[/ndepot/fb_46_release_branch/ide_builder/com.adobe.flashbuilder.launching.multiplatform.contributor/utilswcs/src/debug/ondevice/util/DebuggerHostInfo.as:129]
at mx.netmon::NetworkMonitorImpl/ioErrorHandler()[/ndepot/fb_46_release_branch/ide_builder/com.adobe.flexbuilder.monitors.network/netmonlibrary/src/mx/netmon/NetworkMonitorImpl.as:645]
i want to handle this error with message if no connection
i tried to put condition for internet connection when creation complete
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
monitor = new URLMonitor(new URLRequest('http://www.adobe.com'));
monitor.addEventListener(StatusEvent.STATUS, announceStatus);
monitor.start();
}
public function announceStatus(e:StatusEvent):void {
trace("Status change. Current status: " + monitor.available);
(new AlertMsg()).open(this, false) ;
}
but it doesn't reached if no connection
Note : My target is android
Thanks in advance , for any help

Connecting via named pipe from windows service (session#0) to desktop app (session #1)

Given:
- the application - desktop GUI (WPF) .NET app
- windows service watching for application (.NET also)
The windows service periodically "pings" application to get sure it's healthy (and if it's not winservice will restart it).
I was going to implement "pinging" via named pipes. To make things simpler I decided to do it with WCF. The application hosts a WCF-service (one operation Ping returning something). The windows service is a client for this WCF-service, invokes it periodically based on a timer.
That's all in Windows 7.
Windows service is running under LocalService (in session#0).
Desktop application is running under currently logged in user (in session#1).
The problem:
Windows service can't see WCF endpoint (with NetNamedPipeBinding) created in and being listened in desktop application. That means that on call via wcf proxy I get this exception: "The pipe endpoint 'net.pipe://localhost/HeartBeat' could not be found on your local machine"
I'm sure code is ok, because another desktop application (in session#1) can see the endpoint.
Obviously here I'm dealing with some security stuff for Win32 system object isolation.
But I believe there should be a way to workaround restrictions I've encountered with.
I can sacrifice WCF approach and go the raw NamedPipe way.
An easier solution might be to use a WCF duplex contract with the Windows service hosting the WCF service. The client App would call an operation on the service to register itself, when it starts up. The Ping would then be an operation invoked periodically by the service on the client's callback contract, to which the App would respond.
Service visibility works this way round, because the Windows service can run with SeCreateGlobalPrivilege, and so the shared memory object via which the pipe name is published by the service can be created in the Global kernel namespace, visible to other sessions. Interactive applications can't easily get that privilege in Windows7, so WCF services in such applications fall back to publishing the pipe in the Local kernel namespace, visible only within their own session.
Finally I've found a solution - using Named Pipes from System.IO.Pipes directly. It's seems that WCF's pipes support implementation doesn't use System.IO.Pipes.
Server:
using (var pipeServer = new NamedPipeServerStream("mypipe", PipeDirection.Out, 1))
{
try
{
while (true)
{
// #1 Connect:
try
{
pipeServer.WaitForConnection();
}
catch (ObjectDisposedException)
{
yield break;
}
if (ae.IsCanceled())
return;
// #2: Sending response:
var response = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
try
{
pipeServer.Write(response, 0, response.Length);
}
catch (ObjectDisposedException)
{
return;
}
// #3: Disconnect:
pipeServer.Disconnect();
}
}
finally
{
if (pipeServer.IsConnected)
pipeServer.Disconnect();
}
}
Client:
using (var pipeClient = new NamedPipeClientStream(".", "mypipe", PipeDirection.In))
{
try
{
try
{
pipeClient.Connect(TIMEOUT);
}
catch(TimeoutException ex)
{
// nobody answers to us
continue;
}
using (var sr = new StreamReader(pipeClient))
{
string temp;
while ((temp = sr.ReadLine()) != null)
{
// got response
}
}
}
catch(Exception ex)
{
// pipe error
throw;
}
}