WebAuthenticationResult - System.NotImplementedException - c#

I am trying to implement Facebook authentication sample,
when code reaches at;
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,loginUrl);
I am getting exception like below;
Exception = {System.NotImplementedException: Not implemented
at
Windows.Security.Authentication.Web.WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions
options, Uri requestUri) at
SonglyWindowsPhone.Views.Login.d__0.MoveNext()
--- End ...
Message: The method or operation is not implemented.
Is there any workaround for this?

In WinRT it's similar situation to FilePickers - you have to use AuthenticateAndContinue method. Once you use the method, your app is deactivated and after finished authentication it will be activated, at that moment you should handle OnActivated event in app.xaml.cs:
protected async override void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
var continuationEventArgs = args as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
switch (continuationEventArgs.Kind)
{
case ActivationKind.WebAuthenticationBrokerContinuation:
ValueSet data = continuationEventArgs.ContinuationData;
// continue web authentication
break;
// rest of code
At the WebAuthenticationBroker class you will also find a link to a sample.
And here at MSDN is nice explanation with sample code.

Related

WebView2 - NavigateToString method returns "Operation Cancelled" error

The NavigateToString method returns an error for any html string provided as a parameter.
The event handler for NavigationCompleted returns Operation Canceled. Most likely the initialization is incorrect or incomplete but nut sure what.
Can you please help with a working C# sample so I can learn how to use webview2?
async void InitializeAsync()
{
var env = await Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(userDataFolder: cacheDirectory);
await webView21.EnsureCoreWebView2Async(env);
webView21.Dock = System.Windows.Forms.DockStyle.Right; //Fill
webView21.NavigationStarting += EnsureHttps;
webView21.NavigationCompleted += WebView21_NavigationCompleted;
}
...
...
webView21.CoreWebView2.NavigateToString("<html>HELLO!</html>"); //Fails
webView21.CoreWebView2.Navigate("https://www.google.com"); //Works
Since you can call Navigate("https://www.google.com") but not NavigateToString("<html>HELLO!</html>") the problem must be in the difference.
And that is most likely caused by your EnsureHttps method.
When you use NavigateToString it's NOT https! The url of the new page is about:blank!
So you should check that in your EnsureHttps method and not redirect/change url if the url is about:blank.

NLog Raygun - How to catch exception when calling SendInBackground

I forked the NLog Raygun from Mindscape to provide more settings of Raygun in NLog.
A RaygunTarget is created and needs to override Write method as follows NLog document (https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target).
To send an exception to Raygun, follows the below code
protected override void Write(LogEventInfo logEvent)
{
_raygunClient ??= (_raygunClient = CreateRaygunClient());
...
_raygunClient.SendInBackground(exception, tags, userCustomData);
}
SendInBackground returns a Task which we can not mark Write method as async void because it's not the case of using async void.
Everything works fine. We have a swagger to have Healthcheck. I want to check if NLog Raygun is sent successfully but I don't know how to catch the exception in SendInBackground in case API Key is invalid. I mean is there a better way to test whether this RaygunTarget can send a message successfully to Raygun?
If I provide a setting called ThrowOnError and in Write method updated like this
protected override void Write(LogEventInfo logEvent)
{
_raygunClient ??= (_raygunClient = CreateRaygunClient());
...
var task = _raygunClient.SendInBackground(exception, tags, userCustomData);
if (_setting.ThrowOnError) task.Wait();
}
It works but a question is: This is a good way to do that? Personally, I think it's not because it introduces a different behavior or side-effect based on a setting.
Instead of inheriting from TargetWithLayout then you can inherit from AsyncTaskTarget:
protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
{
_raygunClient ??= (_raygunClient = CreateRaygunClient());
...
var userCustomData = base.GetAllProperties(logEvent);
return _raygunClient.SendInBackground(exception, tags, userCustomData);
}
See also: https://github.com/NLog/NLog/wiki/How-to-write-a-custom-async-target
Then you can hook into the NLog InternalLogger using InternalLogger.LogWriter, and forward to healthcheck-api.
There are plans to improve the API for NLog 5.0 so one can subscribe to an InternalLogger-Event and can also get more context details. Like Target-Name, Target-Type etc. See also: https://github.com/NLog/NLog/issues/3350

Method Prerequisites

The Situation
I'm working on a OAuth2 Api Wrapper. Some api routes are for logged people and some for anonymous and logged.
Here is an example of one method in my wrapper :
public async Task<UploadListResponse> List(bool pagination = false, int page = 1, int limit = 10)
{
var request = UploadRequests.List(pagination, page, limit);
var cancellationTokenSource = new CancellationTokenSource();
var restResponse = await Context.Client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
return restResponse.Handle<UploadListResponse>();
}
I build a request with all parameter set up then execute the request and then handle the answer in case I have an api error and then output an object containing all the data that request gave me.
The problem
With OAuth2, when you log to the API you'll receive an access token and a refresh token. If your access token is expired you have to contact the api with your refresh token to get a fresh new access token.
As I said earlier some of my method needs you to be logged but if your access token is expired I want to try to refresh token before throwing an exception like with this method :
public async Task<bool> NeedRelog()
{
try
{
var validAuth = await ValidAuth();
}
catch
{
try
{
var refresh = await Refresh(Context.Client.Config.RefreshToken);
}
catch
{
return true;
}
}
return false;
}
ValidAuth check with the API if you are logged and if I have an exception then I'll try to refreshToken.
I want to tag method that need logged to call NeedRelog() and those who aren't tag to not call it.
I may just do it in every method but it wouldn't be clean.
What I've done so far
I've found a great tool : PostSharp that seems to fit my needs.
I've started to do a checkLog aspect like this :
[Serializable]
public class CheckLog : OnMethodBoundaryAspect, IOnStateMachineBoundaryAspect
{
public CheckLog()
{
ApplyToStateMachine = false;
}
public override void OnEntry(MethodExecutionArgs args)
{
var instance = (ApiService)args.Instance;
var res = instance.Parent.OAuth.NeedRelog().Result;
if (!res)
{
args.Exception = new Exception("Need to relog");
args.FlowBehavior = FlowBehavior.Return;
}
}
}
Where I'm stuck
The Main problem is with the call to my NeedRelog() Method. Due to the fact this is an async method I'm struggling to make my aspect await for it.
If my OnEntry method is async then It won't block the call if you are not logged.
If my OnEntry method is not async and I wait for needLog it freeze and nothing happen.
I really want to know to use this kind of "conditional method call" with postsharp, it looks awesome but the fact is after looking for hours in the documentation I didn't find a way to do what I want.
I'm starting to ask myself if it is even possible to achieve what I'm aiming to do.
Did you try using a way to make the call synchronous maybe with something like this stackoverflow.com/a/25097498/3131696 ? – M22an 5 hours ago
As I can't mark a comment as answering a question I quote your comment to make this question answered as it is said here : link
Thanks you for this M22an.

Converting EAP web service call to await/async

I have a web reference which uses the Event-based Asynchronous Pattern. I am trying to convert this to use the Task based model so that I can use await/async. However I am having issues with this as it does not seem to do the call. I am using MonoTouch C# for this project.
Earlier I found this Stack overflow post which seemed to detail what I'm trying to do: How can I use async/await to call a webservice?
I managed to setup these methods and this is what my code looks like so far:
Authentication
var client = new AgentService();
GetUserDetailsCompletedEventArgs response = await client.GetUserDetailsAsyncTask(username, password);
if (response.Result != null)
// Do stuff
Agent Service Extensions
public static Task<GetUserDetailsCompletedEventArgs> GetUserDetailsAsyncTask(this AgentService client, string username, string password)
{
var source = new TaskCompletionSource<GetUserDetailsCompletedEventArgs>(null);
client.GetUserDetailsCompleted += (sender, e) => TransferCompletion(source, e, () => e);
client.GetUserDetailsAsync(username, password);
return source.Task;
}
private static void TransferCompletion(TaskCompletionSource<GetUserDetailsCompletedEventArgs> source, AsyncCompletedEventArgs e, Func<GetUserDetailsCompletedEventArgs> getResult)
{
if (e.UserState == source)
if (e.Cancelled)
source.TrySetCanceled();
else if (e.Error != null)
source.TrySetException(e.Error);
else
source.TrySetResult(getResult());
}
At the moment the GetUserDetailsAsyncTask method is called and the event handler is set but is never reached. After the await line is called the statement underneath it is never reached either and just skips to the end of the method. No error message is displayed and no exception is thrown. I'm not sure where I'm going wrong and I'd appreciate any guidance to help me solve this.

Response.Redirect issue with Asp.net async

I'm new to asp.net 4.5 async and am running into the following with calling response.redirect within an async method. The issue is that the response just "hangs" Has anyone else experienced similar issues with attempting an redirect with async? This code will work in a brand new project, but, does not work with a new page in our existing code. I made sure to gut out everything I could out of our web.config and removed our master page. Hitting a brick wall...any ideas? Thanks!
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(PageLoadAsync));
}
private async Task PageLoadAsync()
{
var data = await GetData();
if (data == HttpStatusCode.OK)
Response.Redirect("http://www.google.com");
}
private async Task<HttpStatusCode> GetData()
{
using (var client = new HttpClient())
{
var response = await client.GetAsync("https://www.google.com");
return response.StatusCode;
}
}
This code will work in a brand new project, but, does not work with a new page in our existing code.
I assume your existing site has already been upgraded to .NET 4.5.
The first thing to check is that httpRuntime.targetFramework is set to 4.5. This is not set by default when you upgrade.
Edit from comments:
Another thing to check (just in case) is that Page.Async is set to true.
In this case, the solution was to call Response.Redirect("http://www.google.com", false), which explicitly passes false for the endResponse parameter. The default value of true is only for backwards-compatibility reasons as described here.
The hack I used is:
I used a static dictionary as var d= new Dictionary<string, bool>(); in the class where my API calling method is written.
I put the code line client.timeout = new System.TimeSpan(0,0,60); for API sending the request.
When API is timed out, it throws the TaskTimeoutException, in the TaskTimeoutExceptioncatch block write code as d.Add("timeout", true);
Now, I created the custom action filter and applied the following code:
public class MyCustomActionFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if(MyApiClass.d.ContainsKey("timeout") && d["timeout"])
{
throw new Exception();
}
}
}
I applied the [MyCustomActionFilter ] on the action.
When action is executed and enter the custom filter it throws Exception by checking the dictionary entry.
If timeout would have occurred then dictionary entry will be true, so, on the basis of that, we check the entry and throws the exception. Now, we have Application_Error() in Global.asax.cs that catches the exception.
In the Application_Error() we have written the code for redirect to the required page.
NOTE: In step 4 you can create your custom exception to provide more precise detail for logging.

Categories