success and failure callbacks in realm xamarin - c#

I am looking for callbacks related to add and read data in realm with xamarin.
Here i am fetching data from server and adding into realm , but i want an event where in i can notify UI that company data has been added to realm successfully and if any error comes i can show that too.
var content = await response.Content.ReadAsStringAsync();
Company company = JsonConvert.DeserializeObject<Company>(content);
Realm realm = Realm.GetInstance();
await realm.WriteAsync(tempRealm => {
tempRealm.Add(company);
});
in android native we have following function to execute any transaction in background and can notify for success and failure.
final Realm realm = Realm.getInstance(App.getRealmConfig());
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(userResponseInfo.getCallInfoList());
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
}
});

Realm Xamarin uses the standard .NET mechanism of propagating errors from tasks, which is why you don't need a success and error callbacks. If an error occurred, an exception will be thrown that can be handled in a regular try-catch block:
try
{
var realm = Realm.GetInstance();
await realm.WriteAsync(temp => temp.Add(company));
// if control reaches this line the transaction executed successfully.
notifier.NotifySuccess();
}
catch (Exception ex)
{
// The transaction failed - handle the exception
notifier.NotifyError(ex.Message);
}

Related

Why I am getting AADSTS50011 error when using Microsoft OneDrive sample with UWP app

On VS2019, when using this OneDrive sample with UWP from Microsoft, I am getting the following error. An online search shows some relevant links (such as this or this or this) but their context are different (as they are using web apps or Python etc.):
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: '55dbdbc9-xxxxxxxxxxxxx-a24'
I have followed the sample's instructions for Registering and Configuring the app where Redirect URI I have selected is Public client (mobile & desktop), and have set it's value to https://login.microsoftonline.com/common/oauth2/nativeclient
Question: What I may be doing wrong, and how can we resolve the issue?
UPDATE:
Error occurs at line FolderLoaded?.Invoke(this, EventArgs.Empty); of the method shown below. This is line 180 of file OneDriveList.xaml.cs in the sample. And it is not the error OperationCanceledException since error goes to the second catch statement.
private async Task LoadFolderAsync(string id = null)
{
// Cancel any previous operation
_cancellationTokenSource?.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
// Check if session is set
if (AuthenticationService == null) throw new InvalidOperationException($"No {nameof(AuthenticationService)} has been specified");
// Keep a local copy of the token because the source can change while executing this function
var token = _cancellationTokenSource.Token;
// Add an option to the REST API in order to get thumbnails for each file
// https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_thumbnails
var options = new[]
{
new QueryOption("$expand", "thumbnails"),
};
// Create the graph request builder for the drive
IDriveRequestBuilder driveRequest = AuthenticationService.GraphClient.Me.Drive;
// If folder id is null, the request refers to the root folder
IDriveItemRequestBuilder driveItemsRequest;
if (id == null)
{
driveItemsRequest = driveRequest.Root;
}
else
{
driveItemsRequest = driveRequest.Items[id];
}
// Raise the loading event
FolderLoading?.Invoke(this, EventArgs.Empty);
try
{
try
{
// Make a API request loading 50 items per time
var page = await driveItemsRequest.Children.Request(options).Top(50).GetAsync(token);
token.ThrowIfCancellationRequested();
// Load each page
await LoadGridItemsAsync(page, token);
token.ThrowIfCancellationRequested();
}
finally
{
// Raise the loaded event
FolderLoaded?.Invoke(this, EventArgs.Empty);
}
}
catch (OperationCanceledException)
{ }
catch (Exception ex)
{
// Raise the error event
LoadingError?.Invoke(this, ex);
}
}

C# / UWP / MVVM - How to handle HttpClient exceptions when the server is unrechable

