Xamarin.Mac https://localhost httplclient - .net-core

I have a local webapi which i use a selfsigned certificate to run on a pc.I am able to reach the webapi (written in .net core) using the browser (https://localhost:port/controller/method), but when i use httpclient on Mac OS Mojave i get an exception (High Sierra and Catalina works).
System.DllNotFoundException: libc.dylib assembly:<unknown assembly> type:<unknown type> member:(null)
at (wrapper managed-to-native) System.Net.NetworkInformation.CommonUnixIPGlobalProperties.getdomainname(byte[],int)
at System.Net.NetworkInformation.CommonUnixIPGlobalProperties.get_DomainName () [0x0000b] in <4b9a7f543fd447a3be5e54f34ee219b2>:0
at System.Net.CookieContainer..ctor () [0x0003f] in <4b9a7f543fd447a3be5e54f34ee219b2>:0
at System.Net.Http.MonoWebRequestHandler.get_CookieContainer () [0x0000a] in <e45d721af82a41d98156aeda80e9ce53>:0
at System.Net.Http.MonoWebRequestHandler.CreateWebRequest (System.Net.Http.HttpRequestMessage request) [0x000f5] in <e45d721af82a41d98156aeda80e9ce53>:0
at System.Net.Http.MonoWebRequestHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x0003e] in <e45d721af82a41d98156aeda80e9ce53>:0
at System.Net.Http.HttpClient.SendAsyncWorker (System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) [0x000e8] in <e45d721af82a41d98156aeda80e9ce53>:0
at Mac_Installer.ViewController.Timer_Elapsed (System.Object sender, System.Timers.ElapsedEventArgs e) [0x000bd] in <3581d802103c47bbbf47f26a2763b24c>:0
I have read up and it seems like i need to set the DYLD_FALLBACK_LIBRARY_PATH to /usr/lib (I can see the file - libc.dylib - is there), believe i should add it in the info.plist as an environment variable, but it still fails, or i am doing it wrong.
Any help appreciciated.

If you enabled hardened runtime, try adding "Allow DYLD Environment Variables Entitlement" (com.apple.security.cs.allow-dyld-environment-variables) into your Entitlements.plist.

I just copy libc.dylib. over to the app MonoBundle or Resources folder. The Dll can be found here: https://github.com/facilityweb/Dlls/blob/master/libc.dylib
Another Solution is import the lib MainClass, like follows:
static class MainClass
{
static void Main(string[] args)
{
//solved mojave notfound dll exception
IntPtr p = Dlfcn.dlopen("/usr/lib/libc.dylib", 0);
NSApplication.Init();
NSApplication.SharedApplication.Delegate = new AppDelegate();
NSApplication.Main(args);
}
}

Related

Xamarin Forms Shell Navigation Failure with System.NullReferenceException

This is a sample application attempting the Xamarin Forms navigation capability.
We have an event handler with this simple logic:
async void Button_Clicked(System.Object sender, System.EventArgs e)
{
await Shell.Current.GoToAsync(nameof(SchoolList));
}
We also have the route registered in App.xaml.cs as follows:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
Routing.RegisterRoute(nameof(SchoolList), typeof(SchoolList));
}
However, when the corresponding button is clicked, we get the error below:
System.NullReferenceException: Object reference not set to an instance of an object.
at cross_app1.MainPage.Button_Clicked (System.Object sender, System.EventArgs e) [0x0000f] in /Users/klaus.nji/Projects/cross-app1/cross-app1/MainPage.xaml.cs:18
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-30/mcw/Java.Lang.IRunnable.cs:84
at at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.39(intptr,intptr)
The system is Mac Catalina v10.15.7, IDE is Visual Studio 2019 for Mac and I have the Andriod SDK installed and able to see other aspects of the app.
It looks like you don’t have a Shell, so Shell.Current is null.
What Shell example did you follow?
MainPage = new MainPage(); means your app is pointing to a page of type MainPage. To use Shell (Route) navigation, it needs to be pointing to a Shell.
I would expect to see MainPage = new AppShell();.
There may be other details missing, so be sure to follow a working example, such as Xaminals.
The new AppShell line can be seen in https://github.com/xamarin/xamarin-forms-samples/blob/main/UserInterface/Xaminals/Xaminals/App.xaml.cs.
Note: Its possible to navigate in Xamarin Forms without having Shell, nor defining routes. (Personally, I dislike the Shell, so I don’t use it.) You can define MainPage as a NavigationPage (see its doc). Or you can simply set App.MainPage to different pages, to move between them, without a navigation stack.

How to prevent a NullReferenceException when calling ReceiveEndpoint for MassTransit SQS?

