2012-11-12 32 views
5

Tôi rất mới đối với Lập trình C# và Lập trình Sharepoint.Cách gọi Phương thức C# trong VisualWebPart (.cs) từ các Lớp khác nhau trong cùng một Không gian tên

Tôi đang cố gắng tìm hiểu về WebPart và C# được sử dụng trên đó. Tôi đã tạo một webpart trực quan để thêm/xóa các mục trong danh sách. Tôi có một phương pháp mà được gọi là trên một nút bấm mà thêm mục trong danh sách.

Đây là phương pháp của tôi:

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

này được gọi là:

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

này hoạt động Fine. Tôi đang cố gắng sử dụng cùng một phương pháp trên một WebPart thứ hai mà làm điều tương tự (thêm mục).

Tuy nhiên khi tôi đã thêm một Visual WebPart mới trên cùng một dự án và kêu gọi các lớp và phương pháp như

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

này Thêm nút không hoạt động và khi tôi làm một debug tôi nhận được thông báo sau:

Object reference not set to an instance of an object.

Ai đó có thể vui lòng cho tôi biết tôi nên làm gì?

Trả lời

1

Những gì bạn cần làm là tách biệt logic để lưu mục trong danh sách từ logic tương tác với giao diện người dùng.

Thực hiện một chức năng riêng biệt mà sẽ đưa các dữ liệu được lưu và lưu nó:

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

Sau đó, bạn có thể đặt phương pháp mà trong một lớp tiện ích ở đâu đó.

Sau khi bạn đã làm điều đó, bạn có thể gọi phương thức từ mỗi webparts:

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

Đối với lý do tại sao, có một số điều xảy ra ở đây. Vấn đề chính là khi bạn tạo một cá thể mới của webpart trực quan đầu tiên và gọi phương thức nó không truy cập các giá trị textbox của webpart thứ hai của bạn, nó truy cập các giá trị của textbox của webpart mới được tạo ra; cái chưa từng được hiển thị cho người dùng hoặc được ASP khởi tạo. Bởi vì ASP (hoặc bạn) không bao giờ được gọi là chức năng khởi tạo của nó, trường textbox là tất cả null, do đó lỗi của bạn. Nếu bạn đã khởi tạo nó thì tất cả chúng đều có giá trị văn bản trống, và nó vẫn không giúp bạn. Sự tương tác với hộp văn bản cần phải xảy ra trong mỗi webparts khác nhau; bạn không thể (hoặc ít nhất là không nên, nó sẽ là thực tế xấu để cho phép nó) truy cập các điều khiển nội bộ từ một lớp khác. Những gì bạn có thể chuyển sang lớp khác là mọi thứ bên cạnh tương tác UI thực tế; trong trường hợp này, việc lưu mục vào danh sách.

Một số lưu ý phụ:

  • Bạn đặt SPSite bối cảnh hiện nay trong một khối using; sẽ vứt bỏ nó. Đừng làm điều đó. Chỉ vứt bỏ các đối tượng Site/Web mà bạn tạo ra. Các đối tượng trang web/web của ngữ cảnh hiện tại được sử dụng lại cho các yêu cầu khác nhau; nếu bạn vứt bỏ nó, yêu cầu đó sẽ hoạt động, nhưng khi đối tượng được xử lý được chuyển tới yêu cầu tiếp theo, nó sẽ phá vỡ và kết quả là thường khó sửa lỗi vì vấn đề nằm trong yêu cầu hoàn toàn khác.
  • Bạn mở một trang web mới trong ví dụ đó; bạn có chắc chắn rằng trang web của ngữ cảnh hiện tại không phù hợp? Nếu không, và bạn thực sự muốn web gốc và không phải lúc nào cũng ở web gốc, bạn có thể sử dụng SPContext.Current.Web.RootWeb để truy cập trang web mà không cần mở một trang web mới.
  • Bạn đang sử dụng Convert.ToInt32 trên giá trị do người dùng cung cấp. Điều này sẽ phá vỡ nếu họ không nhập một số thích hợp, nếu họ bao gồm dấu phẩy, vv Hãy xem xét sử dụng int.TryParse để bạn có thể thất bại hơn nếu họ nhập một giá trị không hợp lệ.
  • Bạn không nên sử dụng list.Items.Add() để thêm một mục; bạn nên sử dụng list.AddItem(). Items.Add bị coi là không dùng nữa.
+0

Tôi đọc ở đâu đó rằng câu lệnh 'Sử dụng' có phần quan trọng khi sử dụng các đối tượng Windows SharePoint Services để tránh giữ lại các đối tượng trong bộ nhớ trong Microsoft .NET Framework. Điều đó có đúng không? –

+1

@AndresAdhi Điều quan trọng là phải vứt bỏ các đối tượng 'SPSite' /' SPWeb' mà bạn tạo ra. Nó không kém phần quan trọng để * không * vứt bỏ các trang web/đối tượng web mà bạn không tạo ra. Chỉ cần đặt một 'sử dụng' xung quanh mọi thứ sẽ gây ra vấn đề; bạn cần phải biết khi nào và không phù hợp. Bạn không bao giờ nên vứt bỏ bối cảnh hiện tại. – Servy

+0

Chỉ để hiểu thêm về tôi, tôi khuyên bạn nên đọc http://solutionizing.net/2008/12/06/the-new-definitive-spsitespweb-disposal-article/ Servy lời khuyên tốt về việc xử lý +1! Ngoài ra nếu bạn đã từng lo lắng về việc xử lý đối tượng, hãy kiểm tra http://archive.msdn.microsoft.com/SPDisposeCheck – Truezplaya

Các vấn đề liên quan