I am currently working on an UWP app, that will run on a Raspberry PI. Most of my application can be used without an internet connection, but parts of it rely on fetching data from a server ran locally.
My issue is that whenever the server is offline, I can not handle the exceptions raised by the HttpClient.
To avoid using async tasks in the constructor of the ViewModel, I've moved it to the OnLoaded method of the View.
These are the methods that I use:
HomeAssistantView
private async void OnLoaded(object sender, RoutedEventArgs e)
{
await ViewModel.LoadEntities();
}
HomeAssistantViewModel
public async Task LoadEntities()
{
var entityList = await _homeAssistantService.LoadEntities();
Switches = new ObservableCollection<HomeAssistantSwitchEntity>(entityList.OfType<HomeAssistantSwitchEntity>());
Entities = new ObservableCollection<HomeAssistantEntity>(entityList.Where(entity =>!(entity is HomeAssistantSwitchEntity)));
}
HomeAssistantService
public async Task<List<HomeAssistantEntity>> LoadEntities()
{
_client.BaseAddress = new Uri(_homeAssistantURL);
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_homeAssistantToken}");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = await _client.GetAsync("api/states");
if (response.IsSuccessStatusCode)
{
return DeserializeConfigFile(await response.Content.ReadAsStringAsync());
}
}
catch (HttpRequestException e)
{
Debug.WriteLine(e.Message);
}
return new List<HomeAssistantEntity>();
}
Even though I've added a try block, the application raises a System.Exception, with the message "The server name or address could not be resolved". After disabling the generic Exception type in the settings, Visual Studio told me it was a type of HttpRequestException with the message An error occurred while sending the request.
In a different part of my application, where I use a weather API, I got away with using the NetworkInformation.GetInternetConnectionProfile() to check whether there is an internet connection available prior to sending a request, but it's not a viable option here. Also, I've thought of sending a ping to the server prior to trying to fetch the data, but as far as I'm concerned, pinging is not available on the Windows 10 IoT Core.
I understood, that, you don't want the exception to be thrown, is this correct?
If yes just replace
catch (HttpRequestException e)
{
Debug.WriteLine(e.Message);
}
with
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
this will catch all occuring exceptions

Handling exceptions thrown when an Akka.NET Actor responds to an async request from a stream

When integrating an actor with an Akka.NET stream as described in the Akka.NET integration docs I hit a problem with exception handling. If the actor just throws an exception then Akka swallows it, and I have to wait for the timeout to trigger for it to get reported.
I'm inferring that this is because the actor doesn't send a message back to the stream. Taking the old-school approach of using a big try-catch at a thread boundary I can marshall an exception into a message for the sender, which allows it to break through the timeout and carry on.
Example code below. As far as I can tell there's no way I can create a supervisor strategy that'll allow the stream to handle the actor's exception. What's the best pattern for handling this?
// Run app with argument "straightThrow" or "catchAndHandle"
class Bleurgher : ReceiveActor
{
public Bleurgher()
{
Receive<string>(s =>
{
switch (s) {
case "straightThrow":
throw new Exception("Bleurgh");
break;
case "catchAndHandle":
try
{
throw new Exception("Bleurgh");
}
catch (Exception x)
{
Console.WriteLine($"Exception : {x.Message}");
Sender.Tell(new Akka.Actor.Status.Failure(x));
};
break;
}
});
}
public static Akka.Actor.Props Props()
{
return Akka.Actor.Props.Create<Bleurgher>();
}
}
class Program
{
static void Main(string[] args)
{
using (var system = ActorSystem.Create("cast"))
using (var materializer = system.Materializer())
{
var data = new List<string>(args);
var bleurgher = system.ActorOf(Bleurgher.Props());
var source = Source.From(data);
var sink = Sink.ForEach<string>(s => Console.WriteLine(s));
var runnable = source
.SelectAsync(1, o => bleurgher.Ask(o, TimeSpan.FromSeconds(5)))
.Select(o => (o.ToString()))
.ToMaterialized(sink, Keep.Right);
runnable.Run(materializer).Wait();
}
}
}

MVVM Light making an HTTP Get request using Webapi