I use MassTransit in a .NET core web application (web api) to use SQS. It was working fine for publishing messages. But after I tried to add a consumer, I ran into an issue.
Here is my code
public static void UseMassTransit(this IServiceCollection services, MassTransitConfiguration massTransitConfiguration)
{
services.AddMassTransit(x =>
{
x.AddConsumer<CustomerChangeConsumer>();
x.UsingAmazonSqs((context, cfg) =>
{
cfg.Host(massTransitConfiguration.Host, h =>
{
h.AccessKey(massTransitConfiguration.AccessKey);
h.SecretKey(massTransitConfiguration.SecretKey);
cfg.ReceiveEndpoint("CustomerChangeConsumer",
configurator =>
{
configurator.ConfigureConsumer<CustomerChangeConsumer>(context);
});
// scope topics as well
h.EnableScopedTopics();
});
});
});
services.AddMassTransitHostedService();
}
The problems is that ReceiveEndpoint gives a NullReferenceException.
This is strange as ConfigureConsumer is executed.However, ReceiveEndpoint just cannot fully finish without throwing this exception.
Here is the stacktrace:
MassTransit.AmazonSqsTransport.Configurators.ConfigurationHostSettings.FormatHostAddress()
System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
System.Lazy`1.CreateValue()
System.Lazy`1.Value
MassTransit.AmazonSqsTransport.Configurators.ConfigurationHostSettings.HostAddress
MassTransit.AmazonSqsTransport.Configuration.AmazonSqsHostConfiguration.HostAddress
MassTransit.AmazonSqsTransport.Configuration.AmazonSqsReceiveEndpointConfiguration.FormatInputAddress()
System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
System.Lazy`1.CreateValue()
System.Lazy`1.Value
MassTransit.AmazonSqsTransport.Configuration.AmazonSqsReceiveEndpointConfiguration.InputAddress
MassTransit.Monitoring.Health.EndpointHealth.EndpointConfigured(T configurator)
MassTransit.Monitoring.Health.BusHealth.MassTransit.EndpointConfigurators.IEndpointConfigurationObserver.EndpointConfigured[T](T configurator)
MassTransit.EndpointConfigurators.EndpointConfigurationObservable.<>c__DisplayClass0_0`1.<EndpointConfigured>b__0(IEndpointConfigurationObserver observer)
GreenPipes.Util.Connectable`1.All(Func`2 callback)
MassTransit.EndpointConfigurators.EndpointConfigurationObservable.EndpointConfigured(T configurator)
MassTransit.AmazonSqsTransport.Configuration.AmazonSqsHostConfiguration.CreateReceiveEndpointConfiguration(QueueReceiveSettings settings, IAmazonSqsEndpointConfiguration endpointConfiguration, Action`1 configure)
MassTransit.AmazonSqsTransport.Configuration.AmazonSqsHostConfiguration.CreateReceiveEndpointConfiguration(String queueName, Action`1 configure)
MassTransit.AmazonSqsTransport.Configuration.AmazonSqsHostConfiguration.ReceiveEndpoint(String queueName, Action`1 configureEndpoint)
MassTransit.AmazonSqsTransport.Configurators.AmazonSqsBusFactoryConfigurator.ReceiveEndpoint(String queueName, Action`1 configureEndpoint)
Kinley.SMPD.CustomerService.API.Extensions.MassTransitExtensions.<>c__DisplayClass0_1.<UseMassTransit>b__2(IAmazonSqsHostConfigurator h) in MassTransitExtensions.cs: line: 23
How come? And how to resolve?
You shouldn’t configure receive endpoints inside the host configuration closure. Try moving it outside the .Host() method and see if that resolves your issue.

Blazor 0.6.0 "wipes" Flurl-compatibility?

After updating Blazor from 0.5.1 (with working Flurl) to 0.6.0, calls via flurl throw an exception:
WASM: [Flurl.Http.FlurlHttpException] Call failed. Cannot invoke method
because it was wiped. See stack trace for details.
The project creates a HttpClientFactory which gets Blazor's HttpClient for being used by Flurl:
Create FlurlClient with Blazor's HttpClient (http) using HttpClientFactoryForBlazor:
IFlurlClient c = new FlurlClient() { Settings = new Flurl.Http.Configuration.ClientFlurlHttpSettings { HttpClientFactory = new HttpClientFactoryForBlazor(http) }};
Use the FlurlClient (c) for example by via Flurl's extensionmethod "IFlurlRequest.WithClient(c);"
private class HttpClientFactoryForBlazor : Flurl.Http.Configuration.IHttpClientFactory
{
private readonly HttpClient httpClient;
public HttpClientFactoryForBlazor(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public virtual HttpClient CreateHttpClient(HttpMessageHandler handler)
{
return this.httpClient;
}
}
So, it seems like this approach does no longer work.
Does anybody know how to make Flurl with Blazor 0.6.0 work?
Call-Stack is:
WASM: [Flurl.Http.FlurlHttpException] Call failed. Cannot invoke method because it was wiped. See stack trace for details. GET http://srv01.servicegrid.eu:4455/API/Status?forceLoadDbs=False blazor.webassembly.js:1:32098
WASM: at Flurl.Http.FlurlRequest.HandleExceptionAsync (Flurl.Http.HttpCall call, System.Exception ex, System.Threading.CancellationToken token) <0x26945b8 + 0x001c2> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM: at Flurl.Http.FlurlRequest.SendAsync (System.Net.Http.HttpMethod verb, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken, System.Net.Http.HttpCompletionOption completionOption) <0x2665d30 + 0x005e6> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM: at Flurl.Http.FlurlRequest.SendAsync (System.Net.Http.HttpMethod verb, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken, System.Net.Http.HttpCompletionOption completionOption) <0x2665d30 + 0x0079a> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM: at Flurl.Http.HttpResponseMessageExtensions.ReceiveJson[T] (System.Threading.Tasks.Task`1[TResult] response) <0x26a2180 + 0x000d6> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM: at DotNetFabrik.FlurlExtensions.FlurlRequestExtensions.HandleWebApiExceptions[T] (System.Threading.Tasks.Task`1[TResult] task) <0x26a43f8 + 0x000e2> in <8c1e6df9d3f545cd831ff49915df2d85>:0 blazor.webassembly.js:1:32098
WASM: at DotNetFabrik.FlurlExtensions.FlurlRequestExtensions.HandleWebApiExceptions[T] (System.Threading.Tasks.Task`1[TResult] task) <0x26a43f8 + 0x00264> in <8c1e6df9d3f545cd831ff49915df2d85>:0 blazor.webassembly.js:1:32098
WASM: at BlazorCoreDMSTools.CommunicationService.CommunicationService.SetTokenAsync (System.String token, System.String database, System.String serverUri) <0x260dc60 + 0x00d9e> in <cb925648b50340888772566fbaeac465>:0
Just for some background, the Blazor team is in the process of significantly reducing the app's footprint, and resorting to some unusual measures to do so. In a nutshell, they've reduced it by about 20% by "wiping" HttpClientHandler.
wipe means "replace specified method bodies with a single throw
instruction". Doing this (instead of actually removing the method
entirely) means that the assembly retains a completely standard API
surface, and if you try to use one of the wiped methods, you get an
easy-to-understand exception stack trace that tells you which wiped
method you're trying to call.
This is what you've bumped up against: Blazor is still aware of HttpClientHandler for compilation purposes, but will throw a runtime exception if you (or in this case a compatible library) try to use it.
But HttpClient must wrap some implementation of HttpMessageHandler Blazor has its own: BrowserHttpMessageHandler. And Flurl provides an easy way to swap this in via its HttpClientFactory. But you don't need to pass in an HttpClient instance or implement CreateHttpClient. Instead, inherit from DefaultHttpClientFactory and just override CreateMessageHandler:
private class HttpClientFactoryForBlazor : DefaultHttpClientFactory
{
public override HttpMessageHandler CreateMessageHandler()
{
return new BrowserHttpMessageHandler();
}
}
I'd also recommend registering this once globally on app startup, rather than every time you create a FlurlClient:
FlurlHttp.Configure(settings =>
{
settings.HttpClientFactory = new HttpClientFactoryForBlazor();
});
It should also be noted that Blazor is still experimental and that BrowserHttpMessageHandler may be deprecated in a future release, so expect that this could be just a temporary work-around.
Currently in my 3.0 preview 5, BrowserHttpMessageHandler is not there anymore. Here is my current fix by simply not using any HttpMessageHandler. As far as I am aware, no problem happens to me yet, but I am not sure in all use cases:
class BlazorHttpClientFactory : DefaultHttpClientFactory
{
public override HttpClient CreateHttpClient(HttpMessageHandler handler)
{
return new HttpClient();
}
public override HttpMessageHandler CreateMessageHandler()
{
return null;
}
}

