Method not found Microsoft.Owin.Security.Notifications.MessageReceivedNotification - c#

Recently i've updated packages in an mvc project with owin to 4.0.0
Now up until now I was able to solve a lot of issues with this upgrade (other packages that needed upgrading etc)
But currently I'm stuck on this exception:
Method not found: 'System.Func`2<Microsoft.Owin.Security.Notifications.MessageReceivedNotification`2<Microsoft.IdentityModel.Protocols.OpenIdConnectMessage,Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions>,System.Threading.Tasks.Task> Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationNotifications.get_MessageReceived()'.
I've tried googling, I've tried putting a breakpoint on the inflicted class (constructor get's hit but the method that throws the exception never gets hit even)
Anyone has a clue on what to try next? Or even better on how to fix this one?
protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
{
if (Options.CallbackPath.HasValue && Options.CallbackPath != (Request.PathBase + Request.Path))
{
return null;
}
OpenIdConnectMessage openIdConnectMessage = null;
if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase)
&& !string.IsNullOrWhiteSpace(Request.ContentType)
&& Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase)
&& Request.Body.CanRead)
{
if (!Request.Body.CanSeek)
{
//this._logger.WriteVerbose("Buffering request body");
// Buffer in case this body was not meant for us.
var memoryStream = new MemoryStream();
await Request.Body.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
Request.Body = memoryStream;
}
var form = await Request.ReadFormAsync();
Request.Body.Seek(0, SeekOrigin.Begin);
openIdConnectMessage = new OpenIdConnectMessage(form);
}
if (openIdConnectMessage == null)
{
return null;
}
ExceptionDispatchInfo authFailedEx = null;
try
{
var messageReceivedNotification = new MessageReceivedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(this.Context, this.Options)
{
ProtocolMessage = openIdConnectMessage
};
await this.Options.Notifications.MessageReceived(messageReceivedNotification);
if (messageReceivedNotification.HandledResponse)
{
return null;
}
if (messageReceivedNotification.Skipped)
{
return null;
}
// runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we should process.
AuthenticationProperties properties = null;
if (properties == null)
{
return null;
}
}
catch (Exception exception)
{
// We can't await inside a catch block, capture and handle outside.
authFailedEx = ExceptionDispatchInfo.Capture(exception);
}
if (authFailedEx != null)
{
//Refresh the configuration for exceptions that may be caused by key rollovers.The user can also request a refresh in the notification.
if (this.Options.RefreshOnIssuerKeyNotFound && authFailedEx.SourceException.GetType() == typeof(SecurityTokenSignatureKeyNotFoundException))
{
this.Options.ConfigurationManager.RequestRefresh();
}
var authenticationFailedNotification = new AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(this.Context, this.Options)
{
ProtocolMessage = openIdConnectMessage,
Exception = authFailedEx.SourceException
};
await this.Options.Notifications.AuthenticationFailed(authenticationFailedNotification);
if (authenticationFailedNotification.HandledResponse)
{
return null;
}
if (authenticationFailedNotification.Skipped)
{
return null;
}
authFailedEx.Throw();
}
return null;
}
}
The above code is the least amount of code needed to make this error occur, as soon as the code uses anything that comes from options.notifications the application immediately crashes with a method not found exception.
Notification property has been setup as follows:
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = context =>
{
if (Startup.IsApiRequest(context.Request))
{
context.HandleResponse();
return Task.FromResult(0);
}
context.ProtocolMessage.RedirectUri = redirectUri;
context.ProtocolMessage.PostLogoutRedirectUri = postLogoutRedirectUri;
return Task.FromResult(0);
},
AuthenticationFailed = context =>
{
context.OwinContext.Response.Redirect("/Home/Error");
context.HandleResponse(); // Suppress the exception
return Task.FromResult(0);
},
AuthorizationCodeReceived = context =>
{
var userIdentity = context.AuthenticationTicket.Identity;
userIdentity = userIdentity.TransformClaims();
context.AuthenticationTicket = new AuthenticationTicket(
userIdentity,
context.AuthenticationTicket.Properties
);
return Task.FromResult(0);
},
SecurityTokenReceived = context => Task.FromResult(0),
}
});
Little fyi I'm not the original developer of this code....

Try to replace
using Microsoft.IdentityModel.Protocols;
with
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
everywhere in your code. That should solve the issue.

Related

How to use OdataNextLink in Microsoft Graph API Beta 5