I am a newbie when it comes to MVVM and Web related technologies. We are currently developing an MVVM client app using the latest MVVMLight framework in Visual Studios 2013. The application uses Microsoft's Webapi (latest version) to get data into our model via HTTP requests. Our code executes up to the point where the HTTP request is made, and we have confirmed that the server is getting the request, gathering up the requested data and returning it as JSON. However the client never sees the response, it just continues to wait for the response. Its almost as though we are seeing an issue that seems to do with threads. Where the request was made on one thread, but the response is being received on another. Here is our code (where the HTTP request is made):
public class DataService : IDataService
{
#region Fields
private HttpClient _client;
private LfActivityDataReturnObject _activityReturnObj;
private AdroServices _adroServices;
private bool _selectedProcssingOptionPosted = false;
private bool _activityDataSuccessfullyRetrieved = false;
private decimal _incomingLFEntryId;
#endregion
#region Constructor
public DataService()
{
try
{
//Get command line arguments
string[] arguments = Environment.GetCommandLineArgs();
for (int i = 1; i < arguments.Length; i++)
{
switch (i)
{
case 1:
{
if (!Decimal.TryParse(arguments[i], out _incomingLFEntryId))
{
_incomingLFEntryId = -1;
}
break;
}
}
}
if (_incomingLFEntryId <= 0)
{
throw new ArgumentException(String.Format("Invalid Activity Shortcut Entry ID: {0}", _incomingLFEntryId));
}
}
catch (Exception e)
{
throw e;
}
}
#endregion
#region Methods
public void GetGeneralInformationModel(Action<GeneralInformationModel, Exception> callback)
{
Exception locException = null;
GeneralInformationModel locGeneralInformationModel = null;
if (_adroServices == null)
{
try
{
//Start the HTTP request
GetActivityDataAsync().Wait();
}
catch (Exception e)
{
locException = e;
}
// change? should be for http success but adro failure
if (_activityDataSuccessfullyRetrieved)
{
_adroServices = new AdroServices(_activityReturnObj);
locGeneralInformationModel = new GeneralInformationModel(_adroServices);
}
else
{
Exception e2 = new Exception("Error retrieving activity data in DataService");
locException = e2;
}
}
else
{
locGeneralInformationModel = new GeneralInformationModel(_adroServices);
}
var item = locGeneralInformationModel;
callback(item, locException);
}
//Get data from the repository via the service layer.
private async Task GetActivityDataAsync()
{
try
{
using (this._client = new HttpClient())
{
_client.BaseAddress = new Uri("http://localhost:52512//");
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Line below is where the app just runs getting no response
HttpResponseMessage caseDataResponse = await _client.GetAsync(string.Format("api/LfUrs/{0}", _incomingLFEntryId));
if (caseDataResponse.IsSuccessStatusCode)
{
_activityReturnObj = await caseDataResponse.Content.ReadAsAsync<LfActivityDataReturnObject>();
if (_activityReturnObj.ReturnCode == 0)
{
_activityDataSuccessfullyRetrieved = true;
}
else
{
_activityDataSuccessfullyRetrieved = false;
}
}
else
{
_activityDataSuccessfullyRetrieved = false;
}
}
}
catch (Exception ex)
{
_activityDataSuccessfullyRetrieved = false;
throw ex;
}
}
We have tried using Fiddler to get more information but Fiddler doesn't seem to be able to reveal any of the details. Also I should mention that we are simulating the server on the local host and as I stated above, we have confirmed the server gets the request and returns the data. My associates and I are starting to think this has something to do with the MVVM Light Framework and the IOC or possibly threading. When we use this same code in a MVVM solution that doesn't use the framework it works. Any help would be sincerely appreciated. Thanks...Mike
I have figured it out. Somehow, in my app.xaml, the Dispatcher.Helper had been moved to the event On_Startup rather than being contained in the class constructor. Additionally I had to move the HTTP stuff into the ADRO services class and make sure it was constructed in the App constructor in app.xaml right after Dispatcher.Helper. But thanks to everyone who participates here on StackOverFlow. This resource is an absolute life-saver. Thanks

Using WebJobs with Azure Service Bus and Sessions

I'm new to the Azure Service Bus and am working on a proof of concept using Service Bus Queues, WebJobs, v2.5 of the Azure SDK and Visual Studio 2013
Enqueuing and de-queuing messages from the bus is pretty straightforward, but in order to implement a request-response pattern it looks like I need to use sessions, and that's where the wheels have come off.
Here's the proof-of-concept code from the WebJobs project. It requires that you create two service bus queues: test-request and test-response. The response queue must have Enable Sessions = true
class Program
{
private static string _azureServiceBusConnection;
static void Main()
{
_azureServiceBusConnection = ConfigurationManager.ConnectionStrings["AzureWebJobsServiceBus"].ConnectionString;
var host = new JobHost();
Task.Factory.StartNew(() => Run());
try
{
host.RunAndBlock();
}
catch (Exception ex)
{
Console.WriteLine("RunAndBlock() Unexpected {0}: {1}", ex.GetType().FullName, ex.Message);
throw;
}
}
private static async Task Run()
{
await Task.Delay(1000);
var request = QueueClient.CreateFromConnectionString(_azureServiceBusConnection, "test-request");
var response = QueueClient.CreateFromConnectionString(_azureServiceBusConnection, "test-response");
var sessionid = Guid.NewGuid().ToString();
MessageSession receiver;
try
{
receiver = response.AcceptMessageSession(sessionid);
}
catch (Exception ex )
{
Console.WriteLine("AcceptMessageSession() Unexpected {0}: {1}", ex.GetType().FullName, ex.Message);
throw;
}
var payload = new RequestModel {ID = Guid.NewGuid(), Delay = 1};
var message = new BrokeredMessage(payload) {ReplyToSessionId = sessionid};
try
{
request.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Send() Unexpected {0}: {1}", ex.GetType().FullName, ex.Message);
throw;
}
var receivedMessage = receiver.Receive(TimeSpan.FromSeconds(5));
if (receivedMessage != null)
{
// Request processed within the timeout period
var responseBody = receivedMessage.GetBody<RequestModel>();
Console.WriteLine("Inline response to {0}", responseBody.ID );
receivedMessage.Complete();
}
else
{
// Request processing timed out - should be handled by LocalResponseQueue WebJob (see below)
Console.WriteLine("ERROR: Response timed out.");
}
}
}
public class RequestModel
{
public Guid ID { get; set; }
public int Delay { get; set; }
}
public class RemoteSystemRequestQueue
{
// Simulates the processing of the request on a remote system
public static void ProcessQueueMessage([ServiceBusTrigger("test-request")] BrokeredMessage request, [ServiceBus("test-response")] out BrokeredMessage response)
{
// Wait for the prescribed delay, then bounce the request payload back via the response queue
var requestBody = request.GetBody<RequestModel>();
Console.WriteLine("Recieved Request {0}, delay={1}", requestBody.ID, requestBody.Delay);
Task.Delay(requestBody.Delay * 1000).Wait();
response = new BrokeredMessage(requestBody) {SessionId = request.ReplyToSessionId};
request.Complete();
Console.WriteLine("Completed Request {0}, delay={1}", requestBody.ID, requestBody.Delay);
}
}
public class LocalResponseQueue
{
// Should be called ONLY when the processing took longer than the timeout
public static void ProcessQueueMessage([ServiceBusTrigger("test-response")] BrokeredMessage message, TextWriter logger)
{
var msgBody = message.GetBody<RequestModel>();
Console.WriteLine("ResponseFactory Recieved Reply {0}", msgBody.ID);
}
}
When Enable Sessions = true on the test-response queue, the call to host.RunAndBlock() throws a System.InvalidOperationException with the message
It is not possible for an entity that requires sessions to create a non-sessionful message receiver
The output looks like this:
Found the following functions:
ServiceBusPoc.RemoteSystemRequestQueue.ProcessQueueMessage
ServiceBusPoc.LocalResponseQueue.ProcessQueueMessage
Executing: 'RemoteSystemRequestQueue.ProcessQueueMessage' because New service bus message detected on 'test-request'.
Recieved Request 4f000f8f-dd69-4909-9ec4-020fec12366c, delay=1
RunAndBlock() Unexpected System.InvalidOperationException: It is not possible for an entity that requires sessions to create a non-sessionful message receiver.
TrackingId:7836ac90-6920-4e6c-b7f1-cf648e2a17e5_G38_B10,TimeStamp:10/6/2015 12:37:05 PM
Note that the exception was thrown BEFORE the RemoteSystemRequestQueue object could complete processing the queued request
I presume from this that this means that WebJobs can't handle sessions (at least in the manner in which I'm using them)
Can anyone shed any light on this, or am I going to have to give up on WebJobs?
What version of the WebJobs SDK are you using? In our current v1.1.0 release (still prerelease) we've started opening up more options for ServiceBus configuration. See:
ServiceBusConfiguration
Custom MessagingProvider
You can basically now control more of the messaging details that were previously buried in the SDK internals. However, regarding full Session support, we do have this open issue that might be closer to your scenario. If so, and if you can't get things to work with the above, please add your scenario details to that issue. Thanks.

Categories