MissingMethodException in iOS app while using Xamarin's FileHelper Implementation

I recently followed Xamarin's SQLite tutorial to install SQLite-net PCL. Everything works perfectly on the simulator in Debug mode but I'm getting crashes on startup in Release mode.
The exception is as follows:
exception:
System.MissingMethodException
message:
Default constructor not found for type MyApp.iOS.FileHelper
stack trace:
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain
(int,string[],intptr,intptr) at UIKit.UIApplication.Main
(System.String[] args, System.IntPtr principal, System.IntPtr
delegate) [0x00005] in
/Users/builder/data/lanes/3969/7beaef43/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String
principalClassName, System.String delegateClassName) [0x00038] in
/Users/builder/data/lanes/3969/7beaef43/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at MyApp.iOS.Application.Main (System.String[] args) [0x00008] in
/Users/{FilePath}/iOS/Main.cs:13
What I've found
So this MyApp.iOS.FileHelper is Xamarin's code that fetches the documents directory. The implementation goes like this:
In the Forms application we just have a contract:
public interface IFileHelper
{
string GetLocalFilePath(string filename);
}
In the MyApp.iOS project we define a dependency:
[assembly: Dependency(typeof(FileHelper))]
namespace MyApp.iOS
{
public class FileHelper : IFileHelper
{
public FileHelper() { }
public string GetLocalFilePath(string filename)
{
string docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string libFolder = Path.Combine(docFolder, "..", "Library", "Databases");
if (!Directory.Exists(libFolder))
{
Directory.CreateDirectory(libFolder);
}
return Path.Combine(libFolder, filename);
}
}
}
Here's how I am using it:
DependencyService.Get<IFileHelper>().GetLocalFilePath("MyAppDatabase.db3")
The application works as expected in Debug mode. So either the Dependency Service is behaving differently in Release or the Documents Directory is different in Release.
My Question
How can avoid this exception in release mode?
Dependency Info:
Xamarin Forms 2.3.3.193
Sqlite-net-pcl 1.2.1
update:
What I've tried:
Added a default constructor, yields no change
Tried different linker possibilities, yields no change
From Introduction to DependencyService
Note that every implementation must have a default (parameterless)
constructor in order for DependencyService to be able to instantiate
it. Parameterless constructors cannot be defined by the interface.
You need to add an empty constructor to your FileHelper class.
public FileHelper() {
}
Please note: I tried voting to close this question as a duplicate. It clearly
failed to be closed as such.
Based on comments point to this post from SushiHangover, this is what resolved my issue:
I needed to add decorate my FileHelper class in my iOS project with:
[Preserve(AllMembers = true)]
again, please go check out his original post here:
https://stackoverflow.com/a/41932246/1664443

