I have that lambda:
var Ids = profileExample.CostCenters
.Where(CostCentre => CostCentre != null)
.Select(CostCentre => CostCentre.Id);
Then i convert to that expression tree
static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profileExample)
{
//Begin var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
var property = profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name != "Id").First();
var collection = ((IEnumerable)property.GetValue(profileExample, null)).AsQueryable();
var collectionType = property.PropertyType.GetGenericArguments()[0];
var collectionTypeName = collectionType.Name;
var keyType = typeof(Int64);
var keyName = "Id";
//BeginWhere
var parameter = Expression.Parameter(collectionType, collectionTypeName);
var profileExampleWhere = Expression.Lambda(
Expression.NotEqual(parameter, Expression.Constant(null)),
parameter);
var profileExampleWhereCall = Expression.Call(typeof(Enumerable),
"Where",
new Type[] { collectionType },
collection.Expression,
profileExampleWhere);
//EndWhere
//BeginSelect
var profileExampleSelect = Expression.Lambda(Expression.PropertyOrField(parameter, keyName),
parameter);
var profileExampleSelectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { collectionType, keyType },
profileExampleWhereCall,
profileExampleSelect);
var Ids = Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
//EndSelect
//End var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
return ((IEnumerable)Ids).Cast<Int64>();
}
Now i want to do the same with bellow lambda
var result = Set.AsQueryable()
.Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id)
.Any(Id => Ids.Contains(Id))).ToList();
But i stuck in .Any(Id => Ids.Contains(Id))....
var id = Expression.Parameter(typeof(long), "Id");
var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
var profile = Expression.Parameter(typeof(Profile), "Profile");
var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
var selectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { typeof(CostCentre), typeof(long) },
Expression.PropertyOrField(profile, "CostCenters"),
selectLambda);
How can i call Any from selectCall and call Ids.Contains...
Full code to run as console application bellow:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ExpressionTrees
{
class Program
{
static void Main(string[] args)
{
var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
Ids = AboveLambdaConvertedToExpressionTree(profileExample);
var result = Set.AsQueryable().Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id))).ToList();
//Expression<Func<Profile, bool>> lambda = (Profile) => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id));
var id = Expression.Parameter(typeof(long), "Id");
var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
var profile = Expression.Parameter(typeof(Profile), "Profile");
var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
var selectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { typeof(CostCentre), typeof(long) },
Expression.PropertyOrField(profile, "CostCenters"),
selectLambda);
}
static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profileExample)
{
// I show that as example of what i need to do
var keyType = typeof(Int64);
var keyName = "Id";
//Begin var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
var property = profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name != keyName).First();
var collection = ((IEnumerable)property.GetValue(profileExample, null)).AsQueryable();
var collectionType = property.PropertyType.GetGenericArguments()[0];
var collectionTypeName = collectionType.Name;
//BeginWhere
var parameter = Expression.Parameter(collectionType, collectionTypeName);
var profileExampleWhere = Expression.Lambda(
Expression.NotEqual(parameter, Expression.Constant(null)),
parameter);
var profileExampleWhereCall = Expression.Call(typeof(Enumerable),
"Where",
new Type[] { collectionType },
collection.Expression,
profileExampleWhere);
//EndWhere
//BeginSelect
var profileExampleSelect = Expression.Lambda(Expression.PropertyOrField(parameter, keyName),
parameter);
var profileExampleSelectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { collectionType, keyType },
profileExampleWhereCall,
profileExampleSelect);
var Ids = Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
//EndSelect
//End var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
return ((IEnumerable)Ids).Cast<Int64>();
}
public partial class Profile
{
public virtual Int64 Id { get; set; }
public virtual ICollection<CostCentre> CostCenters { get; set; }
}
public partial class CostCentre
{
public virtual Int64 Id { get; set; }
}
public static Profile profileExample
{
get
{
return new Profile()
{
Id = 1,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 2 } }
};
}
}
public static IList<Profile> Set
{
get
{
return new List<Profile>() { new Profile() { Id = 1,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 1 },
new CostCentre() { Id = 2 } }
},
new Profile() { Id = 2,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 2 },
new CostCentre() { Id = 3 } }
},
new Profile() { Id = 3,
CostCenters = new List<CostCentre>() { new CostCentre() { Id = 3 } }
} };
}
}
}
}
Since Any is a Generic Method you need to create it for a specific type. The method below gets the Any<T> method from the Enumerable type.
public static MethodInfo GetAnyExtensionMethod(Type forType)
{
MethodInfo method =
typeof(Enumerable).GetMethods()
.First(m => m.Name.Equals("Any") &&
m.GetParameters().Count() == 2);
return method.MakeGenericMethod(new[] { forType });
}
Its solved with help of Mads from MS
class Program
{
static void Main(string[] args)
{
//var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
var Ids = AboveLambdaConvertedToExpressionTree(profileExample);
//var result = Set.AsQueryable().Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id))).ToList();
var id = Expression.Parameter(typeof(long), "Id");
var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
var profile = Expression.Parameter(typeof(Profile), "Profile");
var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
var selectCall = Expression.Call(typeof(Enumerable),
"Select",
new Type[] { typeof(CostCentre), typeof(long) },
Expression.PropertyOrField(profile, "CostCenters"),
selectLambda);
//var id2 = Expression.Parameter(typeof(long), "Id");
var containsCall = Expression.Call(typeof(Enumerable),
"Contains",
new Type[] { typeof(long) },
Expression.Constant(Ids),
id);
var anyLambda = Expression.Lambda(containsCall, id);
var anyCall = Expression.Call(typeof(Enumerable),
"Any",
new Type[] { typeof(long) },
selectCall,
anyLambda);
var whereLambda = Expression.Lambda(anyCall, profile);
var callExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { typeof(Profile) },
Set.AsQueryable().Expression,
whereLambda);
var result = Expression.Lambda(callExpression).Compile().DynamicInvoke();
}
Related
I have tried for the last 4 days to find an illusive image in that app, I am new to xamarin forms and a client asked me to replace an image which I did, but I have left with another image that I should implement and I can't find its source, the XML code for the specific section looks like this.
<ScrollView Grid.Row="2"
HeightRequest="50"
HorizontalOptions="CenterAndExpand"
Orientation="Horizontal"
IsVisible="{Binding PhotosVisible.Value}"
x:Name="ScrollPhotos">
<StackLayout Orientation="Horizontal"
Spacing="0"
VerticalOptions="Center"
Padding="5,0"
x:Name="StackPhotos">
</StackLayout>
</ScrollView>
and the place I'm trying to implement the photo in is:
should be an image instead of the blank grey rectengle
(should be an image instead of the blank grey rectangle)
I cant find the source to the other image, and I even deleted something that was pretty similar in the drawAble folder but it changed nothing.
any help or suggestion will be helpful, Thanks. :)
edit:
The xml.cs source code:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DashboardPage : ExtPage
{
public DashboardPage()
{
InitializeComponent();
Padding = new Thickness(0, 0, 0, MashamAppForms.Helpers.Settings.NativeSetting.BottonPadding);
NavigationPage.SetHasBackButton(this, false);
}
protected override void OnAppearing() {
MessagingCenter.Subscribe<Application>(App.Current, "DashboardFillDates", FillDates);
MessagingCenter.Subscribe<Application, CPhoto[]>(App.Current, "DashboardFillPhotos", FillPhotos);
base.OnAppearing();
}
protected override void OnDisappearing() {
MessagingCenter.Unsubscribe<Application>(App.Current, "DashboardFillDates");
base.OnDisappearing();
}
void FillPhotos(Application arg1, CPhoto[] arg2) {
var bc = (DashboardViewModel)BindingContext;
StackPhotos.Children.Clear();
if (arg2 == null)
return;
foreach (var photo in arg2) {
var image = new CachedImage {
Aspect = Aspect.AspectFill,
Source = photo.Path,
BackgroundColor = Color.FromHex("#504F77AB"),
DownsampleHeight = 100,
HeightRequest = 40,
WidthRequest = 60,
Margin = new Thickness(5, 0)
};
Commands.SetTap(image, bc.ViewImageCommand);
Commands.SetTapParameter(image, photo);
StackPhotos.Children.Add(image);
}
Device.BeginInvokeOnMainThread(() => {
try {
ScrollPhotos.ScrollToAsync(StackPhotos.Children.LastOrDefault(), ScrollToPosition.End, false);
}
catch {
}
});
}
void FillDates(Application application) {
var bc = (DashboardViewModel)BindingContext;
var dates = bc.Dates;
StackDates.Children.Clear();
if (dates == null)
return;
for (var i = 0; i < dates.Length; i++) {
var t = dates[i];
var grid = new Grid {
RowDefinitions =
{
new RowDefinition {Height = GridLength.Star},
new RowDefinition {Height = GridLength.Star},
new RowDefinition {Height = GridLength.Star}
},
Padding = new Thickness(5, 0),
RowSpacing = 0,
BindingContext = t
};
grid.SetBinding(Grid.BackgroundColorProperty, "BackgroundColor.Value");
var l1 = new Label {
Text = t.HebrewDay,
TextColor = t.TextColor,
HorizontalOptions = LayoutOptions.Center,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label))
};
l1.SetBinding(Label.TextColorProperty, "TextColor.Value");
grid.Children.Add(l1, 0, 0);
var l2 = new Label {
Text = t.HebrewDate,
TextColor = t.TextColor,
HorizontalOptions = LayoutOptions.Center,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label))
};
l2.SetBinding(Label.TextColorProperty, "TextColor.Value");
grid.Children.Add(l2, 0, 1);
var l3 = new Label {
Text = t.Date.ToString("dd/MM/yyyy"),
TextColor = t.TextColor,
HorizontalOptions = LayoutOptions.Center,
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label))
};
l3.SetBinding(Label.TextColorProperty, "TextColor.Value");
grid.Children.Add(l3, 0, 2);
var gest = new TapGestureRecognizer {
Command = bc.ChangeDateCommand,
CommandParameter = t
};
grid.GestureRecognizers.Add(gest);
StackDates.Children.Add(grid);
if (i != dates.Length - 1)
StackDates.Children.Add(new BoxView {
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Fill,
WidthRequest = 1,
Color = (Color)Application.Current.Resources["SelectionColor"]
});
}
Device.BeginInvokeOnMainThread(() =>
{
try {
ScrollDates.ScrollToAsync(StackDates.Children.LastOrDefault(), ScrollToPosition.End, false);
}
catch {
}
});
}
}
and the viewModel.cs is:
public class DashboardViewModel : FormsBaseViewModel
{
static bool _nowAsking;
static bool _scanning;
public ICommand ChangeDateCommand { get; }
public ICommand LogoutCommand { get; }
public ICommand ListHeaderCommand { get; }
public ICommand EventCommand { get; }
public ICommand QrCommand { get; }
public ICommand ViewImageCommand { get; }
public ICommand PhotoCommand { get; }
public ICommand FeedbackCommand { get; }
public ICommand LocationCommand { get; }
public ICommand ContactsCommand { get; }
public ICommand MessagesCommand { get; }
public ICommand FileCommand { get; }
public ObservableProperty<int> CarouselPosition { get; }
public ObservableProperty<BasePageState> EventsState { get; } = new ObservableProperty<BasePageState>();
public ObservableProperty<bool> IsBusy { get; } = new ObservableProperty<bool>();
public ObservableProperty<bool> PhotosVisible { get; } = new ObservableProperty<bool>();
public SmartCollection<EventDetails> EventList { get; set; }
public Conferance Conferance { get; set; }
public bool SubtitleVisible => !string.IsNullOrEmpty(Conferance?.SubTitle);
public string Phone { get; set; }
public string Name { get; set; }
public string RealId { get; set; }
public EventDetails[] Events { get; set; }
public QrDetails[] QrDetails { get; set; }
public CPhoto[] CPhotos { get; set; }
public string FileLink { get; set; }
public string Greeting { get; set; }
public string ApiKey { get; set; }
public CParticipant[] Participants { get; set; }
public ThreeDatesItem[] Dates { get; set; }
private ThreeDatesItem _selected;
public ThreeDatesItem SelectedDate
{
get => _selected;
set
{
_selected = value;
EventList.Clear();
Task.Run(async () =>
{
await Task.Delay(100);
EventList.AddRange(GetEvents(value.Date));
});
}
}
public DashboardViewModel()
{
CarouselPosition = new ObservableProperty<int>();
EventList = new SmartCollection<EventDetails>();
ChangeDateCommand = new Command<ThreeDatesItem>(item =>
{
foreach (var tdi in Dates)
{
tdi.IsSelected = false;
}
item.IsSelected = true;
SelectedDate = item;
});
LogoutCommand = new Command(async () =>
{
Settings.Authed = false;
Settings.SavedPhone = "";
Settings.SavedId = "";
OneSignal.Current.DeleteTag("confId");
await NavigationService.Navigate<LoginViewModel>();
NavigationService.ClearNavigationStack();
});
ListHeaderCommand = new Command<EventDetails>(details =>
{
var mainColor = (Color)Application.Current.Resources["SelectionColor"];
if (details.IsOpened)
{
var del = EventList.Where(e => e.WhatMashov == details.IsMashov).ToArray();
for (var i = 0; i < del.Length; i++)
{
EventList.Remove(del[i]);
}
details.SeparatorColor.Value = mainColor;
}
else
{
var add = Events?.Where(e => e.Day == details.Day && e.WhatMashov == details.IsMashov).ToArray();
details.SeparatorColor.Value = add.Length == 0? mainColor : Color.LightGray;
var after = details;
for (var i = 0; i < add.Length; i++)
{
add[i].SeparatorColor.Value = i == add.Length - 1 ? mainColor : Color.LightGray;
add[i].GridPadding = new Thickness(10, 10, 20, 10);
EventList.Insert(EventList.IndexOf(after) + 1, add[i]);
after = add[i];
}
}
EventList.Last().SeparatorColor.Value = Color.Transparent;
details.IsOpened = !details.IsOpened;
});
EventCommand = new Command<EventDetails>(async details =>
{
await NavigationService.Navigate<EventInfoViewModel>(model =>
{
model.Participants.AddRange(Participants?.Where(e => e.EventId == details.EventId));
model.Date.Value = SelectedDate;
model.EventDetails.Value = details;
model.Phone = Phone;
model.IsVisibleDescription.Value = !string.IsNullOrEmpty(details.Description);
model.IsVisibleLecturers.Value = model.Participants.Count > 0;
model.Conferance = Conferance;
model.AllEvents = Events;
model.Name = Name;
model.SelectedEventDetails = details;
model.QrDetails = QrDetails;
});
});
QrCommand = new Command<EventDetails>(details =>
{
if (details.QrState == QrState.Normal)
NavigationService.Navigate<QrPickerViewModel>(NavigationType.Popup, m => {
m.EventDetails = Events;
m.EventId = details.EventId;
m.QrDetails = QrDetails;
m.Phone = Phone;
m.Name = Name;
m.ConfId = Conferance.Id;
});
});
ViewImageCommand = new Command<CPhoto>(p =>
{
var s = p?.Path?.Trim();
var photos = CPhotos.Select(e => new MyPhoto {
URL = e?.Path?.Trim(),
Title = string.Empty,
Link = e?.SponsorLink?.Trim()
}).ToList();
if (Device.RuntimePlatform == Device.iOS)
photos.Reverse();
var pos = photos?.FindIndex(e => e.URL == s) ?? 0;
var config = new PhotoConfig {
Photos = photos,
StartIndex = pos,
ActionButtonPressed = async (index) => {
var action = await AlertCenter.ActionSheet(Device.RuntimePlatform == Device.Android ? Localization.SelectAction : null, Localization.Cancel, null, Localization.SponsorLink);
if (action == Localization.SponsorLink) {
if (string.IsNullOrEmpty(photos[index]?.Link)) {
AlertCenter.Error(Localization.NoLink);
}
else {
Device.OpenUri(new Uri(photos[index].Link, UriKind.Absolute));
}
}
}
};
config.Show();
});
PhotoCommand = new Command(async () =>
{
await LoadingPopupService.Show();
var photos = await SimpleServerRequest.Request<CPhoto[]>(new Uri("http://app.masham.org.il/insertToConfearnce2.php?Action=getAllEvents&TableName=I_" + Conferance.Id));
await LoadingPopupService.Close();
if (photos.Item1)
await NavigationService.Navigate<PhotoGalleryViewModel>(m =>
{
m.Photos.Value = photos.Item2.Where(e => e.Type == "גלריה").ToArray();
m.ConfId = Conferance.Id;
m.ApiKey = ApiKey;
});
else
AlertCenter.Error(Localization.ErrorLoading);
});
FeedbackCommand = new Command(async () =>
{
if (string.IsNullOrEmpty(Conferance?.SurvayLink))
{
AlertCenter.Error(Localization.NoLink);
return;
}
await LoadingPopupService.Show();
var res = await SimpleServerRequest.Request(new Uri($#"http://app.masham.org.il/insertToConfearnce2.php?Action=getServerDateAndtime&CID={Conferance.Id}"));
await LoadingPopupService.Close();
try
{
if (res.Success)
{
if (res.Result.ToLower() == "true")
Device.OpenUri(new Uri(Conferance?.SurvayLink, UriKind.Absolute));
else
AlertCenter.Error(Localization.NoMashovTime);
}
else
AlertCenter.Error(Localization.ErrorLoading);
}
catch
{
AlertCenter.Error(Localization.IncorrectLink);
}
});
LocationCommand = new Command(() =>
{
Device.OpenUri(new Uri("https://waze.com/ul?q=" + Conferance?.NameOfLocation));
});
ContactsCommand = new Command(async () =>
{
await NavigationService.Navigate<ContactsViewModel>(m =>
{
m.Phone.Value = Conferance?.Phone;
m.Location.Value = Conferance?.NameOfLocation;
m.Email.Value = Conferance?.Email;
});
});
MessagesCommand = new Command(async () =>
{
await LoadingPopupService.Show();
var messages = await SimpleServerRequest.Request<CMessage[]>(new Uri(
"http://app.masham.org.il/insertToConfearnce2.php?Action=getAllEvents&TableName=" +
"Messages_" + Conferance.Id));
await LoadingPopupService.Close();
if (messages.Item1)
{
DependencyService.Get<ILocalSettings>().PushCounter = 0;
await NavigationService.Navigate<MessagesViewModel>(m =>
{
m.Messages.AddRange(messages.Item2 ?? new CMessage[0]);
m.ConfId = Conferance.Id.ToString();
});
}
else
AlertCenter.Error(Localization.ErrorLoading);
});
FileCommand = new Command(() => {
if (string.IsNullOrEmpty(FileLink)) {
AlertCenter.Error(Localization.NoLink);
return;
}
Device.OpenUri(new Uri(FileLink, UriKind.Absolute));
});
}
public async void Resumed() {
{
if (_nowAsking)
return;
_nowAsking = true;
if (NavigationService.CurrentModalPage == null && NavigationService.CurrentPage.GetType() == typeof(DashboardPage) && !LoadingPopupService.IsLoading) {
IsBusy.Value = true;
await LoadingPopupService.Show();
var users = await SimpleServerRequest.Request<UserAndConferance[]>(new Uri($"http://app.masham.org.il/apimasham.php?Action=getUser&idUsername={Phone}&realId={RealId}"));
if (users.Item1) {
var user = users.Item2.FirstOrDefault();
ApiKey = user?.ApiKey;
var conf = users.Item2.Select(e => e.Conferance).FirstOrDefault(e => e != null && e.Id == Conferance.Id);
if (conf == null) {
_nowAsking = false;
IsBusy.Value = false;
Settings.Authed = false;
Settings.SavedPhone = "";
Settings.SavedId = "";
await LoadingPopupService.Close();
await AlertCenter.ErrorAsync(Localization.ConfNotFound);
await NavigationService.Navigate<LoginViewModel>();
NavigationService.ClearNavigationStack();
return;
}
var eventContainer = await SimpleServerRequest.Request<EventContainer>(new Uri($"http://app.masham.org.il/apimasham.php?Action=getEvents&confId={Conferance.Id}&phone={Phone}"));
if (eventContainer.Item1 && eventContainer.Item2 != null) {
var dates = eventContainer.Item2.EventDetails
?.Select(e => new {
e.Day,
e.HebrewDay
})
.Distinct()
.Select(e => new ThreeDatesItem {
Date = e.Day,
HebrewDate = e.HebrewDay
})
.OrderByDescending(e => e.Date)
.ToArray();
Events = eventContainer.Item2.EventDetails ?? new EventDetails[0];
QrDetails = eventContainer.Item2.QrDetails ?? new QrDetails[0];
QrStateHelper.SetQrStatesForAll(Events, QrDetails, eventContainer.Item2.QrAnswers);
if (conf.Type == "קורס" && dates != null) {
var p = 1;
for (var i = dates.Length - 1; i >= 0; i--) {
dates[i].HebrewDate = "מפגש " + p++;
}
}
var isEqualDates = Dates != null && Dates.Length == dates?.Length && conf.Type == Conferance.Type;
if (isEqualDates)
for (var i = 0; i < dates.Length; i++) {
isEqualDates = dates[i].Date == Dates[i].Date;
if (!isEqualDates)
break;
}
if (!isEqualDates)
Dates = dates;
var photos = eventContainer.Item2.Photos?.Where(e => e.Type == "קרוסלה").ToArray();
var isEqualPhotos = CPhotos != null && CPhotos.Length == photos?.Length;
if (isEqualPhotos)
for (var i = 0; i < photos.Length; i++) {
isEqualPhotos = photos[i].Path == CPhotos[i].Path;
if (!isEqualPhotos)
break;
}
else
CPhotos = photos;
Conferance = conf;
FileLink = eventContainer.Item2.Photos?.FirstOrDefault(e => e.Type == "קובץ")?.Path;
OnPropertyChanged(nameof(Conferance));
PrepareDatesAndPhotos(!isEqualDates, !isEqualPhotos);
if (Events.Length > 0) {
EventsState.Value = BasePageState.Normal;
}
else {
EventList.Clear();
EventsState.Value = BasePageState.NoData;
}
_nowAsking = false;
IsBusy.Value = false;
await LoadingPopupService.Close();
return;
}
}
IsBusy.Value = false;
await LoadingPopupService.Close();
await AlertCenter.ErrorAsync(Localization.ErrorLoading);
}
_nowAsking = false;
}
}
public override async void FirstAppearing()
{
base.FirstAppearing();
NavigationService.ClearNavigationStack();
await Task.Delay(300);
Device.BeginInvokeOnMainThread(() => {
PrepareDatesAndPhotos();
});
}
void PrepareDatesAndPhotos(bool updDates = true, bool updPhotos = true) {
if (updPhotos)
MessagingCenter.Send(App.Current, "DashboardFillPhotos", CPhotos);
PhotosVisible.Value = CPhotos?.Any() ?? false;
if (Dates?.Any() ?? false) {
if (updDates) {
var today = Dates.FirstOrDefault(e => e.Date == DateTime.Today);
if (today != null) {
today.IsSelected = true;
SelectedDate = today;
}
else {
var date = Dates[Dates.Length - 1];
date.IsSelected = true;
SelectedDate = date;
}
MessagingCenter.Send(App.Current, "DashboardFillDates");
}
else {
SelectedDate = SelectedDate;
}
}
}
private EventDetails[] GetEvents(DateTime date)
{
var items = Events?.Where(e => e.Day == date && e.WhatMashov == "").OrderBy(e => e.StartTime).ToArray();
var mainColor = (Color)Application.Current.Resources["SelectionColor"];
if (items?.Length > 0)
{
for (var i = 0; i < items.Length; i++)
{
items[i].IsOpened = false;
if (string.IsNullOrEmpty(items[i].IsMashov) && string.IsNullOrEmpty(items[i].WhatMashov))
{
items[i].SeparatorColor.Value = mainColor;
items[i].GridPadding = new Thickness(10, 10, 10, 10);
}
else
{
items[i].GridPadding = new Thickness(10, 10, 20, 10);
if (i != items.Length - 1)
{
if (!string.IsNullOrEmpty(items[i + 1].IsMashov) ||
!string.IsNullOrEmpty(items[i + 1].WhatMashov))
{
items[i].SeparatorColor.Value = Color.LightGray;
}
else
{
items[i].SeparatorColor.Value = mainColor;
}
}
}
}
items.Last().SeparatorColor.Value = Color.Transparent;
}
return items;
}
}
I have wired up my Okta-OIDC-SSO and verified I'm able to log in properly. I have set up my claims and also was able to get a thumbnail of the user through Active Directory. Now, I wanted to have access to my actual business user model on my website whenever needed. I tried to smuggle it as a claim but claims are the only types of string and not complex objects. So I created my own Identity:
Custom ClaimsIdentity:
public class SystemUserIdentity : ClaimsIdentity
{
private SystemUserModel CurrentUser { get; set; }
public SystemUserIdentity(SystemUserModel systemUser, params Claim[] claims) : base(claims) => CurrentUser = systemUser;
public SystemUserIdentity(SystemUserModel systemUser, IEnumerable<Claim> claims) : this(systemUser,claims.ToArray()) { }
}
Auth setup in ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
...
RegisterAuth(services);
}
private void RegisterAuth(IServiceCollection services)
{
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option =>
{
option.AccessDeniedPath = "/AccessDenied";
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.ResponseType = OpenIdConnectResponseType.Code;
options.ClientId = Configuration["SSO:ClientId"];
options.ClientSecret = Configuration["SSO:ClientSecret"];
options.Authority = Configuration["SSO:Issuer"];
options.GetClaimsFromUserInfoEndpoint = true;
options.CallbackPath = "/authorization-code/callback";
options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true };
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = async ctx =>
{
var service = ctx.HttpContext.RequestServices.GetRequiredService<IUserService>();
var ssoId = ctx.Principal!.FindFirstValue("preferred_username");
var staff = await service.GetUserByIdAsync(ssoId ?? string.Empty);
if (staff != null)
{
staff.Thumbnail = GetUserThumbFromActiveDirectory(WebHost.IsDevelopment() ? "DAPreview.ae": "dca.com", "UserPrincipalName", ssoId, "thumbnailPhoto");
var claims = new List<Claim>
{
new(nameof(staff.Id), staff.Id),
new(nameof(staff.Username), staff.Username),
new(ClaimTypes.Name, "DACRLClaim"),
new(ClaimTypes.Email, staff.Email),
new(ClaimTypes.GivenName, staff.EmployeeName)
};
claims.AddRange(staff.Roles.Select(role => new Claim(ClaimTypes.Role, $"{role.Id}-{role.Name}")));
var appIdentity = new SystemUserIdentity(staff, claims);
ctx.Principal?.AddIdentity(appIdentity);
}
}
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("SuperAdminPolicy", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "Role" && c.Value.Contains("Super Admin"))));
});
}
Usage in the target MVC view:
#inject IHttpContextAccessor HttpContextAccess
#{
var currentUser = HttpContextAccess.HttpContext?.User;
var temp = currentUser?.Identities.SingleOrDefault(w => w.Name == "DACRLClaim");
var reqModel = (SystemUserIdentity)temp;
}
So, basically, I need the custom ClaimsIdentity (SystemUserIdentity) that I added in Startup as it has my actual user object and everything.
I have two tables with similar data for body insurance and third party car insurance ... I have used enum in the model to separate the insurances and I want to do the creation operation for it .... There are two modes for each insurance. One case when that car does not have insurance yet and the second case when we want to extend it.
I wrote this code to create the form, but it encounters the following error
I also get an error on the name of the Create function.error = not all code paths return a value.
Please advise
public async Task<IActionResult> Create(int id, int type)
{
InsuranceViewModel model;
ViewBag.Type = type;
var companies = await _context.InsuranceCompany
.Where(e => e.IsActice)
.ToListAsync();
ViewData["CompanyList"] = new SelectList(companies, "Id", "CompanyName");
if ((InsuranceType)type == InsuranceType.Body)
{
var bodyInsurance = await _context.BodyInsurance
.Include(e => e.InsuranceCompany)
.FirstOrDefaultAsync(e => e.Id == id);
if (bodyInsurance == null)
{
model = new InsuranceViewModel
{
CompanyId = bodyInsurance.InsuranceCompanyId,
CompanyName = bodyInsurance.InsuranceCompany.CompanyName,
InsuranceType = InsuranceType.Body,
IssueDate = new DateTime(bodyInsurance.IssueDate).Ticks,
ExpireDate = new DateTime(bodyInsurance.ExpireDate).Ticks,
VehicleInformationId = id
};
}
else
{
var lastBody = await _context.BodyInsurance.Include(e => e.InsuranceCompany)
.Where(e => e.VehicleInformationId == id)
.OrderBy(e => e.ExpireDate)
.LastAsync();
model = new InsuranceViewModel
{
ExpireDate = new DateTime(lastBody.ExpireDate).AddYears(1).AddDays(1).Ticks,
CompanyId = lastBody.InsuranceCompanyId,
CompanyName = lastBody.InsuranceCompany.CompanyName,
InsuranceType = InsuranceType.Body,
IssueDate = new DateTime(lastBody.ExpireDate).AddDays(1).Ticks,
VehicleInformationId = id
};
}
}
else
{
if ((InsuranceType)type == InsuranceType.Thirdpart)
{
var thirdParty = await _context.ThirdPartyInsurance
.Include(e => e.InsuranceCompany)
.FirstOrDefaultAsync(e => e.Id == id);
if (thirdParty == null)
{
model = new InsuranceViewModel
{
CompanyId = thirdParty.InsuranceCompanyId,
CompanyName = thirdParty.InsuranceCompany.CompanyName,
InsuranceType = InsuranceType.Body,
IssueDate = new DateTime(thirdParty.IssueDate).Ticks,
ExpireDate = new DateTime(thirdParty.ExpireDate).Ticks,
VehicleInformationId = id
};
}
else
{
var lastThirdParty = await _context.ThirdPartyInsurance.Include(e => e.InsuranceCompany)
.Where(e => e.VehicleInformationId == id)
.OrderBy(e => e.ExpireDate)
.LastAsync();
model = new InsuranceViewModel
{
ExpireDate = new DateTime(lastThirdParty.ExpireDate).AddYears(1).AddDays(1).Ticks,
CompanyId = lastThirdParty.InsuranceCompanyId,
CompanyName = lastThirdParty.InsuranceCompany.CompanyName,
InsuranceType = InsuranceType.Body,
IssueDate = new DateTime(lastThirdParty.ExpireDate).AddDays(1).Ticks,
VehicleInformationId = id
};
}
}
return View(model);
}
I have to display a treeview .But it will take much time, that's why I want to load this treeview on demand.At the first I want just display first level, and repeating that level by level.
This is the view
$("#onflycheckboxes").jstree({
json_data: {
"ajax": {
"url": function (node) {
var nodeId = "";
var url = ""
if (node == -1) {
url = "/TreeView/GetCollectionWS/source";
}
else {
nodeId = node.attr('id');
url = "/TreeView/GetCollectionWS/" + nodeId;
}
return url;
},
"type": "POST",
"dataType": "json",
"contentType": "application/json charset=utf-8"
}
},
checkbox: {
real_checkboxes: true,
checked_parent_open: true
},
plugins: ["themes", "json_data", "ui", "checkbox"]
});
this is the controller
public virtual ActionResult GetCollectionWS(string root)
{
int? nodeId = (root == source) ? (int?)null : Convert.ToInt32(root);
Object[] liste = new Object[100];
liste = DSClient.Views.Traitement.getTop(nodeId);
List<TreeViewNode> nodes = new List<TreeViewNode>();
for (int i = 0; (i < liste.Length && liste.ElementAt(i) != null);i++ )
{
bool leaf = false;
nodes.Add(new TreeViewNode()
{
id = Convert.ToString(DSClient.Views.Traitement.GetNodeId(liste.ElementAt(i))),
text = liste.ElementAt(i).Handle,
classes = leaf ? "file" : "folder",
hasChildren = !leaf
});
}
return Json(nodes);
}
when I try a breakpoint on the line return Json(nodes); I remarque that nodes contains
at the first {id=0,text=Collection-10,classes=folder,haChildren=false}
the view display nothing.Please, can any one help me??
public virtual string GetCollectionWS(string id)
{
Object[] liste = new Object[100];
client = new DSServiceClient();
if (id == "source")
{
Collection[] _top = new Collection[100];
client.Open();
_top = client.GetTopCollections();
client.Close();
for (int i = 0; i < _top.Length; i++)
{
DSClient.Controllers.Object obji = new DSClient.Controllers.Object();
obji.Handle = _top[i].Handle;
obji.Name = _top[i].Title;
liste[i] = obji;
}
}
else
{
client = new DSServiceClient();
client.Open();
Tree tree = client.GetTreeView(id);
client.Close();
liste = tree.listObjects;
}
var recursiveObjects = FillRecursive(liste);
string myjsonmodel = new JavaScriptSerializer().Serialize(recursiveObjects);
return myjsonmodel;
}
private static List<RecursiveObject> FillRecursive(Object[] flatObjects)
{
List<RecursiveObject> recursiveObjects = new List<RecursiveObject>();
for (int i = 0; (i < flatObjects.Length && flatObjects.ElementAt(i) != null); i++)
{
recursiveObjects.Add(new RecursiveObject()
{
data = flatObjects.ElementAt(i).Name,
id = flatObjects.ElementAt(i).Handle,
attr = new FlatTreeAttribute { id = flatObjects.ElementAt(i).Handle, selected = false },
children = null,
state = "closed"
});
}
return recursiveObjects;
}
Now I want to send the text and Id of nodes selected to my controller.
<script type="text/javascript">
var divId = [];
var divText = [];
$('#idjstree').value=function GetIDs() {
divId = [];
divText = [];
$("#onflycheckboxes").jstree("get_checked", null, true).each
(function () {
divId.push(this.id);
divText.push($(this).children('a').text());
});
return (divId);
}</script
and this is in the view
#:<div id="onflycheckboxes"></div>
#:<input type="hidden" id="idjstree" name="idjstree" value="" />
but always I get idjstree="" when I do a breakpoint on the post of create.But the function GetIDs() is correct.
What can I do please?
In our application we use MvcContrib for generating links with the exception of cross area links where Contrib seems to be not working properly (or we are doing something wrong). In services we have a function that generates a List< ZakladkaModel > which contains url and other properties used in generating tabstrib via custom html helper. That function takes as an argument an id of database object and UrlHelper to help in link creating.
m_service.GenerowanieZakladkiDlaKontrolera_ARCH_Akt(idAktu, new UrlHelper(this.ControllerContext.RequestContext));
Then in the GenerowanieZakladkiDlaKontrolera_ARCH_Akt we have something like this:
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "Akt", Url = "" });
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "Wzmianki", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.ARCH_WzmiankiController>(c => c.Index(idAktu)) });
if (tekstJednolity.StanTekstuJednolitego == "RB" || tekstJednolity.StanTekstuJednolitego == "SW")
{
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "t.j. aktu", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.ARCH_TekstJednolityController>(c => c.Edytuj(tekstJednolity.Id)) });
}
else
{
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "t.j. aktu", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.ARCH_TekstJednolityController>(c => c.Raport(tekstJednolity.Id)) });
}
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "Przypisek 1", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.Przypisek1Controller>(c => c.Index(idAktu)) });
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "Przypisek 2", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.Przypisek2Controller>(c => c.Index(idAktu)) });
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "Przypisek 3", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.Przypisek3Controller>(c => c.Edytuj(idAktu)) });
model.Add(new ZakladkaModel { Aktywnosc = true, NazwaZakladki = "Przypisek 4", Url = url.Action<Usc.Presentation.Areas.FU_RAU.Controllers.ARCH.Przypisek4Controller>(c => c.Edytuj(idAktu)) });
Now the problem is that on some co-workers computers it generates links to actions properly and on some it looks like it takes a ranedom area from our app and tries to make an invalid link. We could use a simple url.Action("action","controler") which works fine on all but we would prefer MvcContrib :). Does anyone have any idea why this occurs? Or can share an alternative?
It seems that LinkBuilder which is used under doesn't use GetVirtualPatchForArea at all which as I read is MVC bug. So i decided to make my own HtmlHelper which uses that method:
public static string ActionArea<TController>(this HtmlHelper urlHelper, Expression<Action<TController>> expression) where TController : Controller
{
RouteValueDictionary routeValues = GetRouteValuesFromExpression(expression);
VirtualPathData vpd = new UrlHelper(urlHelper.ViewContext.RequestContext).RouteCollection.GetVirtualPathForArea(urlHelper.ViewContext.RequestContext, routeValues);
return (vpd == null) ? null : vpd.VirtualPath;
}
public static string ActionArea<TController>(this UrlHelper urlHelper, Expression<Action<TController>> expression) where TController : Controller
{
RouteValueDictionary routeValues = GetRouteValuesFromExpression(expression);
VirtualPathData vpd = urlHelper.RouteCollection.GetVirtualPathForArea(urlHelper.RequestContext, routeValues);
return (vpd == null) ? null : vpd.VirtualPath;
}
public static RouteValueDictionary GetRouteValuesFromExpression<TController>(Expression<Action<TController>> action) where TController : Controller
{
if (action == null)
{
throw new ArgumentNullException("action");
}
MethodCallExpression call = action.Body as MethodCallExpression;
if (call == null)
{
throw new ArgumentException("Akcja nie może być pusta.", "action");
}
string controllerName = typeof(TController).Name;
if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Docelowa klasa nie jest kontrolerem.(Nie kończy się na 'Controller')", "action");
}
controllerName = controllerName.Substring(0, controllerName.Length - "Controller".Length);
if (controllerName.Length == 0)
{
throw new ArgumentException("Nie można przejść do kontrolera.", "action");
}
// TODO: How do we know that this method is even web callable?
// For now, we just let the call itself throw an exception.
string actionName = GetTargetActionName(call.Method);
var rvd = new RouteValueDictionary();
rvd.Add("Controller", controllerName);
rvd.Add("Action", actionName);
var namespaceNazwa = typeof(TController).Namespace;
if(namespaceNazwa.Contains("Areas."))
{
int index = namespaceNazwa.IndexOf('.',namespaceNazwa.IndexOf("Areas."));
string nazwaArea = namespaceNazwa.Substring(namespaceNazwa.IndexOf("Areas.") + 6, index - namespaceNazwa.IndexOf("Areas.") + 1);
if (!String.IsNullOrEmpty(nazwaArea))
{
rvd.Add("Area", nazwaArea);
}
}
//var typ = typeof(TController).GetCustomAttributes(typeof(ActionLinkAreaAttribute), true /* inherit */).FirstOrDefault();
/*ActionLinkAreaAttribute areaAttr = typ as ActionLinkAreaAttribute;
if (areaAttr != null)
{
string areaName = areaAttr.Area;
rvd.Add("Area", areaName);
}*/
AddParameterValuesFromExpressionToDictionary(rvd, call);
return rvd;
}
private static string GetTargetActionName(MethodInfo methodInfo)
{
string methodName = methodInfo.Name;
// do we know this not to be an action?
if (methodInfo.IsDefined(typeof(NonActionAttribute), true /* inherit */))
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
"Nie można wywoływać metod innych niż akcje.", methodName));
}
// has this been renamed?
ActionNameAttribute nameAttr = methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), true /* inherit */).OfType<ActionNameAttribute>().FirstOrDefault();
if (nameAttr != null)
{
return nameAttr.Name;
}
// targeting an async action?
if (methodInfo.DeclaringType.IsSubclassOf(typeof(AsyncController)))
{
if (methodName.EndsWith("Async", StringComparison.OrdinalIgnoreCase))
{
return methodName.Substring(0, methodName.Length - "Async".Length);
}
if (methodName.EndsWith("Completed", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
"Nie można wywoływać kompletnych metod.", methodName));
}
}
// fallback
return methodName;
}
static void AddParameterValuesFromExpressionToDictionary(RouteValueDictionary rvd, MethodCallExpression call)
{
ParameterInfo[] parameters = call.Method.GetParameters();
if (parameters.Length > 0)
{
for (int i = 0; i < parameters.Length; i++)
{
Expression arg = call.Arguments[i];
object value = null;
ConstantExpression ce = arg as ConstantExpression;
if (ce != null)
{
// If argument is a constant expression, just get the value
value = ce.Value;
}
else
{
value = CachedExpressionCompiler.Evaluate(arg);
}
rvd.Add(parameters[i].Name, value);
}
}
}
Hope this helps people with similiar problems. Some of the code above i got from mvc2-rtm-sources modified to my needs http://aspnet.codeplex.com/releases/view/41742