2012-11-12 15 views
5

C#とSharepoint Programmingの新機能です。同じ名前空間内の異なるクラスからVisual WebPart(.cs)内のC#メソッドを呼び出す方法

私はWebPartとそれに使用されているC#について学びたいと思っています。私はリストに項目を追加/削除する視覚的なwebpartを作った。私はリスト内の項目を追加するボタンのクリックで呼び出されるメソッドを持っています。ここで

は私の方法である:これは正常に動作します

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

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(); 
     } 
    }    
} 

これは次のように呼ばれています。私は同じことを行う2番目のWebPartで同じメソッドを使用しようとしています(アイテムを追加する)。

しかし、私は同じプロジェクトで新しいVisual Webパーツを追加しました。これは、ボタンを追加

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

として、クラスやメソッドを呼び出したときに動作しないと私はデバッグを行うとき、私は次のメッセージを得る:

Object reference not set to an instance of an object.

誰かが私に何をすべきか教えてください。

答えて

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(またはあなた)は初期化関数を呼び出さなかったので、textboxフィールドはすべてnullであったため、エラーになりました。あなたがそれを初期化した場合、それらはすべて空のテキスト値を持ち、それでもあなたを助けません。テキストボックスとのやりとりは、異なるWebパーツのそれぞれで実行する必要があります。他のクラスの内部コントロールにアクセスすることはできません(または、少なくともそれを許可するのは悪い習慣です)。あなたが別のクラスに移動することができるのは、実際のUIのやりとり以外のすべてです。この場合、アイテムをリストに保存します。

いくつかのサイドノート:あなたはusingブロックで現在のコンテキストのSPSiteオブジェクトを置く

  • 。それはそれを処分する。 しないでください。作成したサイト/ Webオブジェクトのみを破棄します。現在のコンテキストのサイト/ Webオブジェクトは、別の要求に対して再利用されます。それを処理すると、その要求は機能しますが、破棄されたオブジェクトが次の要求に渡されたときに破損し、問題が別の要求に完全に含まれているため、エラーをデバッグすることが困難になります。
  • この例では、新しいWebを開いています。現在のコンテキストのWebが適切でないと確信していますか?そうでなければ、本当にルートWebが必要で、常にルートWeb上にあるとは限りませんが、SPContext.Current.Web.RootWebを使用すると、新しいWebサイトを開くことなくアクセスできます。
  • ユーザーが指定した値に対してConvert.ToInt32を使用しています。正しい数字を入力しなかった場合、カンマなどが含まれている場合は、これが破損します。int.TryParseを使用すると、無効な値が入力された場合、正常に機能しなくなります。
  • アイテムを追加するのに、list.Items.Add()を使用しないでください。 list.AddItem()を使用してください。 Items.Addは推奨されなくなりました。
+0

Windows SharePoint Servicesオブジェクトを使用してMicrosoft .NET Frameworkのメモリ内のオブジェクトを保持しないようにするには、「使用」ステートメントが多少重要であるとお読みください。それは正しいのですか? –

+1

@AndresAdhiあなたが作成する 'SPSite' /' SPWeb'オブジェクトを処分することは非常に重要です。作成していないサイト/ Webオブジェクトを廃棄しない*処理しないことも同様に重要です。すべてを "使用する"だけで問題が発生します。それがいつそして適切でないかを知る必要があります。現在のコンテキストを処分してはいけません。 – Servy

+0

あなたの理解を深めるために、私はhttp://solutionizing.net/2008/12/06/the-new-definitive-spsitespweb-disposal-article/処分に関するアドバイスの良いアドバイス+1をお勧めします!また、オブジェクトの廃棄に関する心配があった場合http://archive.msdn.microsoft.com/SPDisposeCheck – Truezplaya

関連する問題