0

私はC#にかなり慣れていないので、簡単に教えてください。

何日も頭を抱えていた大きな問題があります。

問題: Web アプリケーションがあり、MVC4 を使用しています。ドキュメントが開かれると、メソッド SaveValues() を呼び出すことによって、モデル内のすべての値がセッションの backingstore に作成されます。

public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
    public Dictionary<string, object> BackingStore = new Dictionary<string, object>();
    public Dictionary<string, object> Changes = new Dictionary<string, object>();
    public bool HasChanges { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;


    public void SaveValues()
    {
        // Expensive, to use reflection, especially if LOTS of objects are going to be used. 
        // You can use straight properties here if you want, this is just the lazy mans way.

        this.GetType().GetProperties().ToList().ForEach(tProp => { BackingStore[tProp.Name] = tProp.GetValue(this, null); Changes[tProp.Name] = ""; });
        HttpContext.Current.Session["SbackingStore"] = BackingStore;


        HasChanges = false;

    }

    public void RevertValues()
    {
        // Again, you can use straight properties here if you want. Since this is using Property setters, will take care of Changes dictionary.
        this.GetType().GetProperties().ToList().ForEach(tProp => tProp.SetValue(this, BackingStore[tProp.Name], null));
        HasChanges = false;


    }

    public void OnPropertyChanged(string propName, object propValue)
    {
        // If you have any object types, make sure Equals is properly defined to check for correct uniqueness.
        if (HttpContext.Current.Session["SbackingStore"] != null)
        {
            if (propValue == null) propValue = "";
            BackingStore = (Dictionary<string, object>)HttpContext.Current.Session["SbackingStore"];


            if (BackingStore[propName].Equals(propValue))
            { }
            else
            {
                Changes[propName] = propValue;
                HasChanges = true;
            }


            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

    }

}

}

私は so のようなクラス設定を持っています。

public class VisitViewModel : NotifyPropertyChangedBase
{
    public Activity ActivityVM { get; set; }
    public VBSSteps VBSStepsVM { get; set; }
    public ProductTime ProductTimeVM { get; set; }
    public OtherPST OtherPSTVM { get; set; }
    public TimeRange TimeRangeVM { get; set; }
}

上記の VisitViewModel クラスに分類される各クラスは、次の例のようにコーディングされます。それらは NotifyPropertyChangedBase を継承します (情報が多すぎるため、すべてのクラスをここに掲載することはしません)。

public class Activity : NotifyPropertyChangedBase
{
    public int Id { get; set; }
    public string NotesID { get; set; }
    public string SubID { get; set; }
    public string Form { get; set; } // Form Name

    private string _custNumber;
    [MobileCRM.Resources.LocalizedString.LocalizedDisplayName("CustomerNumber")]
    [DataType(DataType.Text)]
    [Required]
    public string CustNumber
    {
        get { return _custNumber; }
        set { _custNumber = value; OnPropertyChanged("CustNumber", value); }
    }

    private string _companyName;
    [MobileCRM.Resources.LocalizedString.LocalizedDisplayName("CustomerName")]
    [DataType(DataType.Text)]
    [Required]
    public string CompanyName
    {
        get { return _companyName; }
        set { _companyName = value; OnPropertyChanged("CompanyName", value); }
    }
}

ここでの問題は、以下のようなバッキング ストア (セッション) で作成される値です (それらのいずれか、つまり必要なキーと値を含む ActivityVM を展開すると)。

[0] {[ActivityVM, MobileCRM.Models.Activity]}
[1] {[VBSStepsVM, MobileCRM.Models.VBSSteps]}
[2] {[ProductTimeVM, MobileCRM.Models.ProdcutTime]}
[3] {[OtherPSTVM, MobileCRM.Models.OtherPST]}
[4] {[TimeRangeVM, MobileCRM.Models.TimeRange]}
[5] {[HasChanges, False]}

これに関する問題は、値を取得して変更されたデータを比較するために使用するコードです。プロパティとして保存されているため、値を見つけることができません....誰かがこれを回避する方法を提案できますか? おそらく、値が保存されるときに、各クラスをループして、各クラスのすべての値をバッキング ストアに追加し、値がプロパティとして保存されるのを止めることができます。

バッキング ストアから値を取得して比較を実行するコード (データが変更されたかどうかを確認するため)

public void OnPropertyChanged(string propName, object propValue)
{
    // If you have any object types, make sure Equals is properly defined to check for correct uniqueness.
    if (HttpContext.Current.Session["SbackingStore"] != null)
{
    if (propValue == null) propValue = "";
    BackingStore = (Dictionary<string, object>)HttpContext.Current.Session["SbackingStore"];


    if (BackingStore[propName].Equals(propValue)) // Errors here : gives The given key was not present in the dictionary.
4

1 に答える 1

0

あなたはこのコードを持っています:

public void SaveValues()
    {
        // Expensive, to use reflection, especially if LOTS of objects are going to be used. 
        // You can use straight properties here if you want, this is just the lazy mans way.

        this.GetType().GetProperties().ToList().ForEach(tProp => { BackingStore[tProp.Name] = tProp.GetValue(this, null); Changes[tProp.Name] = ""; });
        HttpContext.Current.Session["SbackingStore"] = BackingStore;


        HasChanges = false;

    }

すべてのクラスは、このメソッドで基本クラスを継承します。したがって、派生クラスのいずれかで SaveValues メソッドを呼び出すたびに、HttpContext.Current.Session["SbackingStore"] が新しい backingstore で ovveriden を取得するため、「A key is missing in Dictionary」が表示されます。

于 2013-07-03T14:27:18.293 に答える