I cannot established connection with WCF services in Xamarin - android

I have a WPF application in VB.NET that already developed by my old colleagues. Now, my superior want to replace current platform by implementing the same concept to be run on the Android system. So, I've decided to use Xamarin Android .NET Standard.
I have searched for a way to consume WCF and the error throw before I'm asking but I'm still stuck at the same error.
I have set up the service references WCF on the android class. Given on solution, I have 2 projects:- MyProject and MyProject.Android
===========================================================================
WPF
Private Function EstablishConnect() As Boolean
Try
Dim context As InstanceContext = New InstanceContext(Me)
svrobj = New DisplayServicesClient(context, "DisplayTcpBinding")
Dim endpointAddress As New EndpointAddress(modUtility.ServerEndPointAddress)
svrobj.Endpoint.Address = endpointAddress
svrobj.Open()
SecondDiffFromServer = DateDiff(DateInterval.Second, Now, svrobj.GetDateTime)
Return True
Catch ex As Exception
WriteLog.Log(ex.ToString, True)
Return False
End Try
End Function
modUtility.ServerEndPointAddress get from INI:
net.tcp://localhost:8002/AppServ/WCFServices/Display
===========================================================================
XAMARIN FORMS
private async Task<bool> EstablishConnectAsync()
{
try
{
InstanceContext context = new InstanceContext(this);
svrobj = new DisplayServicesClient(DisplayServicesClientBase.EndpointConfiguration.DisplayTcpBinding); //, DisplayServicesClientBase.EndpointConfiguration.DisplayTcpBinding
EndpointAddress endpointAddress = new EndpointAddress(modUtility.ServerEndPointAddress);
svrobj.Endpoint.Address = endpointAddress;
await svrobj.OpenAsync();
modUtility.SecondDiffFromServer = (int)(DateTime.Now - await svrobj.GetDateTimeAsync()).TotalSeconds;
return true;
}
catch (Exception ex)
{
Device.BeginInvokeOnMainThread(() =>
{
ResultText.Text = "Unable to established connection with endpoint service. Ex-" + ex.Message;
});
return false;
}
}
modUtility.ServerEndPointAddress get from settings:
net.tcp://10.0.2.2:8002/AppServ/WCFServices/Display
I'm currently run android on emulator.
My code throw exception on any call to svrobj function. Below are the error that throw:-
The communication object System.ServiceModel.DuplexChannelFactory`1[AppServ.IDisplayServices] is not at created state but at Opening state.
The method or operation is not implemented.
Do I missing something or do I have implement wrong way?

Related

Dotmim.Sync null reference exception in web proxy post method

I am using Dotmim.sync framework. I am trying to sync an mssql database with my xamarin android app's sqlite database. So I implemented the web proxy to reach the database from the android app.
The proxy starts fine, but then when I call the sync from the android app the Post method gives a null reference error, but I cannot find what is null.
In the ASP.NET Core web app's Startup file:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// [Required]: To be able to handle multiple sessions
services.AddMemoryCache();
// [Required]: Get a connection string to your server data source
var connectionString = #"[my connection string]";
// [Required]: Tables list involved in the sync process
var tables = new string[] { "dbo.Album", "dbo.Artist", "dbo.Customer", "dbo.Invoice", "dbo.InvoiceItem", "dbo.Track" };
// [Required]: Add a SqlSyncProvider acting as the server hub.
services.AddSyncServer<SqlSyncChangeTrackingProvider>(connectionString, tables);
}
The SyncController:
[ApiController]
[Route("api/[controller]")]
public class SyncController : ControllerBase
{
private WebServerManager manager;
public SyncController(WebServerManager man) => this.manager = man;
[HttpPost]
public async Task Post()
{
await manager.HandleRequestAsync(this.HttpContext);
} //----> the Null error comes
[HttpGet]
public async Task Get() => await manager.HandleRequestAsync(this.HttpContext);
}
In the android app the sync function that is called:
public async Task SyncDatabase(string connString, Context context)
{
var handler = HttpClientHandlerService.GetInsecureHandler();
HttpClient httpClient = new HttpClient(handler);
httpClient.DefaultRequestHeaders.Host = $"localhost:44372";
var serverOrchestrator = new WebClientOrchestrator("https://10.0.2.2:44372/api/sync", client: httpClient);
// Second provider is using plain sqlite provider
var clientProvider = new SqliteSyncProvider(connString);
var agent = new SyncAgent(clientProvider, serverOrchestrator);
try
{
var result = await agent.SynchronizeAsync(); //---> error comes when this line is called
var output = result.ToString();
output = output.Replace("\n", " ").Replace("\t", " ").Replace("\r", " ");
Toast.MakeText(context, output, ToastLength.Long).Show();
}
catch (Exception e)
{
Toast.MakeText(context, e.Message, ToastLength.Long).Show();
}
}
Let me know what further information should I supply to solve this.
EDIT:
Calling from postman it gives this error: {"tn":"HttpHeaderMissingExceptiopn","m":"Header dotmim-sync-scope-name is missing."}
EDIT2:
Server orchestrator on the client side:
On the server side:
The details of the exception:
SOLUTION:
I tried the sync with a different database and tables, and that worked, so it was clear that dotmim has some problem with the tables I was using. So after lot of thinking I tried with a different schema name instead of dbo, since the other database that worked had something else. And it turns out the sync has some problem if the schema name is dbo, something gets mixed probably when it tries to create its own new tables. So use something different from dbo for schema.

xamarin android : httpclient PostAsync

we have an app under xamarin android build with visual studio 2017.
this app works since three years without any problems.
since two weeks and I don't know why actually some device can't sync with our back end.
It's really strange because nothing has change in this part .
this error does not appear on all devices but on one or two from time to time
we use the dll httpClient for to sync the datas with our backend.
If i put a break point inside the postAsync I have an exception with this -> Cannot access a disposed object. Object name: 'System.Net.Sockets.NetworkStream
Any one has an idea about how to solve this ? also what does it meam ?
Here is it the code of the postAsync method :
thanks for our time and comment guys
public override HttpResult ExecutePost(Uri target, string body)
{
var client = new HttpClient();
client.MaxResponseContentBufferSize = MaxHttpResponseBufferSize;
try
{
var requestContent = new StringContent(body, RequestContentEncoding, RequestContentType);
var response = client.PostAsync(target, requestContent).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsStringAsync().Result;
return new HttpResult(content, null, null);
}
return new HttpResult(null, "Response is empty", response.StatusCode.ToString());
}
catch (Exception e)
{
return new HttpResult(null, "Problem with the HttpPost", e.Message);
}
}
I experienced the same issue. Have been battling for 6 hours on this issue.
If you read the error, I was getting (Failed to connect to localhost/127.0.0.1:7113). If you put localhost in your browser or swagger tool it will work but if you put https://127.0.0.1:7113/api/weatherforecast in your browser it will not work. It will give you a certificate problem.
So I think you have to resolve 127.0.0.1 to localhost with https certificate on your local dev machine.
I'm building a MAUI app with Visual Studio 2022 Preview.
So I solved this issue by deploying my API to AZURE.
Then update to the azure url for example:
string apiUrl = "https://weatherforecast.azurewebsites.net/api/weatherforecast";
and then it worked brilliantly. Like super brilliantly.
Here is my code:
public void LoginAsync()
{
HttpClient client = new HttpClient();
string apiUrl = "https://weatherforecast.azurewebsites.net/api/weatherforecast";
UserCredentials.EmailAddress = LoginUIEntity.EmailAddress;
UserCredentials.Password = LoginUIEntity.Password;
string serialized = JsonConvert.SerializeObject(UserCredentials);
var inputMessage = new HttpRequestMessage
{
Content = new StringContent(serialized, Encoding.UTF8, "application/json")
};
inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
var message = client.PostAsync(apiUrl, inputMessage.Content).Result;
if (message.IsSuccessStatusCode)
{
var apiResponse = message.Content.ReadAsStringAsync();
UserCredentials = JsonConvert.DeserializeObject<UserCredentials>(apiResponse.Result);
if (UserCredentials.IsValid)
{
UserCredentials.IsLoggedIn = true;
}
else
{
ErrorMessage = "Invalid credentials supplied.";
}
}
}
catch (Exception ex)
{
ErrorMessage = "An error has occurred. Please contact support if the error persists.";
}
}
}
thanks for the link your provide.
I've try up the buffer on the postasync / try to sync in wifi OR 3G / delete special character in json / ...
but nothing work
we have move the prod database to the test and try to sync the data to the test database with postman. with postman the result was ENTITY TOO LARGE !
Json is size > 1.2 mega and the default value inside IIS is set to 1 mega
Here is it the problem ...
thanks problem solve

How do I send a serialized object over network stream to a tcp listener in Xamarin?

Can someone show me a code example of how to send serialized objects back and forth from a Xamarin Android application using a BinaryFormatter instead of Json? It's going to be over WiFi inside the Server Farm.
I'm currently trying to port a simple administrative console application over to an Xamarin Android forms application. I don't understand PCL yet or it's lack of [serializable] attribute. I've heard from the guys at Xamarin that I should probably try Android specific Xamarin instead of forms. I'm new to this so I'm not sure. This will be connecting to a custom Windows Service using standard TCPListeners. Any help would be greatly appreciated. Thanks.
This is an example of the type of console code that I am trying to port over.
public static void HeartBeatPulseListener()
{
Int32 hbPort = 8002;
Console.WriteLine("\nStarting Heart Beat Listener on Port: {0}", hbPort.ToString());
TcpListener heartBeatListener = new TcpListener(IPAddress.Any, hbPort);
heartBeatListener.Start();
while (true)
{
using (TcpClient client = heartBeatListener.AcceptTcpClient())
{
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.ForegroundColor = ConsoleColor.Yellow;
NetworkStream netStream = client.GetStream();
IFormatter formater = new BinaryFormatter();
HeartBeatPulse pulseMSG = (HeartBeatPulse)formater.Deserialize(netStream);
if (pulseMSG != null) Console.WriteLine("\nPulse:{0} \n tStamp:{1}\n FROM:{2}\n Instance:{3} \n Original Unique:{4} \n Type: {5}", pulseMSG.Id.ToString(), pulseMSG.TimeStamp.ToString(), pulseMSG.A.ToString(), pulseMSG.ServerCoreInstanceId, pulseMSG.OriginalUnique, pulseMSG.Type);
if (pulseMSG.Roles.Count() > 1)
{
Console.WriteLine("\nRoles:");
foreach (string role in pulseMSG.Roles)
{
Console.WriteLine("\n{0}", role);
}
}
else Console.WriteLine("\nSum Ting Wong");
Console.ResetColor();
}
}
}

Http session is always created on android version ModernHttpClient(okHttp1.5)

Note that both platform are using HttpClient code below. However the native message handler change depending on device : Android using OKhttp1.5 and IOS NSurlSession which is handle from ModernHttpClient library.
My problem is on the android device, a session is always created on the server each time a request is called and it shouldn't.
However, on the IOS the session remain before the session timeout reach out which help performance.
Is there something i need to do on the android version specially to retain the session cookie ?
Thanks!
private static HttpClient _mobileService = null;
public static HttpClient MobileService
{
get
{
if (_mobileService == null)
{
NativeMessageHandler nmh = new NativeMessageHandler();
_mobileService = new HttpClient(nmh);
}
return _mobileService;
}
set
{
_mobileService = value;
}
}

How to use HttpWebRequest with async & await

I am new to Xamarin and C# as well. I try to make a Http request to my server with some information.
In general with android Native a uses AsyncTask and HttpClient for that. and build a json object or name value pair, and encrypt it to integrate information with the request.
But when I try to do the same with xamarin I get some problems.
if I try to import the namespace
using System.Net.Http.HttpClient
than my xamarin not have this namespace
Because of the above problem I try to use HttpWebRequest. But when I go for use it with the asyc and await I am not getting any response from server.
I am new to xamarin so I am not sure about async and await keyword.
I read lot of articles but No luck :(
on Click of the Button I call the below Method
public async Task<int> ValidateUser(){
try{
var request = HttpWebRequest.Create (URL);
request.Method = "GET/POST";
String postString = String.Format ("AAA ={0}&BBB={1}&CCC={2}", "111",
"222","333");
byte[] postByte = Encoding.UTF8.GetBytes (postString);
Stream st = request.GetRequestStream ();
//I am reaching here
Console.WriteLine("Check for Validity");
request.ContentLength = postByte.Length;
st.Write (postByte, 0, postByte.Length);
st.Close ();
Task<Stream> contentTask = request.GetRequestStreamAsync();
Stream response = await contentTask;
String str = response.ToString();
// this is not getting printed in Console
Console.WriteLine("=====>>"+str);
}
catch (WebException exception) {
string responseText;
using (var reader = new StreamReader(exception.Response.GetResponseStream())) {
responseText = reader.ReadToEnd ();
Console.WriteLine ("====Dude Error"+responseText);
}
}catch(Exception e){
}
return 1;
}
Any help will be appreciated
Consider using RestSharp, a component created for Xamarin to facilitate web requests. Click here for more info on the component. It will facilitate allot of things about webrequesting ( like serialization, automatic return type detection,... )
Your code would look something like this with restsharp:
public async Task<int> ValidateUser(){
var client = RestClient (URL);
var request = new RestRequest ("AAA ={0}&BBB={1}&CCC={2}", "111",
"222","333");
client.ExecuteAsync (request, response => {
WebApiResponse webApiResponse = new WebApiResponse ();
webApiResponse.Content = response.Content;
webApiResponse.StatusCode = response.StatusCode;
webApiResponse.ResponseStatus = (WebApiResponseStatus)response.ResponseStatus;
return webApiResponse.Content;
});
return -1
}
Using HttpWebRequest is a bad idea, instead it would be better to focus on why you don't have the System.Net.Http.* namespace. Imho the most likely cause is that you didn't add System.Net.Http as a reference to your project.
Here's how you add System.Net.Http.* to your project.
In Visual Studio 2013:
Open the solution
Open the project
Open the Solution Explorer
Right-click on References
Add Reference
Click on 'Search Assemblies'
Type in 'Http'
Select System.Net.Http
Press 'OK'
In Xamarin Studio:
Open the solution
Open the project
Open the Solution Explorer
Right-click on References
Edit References
Type in 'Http'
Select System.Net.Http
Press 'OK'
Afterwards there should be no problems resolving System.Net.Http when 'using System.Net.Http;'

Categories

Resources