5

私はC#とSharepointプログラミングに非常に慣れていません。

WebPartとそれに使用されるC#について学習しようとしています。リストのアイテムを追加/削除するビジュアルWebパーツを作成しました。リストにアイテムを追加するボタンクリックで呼び出されるメソッドがあります。

これが私の方法です:

public void TestMethod()
{
    using (SPSite oSPSite = SPContext.Current.Site)
    {
        using (SPWeb ospweb = oSPSite.OpenWeb())
        {
            SPList lst = ospweb.Lists["CusomList1"];

            SPListItem item = lst.Items.Add();

            item["Item1"] = txt1.Text;
            item["Item2"] = txt3.Text;
            item["Item3"] = Convert.ToInt32(txt3.Text);
            item["Item4"] = txt4.Text;
            item.Update();
        }
    }            
}

これは次のように呼ばれます。

protected void Button1_Click(object sender, EventArgs e)
{
    TestMethod();
}

これは問題なく動作します。同じこと(アイテムの追加)を行う2番目のWebパーツで同じメソッドを使用しようとしています。

ただし、同じプロジェクトに新しいVisual Webパーツを追加し、クラスとメソッドを次のように呼び出した場合

protected void Button1_Click(object sender, EventArgs e)
{
    VWP1 NewClass = new VWP1();
    NewClass.TestMethod();
}

この[追加]ボタンは機能せず、デバッグを実行すると、次のメッセージが表示されます。

オブジェクト参照がオブジェクト インスタンスに設定されていません。

誰かが私に何をすべきか教えてもらえますか?

4

1 に答える 1

1

あなたがする必要があるのは、リスト内のアイテムを保存するロジックを、ユーザーインターフェイスと対話するロジックから分離することです。

保存するデータを取得して保存する別の関数を作成します。

public static void SaveItem(string item1, string item2, int item3, string item4)//TODO rename parameters
{
    SPListItem newItem = SPContext.Current.Web.Lists["CusomList1"].AddItem();
    //set fields of new item
    newItem.Update();
}

次に、そのメソッドをユーティリティクラスのどこかに置くことができます。

それが終わったら、各Webパーツからメソッドを呼び出すことができます。

protected void Button1_Click(object sender, EventArgs e)
{
    MyUtilityClass.SaveItem(txt1.Text, txt2.Text, Convert.ToInt32(txt3.Text), txt4.Text);
}

理由としては、ここで起こっていることがたくさんあります。主な問題は、最初のビジュアルWebパーツの新しいインスタンスを作成し、メソッドを呼び出すと、2番目のWebパーツのテキストボックス値にアクセスせず、新しく作成されたWebパーツのテキストボックス値にアクセスすることです。ユーザーに表示されたことがない、またはASPによって初期化されたことがないもの。ASP(またはあなた)がその初期化関数を呼び出さなかったため、テキストボックスフィールドはすべてnullであり、エラーが発生しました。あなたがそれを初期化したならば、それらはすべて空のテキスト値を持っているでしょう、そしてそれはまだあなたを助けません。テキストボックスとの相互作用は、それぞれの異なるWebパーツ内で発生する必要があります。別のクラスから内部統制にアクセスすることはできません(または少なくともそうすべきではありません。許可するのは悪い習慣です)。別のクラスに移動できるのは、実際のUIインタラクション以外のすべてです。この場合、アイテムをリストに保存します。

いくつかのサイドノート:

  • 現在のコンテキストのSPSiteをusingブロックに入れます。それはそれを処分します。 それをしないでください。作成したサイト/Webオブジェクトのみを破棄します。現在のコンテキストのサイト/Webオブジェクトは、別のリクエストに再利用されます。それを破棄すると、そのリクエストは機能しますが、破棄されたオブジェクトが次のリクエストに渡されると壊れ、問題は別のリクエストに完全にあるため、エラーのデバッグが困難になることがよくあります。
  • その例では、新しいWebを開きます。現在のコンテキストのWebが適切ではないと確信していますか?そうではなく、本当にルートWebが必要であり、常にルートWebにいるとは限らない場合はSPContext.Current.Web.RootWeb、新しいWebを開かずにアクセスするために使用できます。
  • Convert.ToInt32ユーザー提供の値を使用しています。適切な数値を入力しない場合、コンマが含まれている場合など、これはint.TryParse機能しません。無効な値を入力した場合に、より適切に失敗できるように、使用を検討してください。
  • list.Items.Add()アイテムの追加には使用しないでください。を使用する必要がありますlist.AddItem()Items.Add非推奨と見なされます。
于 2012-11-12T19:05:32.307 に答える