I was using the Microsoft Graph API 1.0 but have updated to the Beta in order to use CustomSecurityAttributeValue support.
I've managed to port most of the code but I can't see any way to process multiple results pages.
Previously you would just do something like
if (membersPage.NextPageRequest != null)
membersPage = await membersPage.NextPageRequest.GetAsync();
But NextPageRequest no longer exists, the only available information is OdataNextLink which is a string with no obvious way to request the next page or create a raw request using the url.
Code I have so far:
public async Task<IEnumerable<Microsoft.Graph.Beta.Models.User>> GetGraphUsersInGroups(IEnumerable<string> groupIds, string? searchText = null)
{
Dictionary<String, Microsoft.Graph.Beta.Models.User> users = new Dictionary<String, Microsoft.Graph.Beta.Models.User>();
foreach (var groupId in groupIds)
{
try
{
var membersPage = await GraphClient.Groups[groupId].Members
.GetAsync((memberRequest) => {
memberRequest.Headers.Add(new KeyValuePair<string, string>("$count", "true"));
memberRequest.Headers.Add(new KeyValuePair<string, string>("ConsistencyLevel", "eventual"));
memberRequest.QueryParameters.Count = true;
memberRequest.QueryParameters.Orderby = new[] { "displayName" };
if (searchText != null)
memberRequest.QueryParameters.Search = $"\"displayName:{searchText}\"";
});
while (membersPage != null)
{
foreach (var member in membersPage.Value.OfType<Microsoft.Graph.Beta.Models.User>())
{
users[member.Id] = member;
}
if (membersPage.OdataNextLink != null)
{
// How to use membersPage.OdataNextLink???
}
else
break;
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
return users.Values;
}
You should use the PageIterator, see an example below:
var users = new List<User>();
var userResponse = await serviceClient.Users.GetAsync((builder) => {
// builder.SomeStuff
});
// Added the namespace here, just for some clarity :-)
var pageIterator = Microsoft.Graph.PageIterator<User,UserCollectionResponse>
.CreatePageIterator(serviceClient, userResponse, (user) =>
{
users.Add(user.Id);
return true; });

This OperationContextScope is being disposed out of order

I am calling WCF service in ASP.NET Core and everything is working fine, but whenever end of using gets executed, I get an error:
This OperationContextScope is being disposed out of order
I believe I am using wrong pattern to call WCF service using async/await but I am not sure what I am doing wrong.
Below is the code I am using to call a service.
[HttpPost]
public async Task<IActionResult> Runcase(IFormCollection formCollection)
{
if (ModelState.IsValid)
{
var runnumber = formCollection["Run number"];
await CallServiceasync();
return RedirectToAction("", "");
}
else
{
return View(formCollection);
}
}
public async Task CallServiceasync()
{
var product = p1.Value;
var a = product.first;
foreach (int Age in a.age)
{
foreach (int Gender in a.sex)
{
foreach (int Healthclass in a.uclass)
{
RequestData requestData = new RequestData()
{
ProductID = 534,
STATE = "CO",
AGE1 = Age,
SEX1 = Gender,
UND_CLASS1 = Healthclass,
};
RecieveResponseasync(requestData);
}
}
}
}
public async Task RecieveResponseasync(InputValues inputValues)
{
string reqedata = "";
string apikey = "001010iZno7001010L";
QuoteEngineService.MarketingSoftwareClient Service = new QuoteEngineService.MarketingSoftwareClient();
await Service.OpenAsync();
try
{
using (OperationContextScope scope = new OperationContextScope(Service.InnerChannel))
{
HttpRequestMessageProperty httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add("apikey", apikey);
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestMessage;
reqedata = inputValues.XmlSerializetoString();
var result = await Service.ProcessRequestAsync(reqedata, "4fa2-ae27");
var outputvalues = new OutputvaluesViewModel();
outputvalues = result.DeserializeToObject();
List<OutputValue> outputs = new List<OutputValue>();
if (outputvalues.InitialPremium != null)
outputs.Add(new OutputValue { Name = "InitialPremium", Result = outputvalues.InitialPremium});
if (outputvalues.TargetPremium != null)
outputs.Add(new OutputValue { Name = "TargetPremium", Result = outputvalues.TargetPremium });
foreach (var output in outputs)
{
await _context.outputValues.AddAsync(output);
await _context.SaveChangesAsync();
}
await Task.Delay(500);
}
}// **At this point I am getting error**
catch (Exception ex)
{
throw;
}
finally
{
if (Service.State == System.ServiceModel.CommunicationState.Opened)
{
await Service.CloseAsync();
}
}
}
From the docs:
Warning
Do not use the asynchronous "await" pattern within a OperationContextScope block. When the continuation occurs, it may run on a different thread and OperationContextScope is thread specific. If you need to call "await" for an async call, use it outside of the OperationContextScope block.

"Attempt to present Xamarin_Forms_Platform_iOS_ModalWrapper whose view is not in the window hierarchy" error with UIImagePickerController

I have an Xamarin.Forms-based app which runs on Android and iOS. Right now, I am implementing the feature of selecting images from the camera roll and uploading it to our server. Therefore, I am writing platform-specific code for iOS, which is where the error occurs.
I am calling the UIImagePickerController from a platform-specific renderer for iOS. It opens normally. But when tapping on an image in the UIImagePickerController nothing happens, except Visual Studio showing a message in the debug console:
"Warning: Attempt to present Xamarin_Forms_Platform_iOS_ModalWrapper: 0x155a7ed00 on Xamarin_Forms_Platform_iOS_PlatformRenderer: 0x153ead6a0 whose view is not in the window hierarchy!"
I googled and found somebody writing a function called "GetVisibleViewController" which i adapted to my project (you can see it below). On the ViewController which that function returns, I call the PresentModalViewController() method. Unfortunately, it is not working either. It is not possible to select a photo.
private void ChoosePhoto()
{
_imagePicker = new UIImagePickerController()
{
SourceType = UIImagePickerControllerSourceType.PhotoLibrary,
MediaTypes = new string[] { UTType.Image }
};
_imagePicker.FinishedPickingMedia += delegate (object sender, UIImagePickerMediaPickedEventArgs e)
{
var fileName = eopAppLibrary.Tools.GetTimestampJpegFileName("ScanToEop_iOS");
var jpegImageData = e.OriginalImage.AsJPEG();
var jpegBytes = jpegImageData.ToArray();
Events.RaiseFilePreviewNeeded(this, jpegBytes, fileName);
};
_imagePicker.Canceled += delegate (object sender, EventArgs e)
{
_imagePicker.DismissModalViewController(true);
};
var viewController = GetVisibleViewController();
viewController.PresentModalViewController(_imagePicker, true);
}
UIViewController GetVisibleViewController(UIViewController controller = null)
{
controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;
if (controller.PresentedViewController == null)
{
return controller;
}
if (controller.PresentedViewController is UINavigationController)
{
return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
}
if (controller.PresentedViewController is UITabBarController)
{
return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
}
return GetVisibleViewController(controller.PresentedViewController);
}
We had a similar issue and here is what we came up with:
var topViewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
var controllerToPresentWith = topViewController.VisibleViewController();
controllerToPresentWith.PresentModalViewController(_imagePicker, true);
and then
...
public static UIViewController VisibleViewController(this UIViewController controller)
{
if (controller == null)
return null;
if (controller is UINavigationController navController)
{
return navController.VisibleViewController();
}
else if (controller is UITabBarController tabController)
{
tabController.SelectedViewController?.VisibleViewController();
}
else
{
var vc = controller.PresentedViewController?.VisibleViewController();
if (vc != null)
return vc;
}
return controller;
}
In the end, I implemented this by using James Montemagno's Media Plugin library (available over NuGet: https://www.nuget.org/packages/Xam.Plugin.Media) and Permissions Plugin (https://www.nuget.org/packages/Plugin.Permissions).
I wrote the following code for this:
private async Task ChoosePhoto()
{
var permission = await CheckCameraRollPermission();
if (permission == PermissionStatus.Granted)
{
await CrossMedia.Current.Initialize();
// Show image picker dialog
var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions()
{
ModalPresentationStyle = Plugin.Media.Abstractions.MediaPickerModalPresentationStyle.OverFullScreen
});
if (file != null)
{
// Image has been selected
using (var stream = file.GetStream())
{
using (var memoryStream = new System.IO.MemoryStream())
{
stream.CopyTo(memoryStream);
var fileBytes = memoryStream.ToArray();
// DO WHATEVER YOU WANT TO DO WITH THE SELECTED IMAGE AT THIS POINT
}
}
}
}
}
private async Task<PermissionStatus> CheckCameraRollPermission()
{
// Check permission for image library access
var permission = await PermissionsImplementation.Current.CheckPermissionStatusAsync(Permission.Photos);
if (permission != PermissionStatus.Granted)
{
// Permission has not been granted -> if permission has been requested before and the user did not grant it, show message and return the permission
var message = "";
switch (permission)
{
case PermissionStatus.Denied:
case PermissionStatus.Restricted:
message = "Unfortunately, you did not grant permission to access the camera roll. If you want to change this, you can do so in the system settings of your device.";
break;
default:
break;
}
if (!string.IsNullOrEmpty(message))
{
// Message available -> Display alert and return the permission
var alert = UIAlertController.Create("Permission not granted", message, UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
PresentViewController(alert, true, null);
return permission;
}
// In all other cases, request the permission
await PermissionsImplementation.Current.RequestPermissionsAsync(Permission.Photos);
// Check for permission one more time and return it
permission = await PermissionsImplementation.Current.CheckPermissionStatusAsync(Permission.Photos);
}
return permission;
}

await on long service call behaves differently in Microsoft Bot Framework

I have two dialogs called from root dialog based on the prompt response.
Both dialogs internally prepare request and call a service class. Weird thing is one dialog resumes with response from service but the other though receives response from service is not resuming.
Below method works fine and resumes the call at if (searchResult != null && searchResult.Item1 != null)
public virtual async Task MessageRecievedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Text == "quit")
{
context.Done<object>(null);
}
else
{
try
{
var srm = new CoveoRestSearchService.CoveoSearchRequestModel
{
Query = message.Text,
EnableDidYouMean = true,
QuerySource = CoveoRestSearchService.Constants.SWEATERSSOURCE
};
var searchResult = await csp.PerformSearch(srm);
if (searchResult != null && searchResult.Item1 != null)
{
await CardUtil.showHeroCard(message, searchResult.Item1);
}
else
{
await context.PostAsync($"No search results for {message.Text} found");
}
await PostSearchUsageAnalyticsToCoveo(context, srm, searchResult.Item2);
}
catch (Exception e)
{
Debug.WriteLine($"Error when searching : {e.Message}");
}
finally {
context.Wait(MessageRecievedAsync);
}
}
}
This below one though looks identical is not resuming the if (response != null)
public virtual async Task MessageRecievedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Text == "quit")
{
context.Done<object>(null);
}
else
{
try
{
var currentDate = DateTime.UtcNow;
string toDate = currentDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
string fromDate = currentDate.AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
MetricsQuery = MetricsQuery.Replace("{fromISODate}", fromDate);
MetricsQuery = MetricsQuery.Replace("{toISODate}", toDate);
MetricsQuery = MetricsQuery.Replace("{term}", message.Text);
var response = await cuawc.MetricSearchUsageToCoveoAsync(MetricsQuery
.Replace(" ", "%20")
.Replace("!=", "!%3D")
.Replace("==", "%3D%3D")
.Replace(":", "%3A"));
if (response != null)
{
var message_from_bot = context.MakeMessage();
}
//message_from_bot.Attachments = new List<Attachments>();
await context.PostAsync("Please enter the search term for metrics");
}
catch (Exception e)
{
Debug.WriteLine($"Error when pulling metrics : {e.Message}");
}
finally
{
context.Wait(MessageRecievedAsync);
}
}
}
Struggling from past 2 days to figure what is wrong!!

.ConfigureAwait(false) solves the observation on sonarqube?

I have this piece of code in a WebApi controller:
var task = await Request.Content.ParseMultipartAsync()
.ContinueWith<IHttpActionResult>(result =>
{
var data = result.Result;
var validateImage = new ImageValidator();
if (!validateImage.Validate(data.Files["image"]))
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
try
{
var newCategory = this.categoryService.Add(new Model.BusinessObjects.Category
{
Name = data.Fields["Name"].Value,
Description = data.Fields["description"].Value,
Logo = data.Files["image"].File
});
return Ok(newCategory.Id);
}
catch (System.Exception e)
{
return Content(HttpStatusCode.InternalServerError, e);
}
}).ConfigureAwait(false);
return task;
The sonar lint tell me to do that to avoid the warning but I don't know what does it mean, is it correct? before my code only has this line:
var data = await Request.Content.ParseMultipartAsync();
Does the first part of code solve the problem observed by sonar lint?

Categories

Resources