realm in Xamarin, System.EntryPointNotfoundException when trying to use realm

I have installed realm in a Xamarin app and when I try to use an object (count, write, etc) it gives me a System.EntryPointNotFoundException.
Below code:
_realm = Realm.GetInstance();
_realm.Write(() =>
{
var myConfig = _realm.CreateObject<Config>();
myConfig.Email = "";
myConfig.User = "";
});
System.EntryPointNotFoundException: shared_realm_begin_transaction
at at (wrapper managed-to-native) Realms.NativeSharedRealm:begin_transaction (Realms.SharedRealmHandle)
at Realms.Transaction..ctor (Realms.SharedRealmHandle sharedRealmHandle) [0x0000d] in :0
at Realms.Realm.BeginWrite () [0x00000] in :0
at Realms.Realm.Write (System.Action action) [0x00000] in :0
at rasoApp.ConfigViewModel..ctor () [0x00025] in /Users/luis/Projects/rasoApp/rasoApp/viewModels/ConfigViewModel.cs:22
at rasoApp.ConfigPage.SetBinding (Xamarin.Forms.BindableProperty targetProperty, Xamarin.Forms.BindingBase binding) [0x0000e] in /Users/luis/Projects/rasoApp/rasoApp/views/ConfigPage.xaml.cs:13
at rasoApp.HomePage.btnOpenConfig (System.Object sender, System.EventArgs e) [0x00007] in /Users/luis/Projects/rasoApp/rasoApp/views/HomePage.xaml.cs:18
at Xamarin.Forms.Button.Xamarin.Forms.IButtonController.SendClicked () [0x00020] in :0
at Xamarin.Forms.Platform.iOS.ButtonRenderer.OnButtonTouchUpInside (System.Object sender, System.EventArgs eventArgs) [0x0000e] in :0
at UIKit.UIControlEventProxy.Activated () [0x00007] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/src/UIKit/UIControl.cs:38
at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/src/UIKit/UIApplication.cs:63
at rasoApp.iOS.Application.Main (System.String[] args) [0x00008] in /Users/luis/Projects/rasoApp/iOS/Main.cs:17
Congratulations on an interesting problem!
I have seen a similar error but only in recent work I was doing refining code generation, when I generated bad IL code. We have no previous issues recorded nor any discussions of EntryPointNotFoundException messages that I can find.
If you try building one of our examples from the Realm source download, such as QuickJournal does that work?
If you can send a full project demonstrating the problem to help#realm.io that is probably the fastest way to work out what is happening.
Update 2016-07-11
Looking at another SO question made me think of a few more things to try:
Does this happen on all platforms?
- Do you have Full Linking enabled in Xamarin studio?
Earlier Suggestions
Does your app have a PCL containing that logic?
Did you also install the Realm NuGet into the main application (IOS or Android) projects? That is a necessary step. The main Realm libraries are only included with the platform-specific dlls which NuGet adds to IOS or Android projects.

Resources