连接到Web API的{WPF MVVM控件

时间:2017-03-16 06:22:49

标签: c# api web mvvm

我有一个带有SQL数据库/实体框架的ASP.NET Web API,我将用它作为我正在构建的应用程序的服务器端。客户端现在将是WPF。我在确定MVVM控件从服务器访问数据的最佳方法时遇到了一些麻烦。我为MVVM完成的所有教程和课程都直接连接到本地数据库,并在加载控件时更新。我想要的是一个常量循环,其中API每分钟调用一次,控件中的数据在该点自动刷新。我有两个主要控件工作(遇到一个问题从另一个线程更新集合,并不得不使用App.Current.Dispatcher.Invoke),但我不确定我是否保持最佳实践运行API调用直接来自视图模型。此外,我需要能够在视图模型之间共享数据。

ScheduledForwardsViewModel具有ActiveForwardsViewModel所需的数据,ActiveForwardsViewModel具有CreateForwardsViewModel所需的数据。每个条目的ActiveForward需要能够查看每个相应的计划项目的计划日期,以便它可以找到下一个事件并显示在ActiveForwardsView中发生该事件之前的剩余时间。 CreateForwardView只需要访问在ActiveForwards数据操作期间创建的AllUsers,AllGroups,AllContacts可观察集合,以便在计划新的转发时可以在下拉字段中使用该数据。我还没有能够让下拉列表工作。我确实可以使用静态对象访问ScheduledForwardsView所需的信息,但我觉得可能有更好的方法。当我的应用程序的一部分已经拥有我需要的数据时,我宁愿不要为相同的数据多次调用API。

基本布局:

MainWindow
    CreateForwardView (with view model)
        [Drop down boxes to select user and schedule forward]
        [Buttons, etc.]
    [TabControl]
        [TabItem: Active Forwards]
            ActiveForwardsView (with view model)
        [TabItem: Scheduled Forwards]
            ScheduledForwardsView (with view model)
    [EndTabControl]

ActiveForwardsViewModel如下所示。 ScheduledForwardsViewModel本质上是相同的,但它调用一个不同的API方法并包含我在ActiveForwardsViewModel中使用的静态对象(请参阅我继续使用UpdateUserObjects之前等待ScheduledForwardsViewModel完成1次运行的部分)。这似乎不是正确的做法,但我这样设置就是为了让我可以转向其他事情。

public class ActiveForwardsViewModel : INotifyPropertyChanged
{

    private CancellationToken updater = default(CancellationToken);
    private AppLog log;
    private FFObject _selectedObject;
    private ObservableCollection<FFObject> _activeForwards;
    public ObservableCollection<FFObject> ActiveForwards
    {
        get { return _activeForwards; }
        set
        {
            if (_activeForwards != value)
            {
                _activeForwards = value;
                PropertyChanged(this, new PropertyChangedEventArgs("ActiveForwards"));
            }

        }
    }

    public ObservableCollection<FFObject> AllUsers { get; set; }
    public ObservableCollection<FFObject> AllGroups { get; set; }
    public ObservableCollection<FFObject> AllContacts { get; set; }
    public ObservableCollection<FFObject> AllObjects { get; set; }

    public bool Running = false;
    public bool FirstRunComplete = false;


    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public ActiveForwardsViewModel()
    {
        if (DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
        {
            updater.ThrowIfCancellationRequested();
            return;
        }
        ActiveForwards = new ObservableCollection<FFObject>();
        AllUsers = new ObservableCollection<FFObject>();
        AllGroups = new ObservableCollection<FFObject>();
        AllContacts = new ObservableCollection<FFObject>();
        AllObjects = new ObservableCollection<FFObject>();
        StartUpdater(updater);
        RemoveForwardCommand = new RelayCommand(OnRemove, CanRemove);

    }


    public async Task StartUpdater(CancellationToken token = default(CancellationToken))
    {


        while (!token.IsCancellationRequested)
        {
            Running = true;
            await this.Update();
            FirstRunComplete = true;
            try
            {
                await Task.Delay(TimeSpan.FromMinutes(1), token);
            }
            catch (TaskCanceledException)
            {
                Running = false;
                break;
            }

        }
    }

    private List<FFObject> UpdateAllObjectList(string strJson)
    {
        var serializer = new JavaScriptSerializer();
        return serializer.Deserialize<List<FFObject>>(strJson);
        //return AllObjects;
    }

    public string GetString(string method)
    {
        using (var client = new WebClient())
        {
            var url = string.Format("https://mywebapi.domain.com/api/{0}", method);
            return client.DownloadString(url);
        }
    }

    public async Task Update()
    {

        Func<string, List<FFObject>> getUsersJson = UpdateAllObjectList;
        await Task<string>.Factory.StartNew(() => GetString("Users"))
                        .ContinueWith(antecendent => getUsersJson(antecendent.Result))
                        .ContinueWith(antecendent => UpdateUserObjects(antecendent.Result));

    }

    private void CheckRemoved(List<FFObject> all)
    {
        List<FFObject> RemoveObjects = new List<FFObject>();

        foreach (var obj in ActiveForwards)
        {
            var newObj = all.FirstOrDefault(i => i.ID == obj.ID);
            if (newObj == null)
            {
                RemoveObjects.Add(obj);
            }
            else
            {
                if (!(bool) newObj.IsForwarded)
                {
                    RemoveObjects.Add(obj); 
                }
            }
        }

        foreach (var obj in RemoveObjects)
        {
            App.Current.Dispatcher.Invoke((Action)delegate
            {
                ActiveForwards.Remove(obj);
            });
        }


    }

    private void UpdateUserObjects(List<FFObject> all)
    {
        Debug.WriteLine("Starting UpdateUserObject");
        if (all != null)
        {
            AllObjects = new ObservableCollection<FFObject>(all);
            CheckRemoved(all);

            var x = 0;
            while (!ScheduledForwardsViewModel.RunOnce && x < 5)
            {
                System.Threading.Thread.Sleep(1000);
                x++;
            }


            foreach (var obj in all)
            {
                if (obj.ObjectType.ToLower() == "user")
                {

                    var existing = AllUsers.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);

                    if (existing != null)
                    {
                        existing.ForwardedTo = obj.ForwardedTo;
                        existing.ForwardedToAd = obj.ForwardedToAd;
                        existing.ForwardedToDn = obj.ForwardedToDn;
                        existing.ForwardedToPk = obj.ForwardedToPk;
                        existing.ForwardedToDisplay = obj.ForwardedToDisplay;
                        existing.IsForwarded = obj.IsForwarded;
                        existing.DeliverAndRedirect = obj.DeliverAndRedirect;
                        existing.IsScheduled = obj.IsScheduled;
                        existing.TimeLeft = obj.TimeLeft;
                    }
                    else
                    {
                        //AllUsers.Add(obj);
                        App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
                        {
                            AllUsers.Add(obj);
                        });
                    }


                    if (obj.IsForwarded ?? false)
                    {
                        existing = ActiveForwards.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);

                        obj.TimeLeft = "";
                        var now = DateTime.Now;
                        var TimeRemaining = new TimeSpan?();
                        foreach (var schedule in ScheduledForwardsViewModel.ScheduledForwards)
                        {

                            if (schedule.DistinguishedName == obj.DistinguishedName)
                            {

                                if (schedule.StopJobStatus == "Scheduled")
                                {
                                    if (TimeRemaining == null)
                                    {
                                        TimeRemaining = schedule.StopTime - now;
                                    }
                                    else
                                    {
                                        if (schedule.StopTime - now < TimeRemaining)
                                        {
                                            TimeRemaining = schedule.StopTime - now;
                                        }
                                    }
                                }
                            }
                        }

                        if (TimeRemaining != null)
                        {
                            var remaining = (TimeSpan)TimeRemaining;
                            var min = new int();
                            if (remaining.Seconds > 30)
                            {
                                min = remaining.Minutes + 1;
                            }
                            double m = remaining.Minutes / (double)60;
                            double hm = remaining.Hours + m;
                            double h = hm / 24;
                            double dh = remaining.Days + h;
                            if (remaining.Days > 0)
                            {
                                var daysleft = Math.Round(dh, 2);
                                var quarterRound = Math.Round(dh * 4, MidpointRounding.ToEven) / 4;
                                obj.TimeLeft = quarterRound + "d";
                            }
                            else if (remaining.Hours > 0)
                            {
                                var hoursleft = Math.Round(hm, 2);
                                var quarterRound = Math.Round(hm * 4, MidpointRounding.ToEven) / 4;
                                obj.TimeLeft = quarterRound + "h";

                                obj.TimeLeft = remaining.Hours + "h" + remaining.Minutes + "m";
                            }
                            else
                            {
                                if (min == 0)
                                {
                                    obj.TimeLeft = "< 30s";
                                }
                                else
                                {
                                    obj.TimeLeft = min + "m";
                                }

                            }
                        }

                        if (existing != null)
                        {
                            existing.ForwardedTo = obj.ForwardedTo;
                            existing.ForwardedToAd = obj.ForwardedToAd;
                            existing.ForwardedToDn = obj.ForwardedToDn;
                            existing.ForwardedToPk = obj.ForwardedToPk;
                            existing.ForwardedToDisplay = obj.ForwardedToDisplay;
                            existing.IsForwarded = obj.IsForwarded;
                            existing.DeliverAndRedirect = obj.DeliverAndRedirect;
                            existing.IsScheduled = obj.IsScheduled;
                            existing.TimeLeft = obj.TimeLeft;
                        }
                        else
                        {
                            //ActiveForwards.Add(obj);
                            App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
                            {
                                ActiveForwards.Add(obj);
                            });
                        }

                    }
                }
                else if (obj.ObjectType.ToLower() == "group")
                {
                    if (obj.IsForwarded ?? false)
                    {
                        var existing = AllGroups.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);

                        if (existing != null)
                        {
                            existing.ForwardedTo = obj.ForwardedTo;
                            existing.ForwardedToAd = obj.ForwardedToAd;
                            existing.ForwardedToDn = obj.ForwardedToDn;
                            existing.ForwardedToPk = obj.ForwardedToPk;
                            existing.ForwardedToDisplay = obj.ForwardedToDisplay;
                            existing.IsForwarded = obj.IsForwarded;
                            existing.DeliverAndRedirect = obj.DeliverAndRedirect;
                            existing.IsScheduled = obj.IsScheduled;
                            existing.TimeLeft = obj.TimeLeft;
                        }
                        else
                        {
                            //AllGroups.Add(obj);
                            App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
                            {
                                AllGroups.Add(obj);
                            });
                        }
                    }
                }
                else if (obj.ObjectType.ToLower() == "contact")
                {
                    if (obj.IsForwarded ?? false)
                    {
                        var existing = AllContacts.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);

                        if (existing != null)
                        {
                            existing.ForwardedTo = obj.ForwardedTo;
                            existing.ForwardedToAd = obj.ForwardedToAd;
                            existing.ForwardedToDn = obj.ForwardedToDn;
                            existing.ForwardedToPk = obj.ForwardedToPk;
                            existing.ForwardedToDisplay = obj.ForwardedToDisplay;
                            existing.IsForwarded = obj.IsForwarded;
                            existing.DeliverAndRedirect = obj.DeliverAndRedirect;
                            existing.IsScheduled = obj.IsScheduled;
                            existing.TimeLeft = obj.TimeLeft;
                        }
                        else
                        {
                            //AllContacts.Add(obj);
                            App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
                            {
                                AllContacts.Add(obj);
                            });
                        }
                    }

                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
        RunOnce = true;
    }

0 个答案:

没有答案