microsoft.sharepoint etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
microsoft.sharepoint etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

27 Temmuz 2011 Çarşamba

WSS Backward-Compatibility Comparison Table

ASP.NET Web Parts
SharePoint Backward Compatibility
WebBrowsableAttribute
BrowsableAttribute
WebDisplayName
FriendlyName
WebDescription
Description
Personalizable
WebPartStorage
PersonalizationScope
Storage
EditorPart
ToolPart
EditorPartCollection
ToolPart[]
CreateEditorParts()
GetToolParts()
RenderContents()
RenderWebPart()
SetPersonalizationDirty()
SaveProperties

Rerefence: Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattisonand, Daniel Larson

18 Temmuz 2011 Pazartesi

Designing Site Pages by Using Controls

Consturcting Pages with Custom Controls

using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;

namespace CustomSitePages
{
  public class CustomControl1 : WebControl
  {
    protected override void RenderContents(HtmlTextWriter output)
    {
      SPWeb site = SPContext.Current.Web;
      output.Write("Current Site: " + site.Title);
      output.Write("<br/>");
      output.Write("Current Site ID: " + site.ID.ToString());
    }
  }
}

Yukarıdaki örnek RenderContents metodunu override ederek custom control sınıfını değiştirir.

Bir assembly DLL'ini deploy etmek için iki seçenek vardır. İlki DLL'i strong name ile compile ederek Global Assembly Cahce'e yüklemek. İkincisi DLL'i application'un root directory'sindeki bin klasörüne koymaktır.

Deploy işlemi tamamlandığında ASP.NET ile register edebilirsiniz.

<%@ Page MasterPageFile="~masterurl/default.master"
    meta:progid="SharePoint.WebPartPage.Document" %>

<%@ Register Assembly="CustomSitePages, ... "
    Namespace="CustomSitePages" TagPrefix="CustomSitePages" %>


<asp:Content ID="main"
     ContentPlaceHolderId="PlaceHolderMain"
     runat="server">

<h3>A custom control example</h3>

<CustomSitePages:CustomControl1 ID="cc1" runat="server" />

</asp:Content>

Eğer sayfa özelleştirilmiş ise, sayfa güvenli modda çalışacaktır. Bu durumda safe control olarak register edilmeyen kontroller hataya neden olacaktır. Bunu çözmek için web.config'e bir custom SafeControl eklememiz gerekmektedir.

<SafeControl
  Assembly="CustomSitePages, ..."
  Namespace="CustomSitePages"
  TypeName="CustomControl1"
/>

Consturcting Pages with User Controls

<%@ Control Language="C#" %>

<script runat="server">
  protected void cmdButton1_Click(object sender, EventArgs e) {
    lblStatus.Text = "Hello, World";
  }
</script>
<asp:Button ID="cmdAddCustomer" runat="server" Text="Add Customer"
            OnClick="cmdAddCustomer_Click" />
<br/>
<asp:Label ID="lblStatus" runat="server" Text="" />

Bu örnekte olduğu gibi user controllerine kolayca başlangıç yapabiliriz. Unutmamaız gereken bir ayrıntı olarak WSS user kontrollerinin kullanıcı özellleştirmesini destekleemz. User kontrolleri daima front-end Web serverın dosya sisteminden yüklenip assemblylere derlenir.

Ayrıca User Kontrollerine in-line kod da yazabilirsiniz.

<%@ Control Language="C#" %>
<%@ Assembly Name="Microsoft.SharePoint, ..." %>
<%@ Import Namespace="Microsoft.SharePoint" %>

<script runat="server">
  protected override void OnLoad(EventArgs e) {
    SPWeb site = SPContext.Current.Web;
    lblDisplay.Text = "Current Site: " + site.Url;
  }
</script>

<asp:Label ID="lblDisplay" runat="server" />

User Control ve Custom Control Templeate'leri C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES adlı klasörün içinde tutulur. Bu template'lerin virtual directory'si /_controltemplates'tir.

Custom Controls gibi User Controls'te de güvenli moda dikkat edilmelidir. Eğer bu kontrol özelleştirilmiş bir sayfaya uyarlanacaksa web.config'e SafeControl register edilmelidir.

<SafeControl
  Src="~/_controltemplates/*"
  IncludeSubFolders="True"
  Safe="True"
  AllowRemoteDesigner="True"
/>

Designing Web Part Pages

Web Part'ları özelleştirmek ve kişiselleştirmek site sayfalarında desteklenir fakat application sayfalarında desteklenmez. ASP.NET 2.0 application'ında web part oluşturmak için WebPartManager instance'ı ve bir veya birdefn fazla WebPartZone kontrolü içeren bir .aspx sayfası oluşturmamız gerekmektedir.

WSS 3.0'ın Web Part altyapısı standart WebPartManager kontrolünü kullanmaz. Bunun yerine WebPartManager'dan türeyen SPWebPartManager kullanılır. Bu kontrol standart WebPartManager'ı override eder.

Çoğu zaman SPWebPartManager ile uğraşmak gerekmez çünkü bu kontrol zaten default.master sayfasında tanımlanmıştır. Yani siz master'ı default.master olan bir sayfa oluşturduğunuzda SPWebPartmanager otomatik olarak eklenecektir. Yapmanız gereken tek şey gerekli WebPartZone kontrollerinin eklenmesidir.

Bir sayfa template'ine WebPartZone eklemek için Microsoft.SharePoint.dll assembly'sinden bütün kontrolleri getiren bir Register eklememiz gerekmeketir.

<%@ Page MasterPageFile="~masterurl/default.master"
    Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,
              Microsoft.SharePoint, [full 4-part assembly name]"
    meta:progid="SharePoint.WebPartPage.Document" %>

<%@ Register Tagprefix="WebPartPages"
    Namespace="Microsoft.SharePoint.WebPartPages"
    Assembly="Microsoft.SharePoint, ..." %>



Custom Web Part page






Rerefence: Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattisonand, Daniel Larson

17 Temmuz 2011 Pazar

Programming with SPFile Objects

WSS obje modelinden bir sayfaya ulaşmak için SPFile sınıfını kullanırız. Bir sayfayı SPFile objesinin GetFile metodunu kullanarak okuyup değiştirebiliriz.

SPWeb site = SPContext.Current.Web;
SPFile homePage = site.GetFile("default.aspx");

OpenBinary ve OpenBinaryStream metodu ile safyayı okuyabilir, SaveBinary metodu ile sayfayı güncelleştirebilirsiniz. Ancak unutulmamalıdır ki güncelleştirilen sayfalar özelleşecektir ve unghosted halini alacaktır.

Delete, MoveTo, CopyTo metodları ile sayfaları silebilir, kopyalayabilir hatta yerlerini değiştrebilirsiniz.

Add metodu ile yeni sayfalar oluşturabilir. MemoryStream metodu ile bu sayfalara kod yazabilirsiniz.

// write out new page in memory stream
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine("<html><body>");
writer.WriteLine("Hello, World");
writer.WriteLine("</body></html>");
writer.Flush();

// add new page to site
SPWeb site = SPContext.Current.Web;
site.Files.Add("hello.htm", stream);

Ancak Add metodu yalnızca unghosted sayfalar oluşturduğunu unutmamamız gerekir.

Sayfaların özelleştirilmiş olup olmadığını öğrenmemiz için SPFile sınıfı bize CustomizedPageStatus propertysini sunar. Dahası RevertContentStream metodu ile bir sayfanın özelleştirilen özelliklerini kaldırarak o sayfayı ghosted haline çevirebilir.

Rerefence: Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattisonand, Daniel Larson

15 Temmuz 2011 Cuma

SharePoint Architecture

ASP.NET Framework aspnet_isapi.dll 'i ISAPI uznatısı olarak uygular.

.aspx, .ascx, .ashx, and .asmx dosya uzantılarını gören IIS isteği doğrudan aspnet_isapi.dll'e yönlendirir.

Temel hali ile ASP.NET konfigurasyon xml dosyası:
<configuration>

  <system.web>
    <customErrors mode="On" />
    <httpRuntime maxRequestLength="51200" />
    <authentication mode/>
    <identity impersonate="true" />
    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>

</configuration>

ASP.NET çatısı, aynı IIS Worker Process te bile çalışsalar ASP.NET uygulamalarını birbirinden yalıtır.

Master Page tanımı için @Master direktifini sayfanın üstüne koyarız
<%@ Master %>
<html>
<body>
  <form id="frmMain" runat="server">
    <table width="100%">
      <tr>
        <td> <!-- Display Litware Banner -->
          <h1>Litware Inc.</h1><hr />
        </td>
      </tr>
      <tr>
        <td> <!-- Display Main Body of Page -->
          <asp:contentplaceholder id="PlaceHolderMain" runat="server" />
        </td>
      </tr>
    </table>
  </form>
</body>
</html>

İçerik sayfası oluşturmak için @Page direktifi ve içine MasterPageFile özelliğini tanımlar ve uygun .master uzantılı dosyayı değer olarak verebilirsiniz.
<%@ Page Language="C#" MasterPageFile="~/default.master" %>
<script runat="server">
  protected override void OnLoad(EventArgs e) {
    lblDisplay.Text = "Hello World";
  }
</script>
<asp:Content ID="main" Runat="Server"
             ContentPlaceHolderID="PlaceHolderMain" >
  <asp:Label ID="lblDisplay" runat="server" />
</asp:Content>

WSS tarafında MasterPage zaten tanımlı olup biz ContentPage tanımlıyor ve WSS nin masterPage ine referans veriyor olacağız. Bu durumda WSS takımının bizler için hazırladığı PLACEHOLDER ları öğreneceğiz.

Http Request Pipeline 3 değiştirilebilir bileşene sahiptir: HttpHandler, HttpApplication, HttpModule. Bu bileşenleri kendi bileşenlerimizle değiştirebiliriz.

İstekler(Requests) geldiğinde hepsi bir kuyruğa sıralanır ve bir worker thread atanır. Sonra bu thread sırayla HttpHandler, HttpApplication, HttpModule bileşenlerden geçirir.

HttpHandler sınıfı IHttpHandler arayüzünü uygular. Kendi handlerimizi aşağıdaki gibi oluşturup web.config dosyasına ekleyerek kullanabiliriz.
using System.Web;
public class KendiHendlirim:IHttpHandler
{
    public bool IsReusable
    {
        get { throw new System.NotImplementedException(); }
    }

    public void ProcessRequest(HttpContext context)
    {
        throw new System.NotImplementedException();
    }
}

HttpApplication sınıfında BeginRequest, AuthenticaRequest, AuthorizeRequest eventlerini geçtikten sonra HttpHandler'a doğru isteği taşırız.

HttpModule benzer şekilde değiştirilebilir componenttır. HttpApplication sınıfı taraından tanımlanan eventlerin handle edilmesiyle değiştirebiliriz. Bu değişiklik, kontrolün HttpHandler sınıfına gönderilmeden önce gerçekleştirilir. Örneğin BeginRequest, AuthenticateRequest, and AuthorizeRequest gibi request-level eventlerini handle etmemiz için özel bir HttpModule component oluşturabiliriz. Bu değişiklikleri IHttpModule arayüzü ile implemente edip HTTP Request Pipeline'a bağlayan bir class yazarak gerçekleştirebiliriz. IHttpModule arayüzünü pipeline'a bağlamamız için web.config'e configuration elementlerini eklememiz gerekir.

Ayrıca HttpApplication'dan farklı olarak birden fazla HttpModule eklenebilir ve machine level'da değiştirilebilir.

Son olarak ASP.NET, HttpContext'i barındıran bir requesti başlatı ve HTTP Request Pipeline'a gönderir. Zaman perspektifinde baktığımızda HttpContext bütün custom kodların execute edilmeden önce oluşturulur. Bu durumda Request, User, ve Response objelerini her zaman programlayabiliriz:

HttpContext currentContext = HttpContext.Current;
string incomingUrl = currentContext.Request.Url;
string currentUser = currentContext.User.Identity.Name;
currentContext.Response.Write("Hello world");

WSS de bir web uygulaması için standart web.config dosyası
<configSections>
    <sectionGroup name="SharePoint">
      <section name="SafeControls" type="..." />
      <section name="RuntimeFilter" type="..." />
      <section name="WebPartLimits" type="..." />
      <section name="WebPartCache" type="..." />
      <section name="WebPartWorkItem" type="..." />
      <section name="WebPartControls" type="..." />
      <section name="SafeMode" type="..." />
      <section name="MergedActions" type="..." />
      <section name="PeoplePickerWildcards" type="..." />
    </sectionGroup>
  </configSections>

  <SharePoint>
    <SafeMode />
    <WebPartLimits />
    <WebPartCache />
    <WebPartControls />
    <SafeControls />
    <PeoplePickerWildcards />
    <MergedActions />
    <BlobCache />
    <RuntimeFilter />
  </SharePoint>
</configuration>

Microsoft Office SharePoint Designer ile WSS içindeki .aspx ve .master dosyalarımız özelleştirebiliriz. Değiştirilmiş dosyaları kaydettiğimizde, WSS değişimi content veritabanına yazar. Bu sayfayı istemci talep ettiğinde DB den çekilerek gönderilir.

The idea behind a virtual path provider is that it abstracts the details of where page files are stored away from the ASP.NET runtime.

SPVirtualPathProvider gider ASP.NET sayfasını content DB den çekip onu ASP.NET page parsırına gönderir ve oradan gelenide SPPageParserFilter ile DLL dosyasına çevirir. İstenirse bunu web.config de belirtilmesi kaydıyla DLL yapmadan da tutabilir.

SPVirtualPathProvider isteğin ghosted mı unghosted mı olduğuna karar vererek sayfayı content db den çeker.

Ghosted Pages:

UnGhosted Pages:

Virtual Directories

_vit_bin : dll ve .asmx dosyalarımızı barındırır.
_controltemplates : User controllerini barındırır.
_wpresources : Web Part lar tarafından kullanılan resource dosyaları tutar.
_layouts :Application page leri tutar.

Site Pages vs Application Pages

Özelleştirilmiş sayfalar bize büyük bir esneklik sağlıyorken dezavantajları da var. Özelleştirilmiş sayfalar content database'de saklandığı için her unghosted sayfa performansı etkileyecektir. Ayrıca bu sayfalar güvenlik açığına da sebebiyet verecektir. Örneğin admin izni olan bir kullanıcı in-line code ile DB'de tutulan özelleştirilmiş sayfaya saldırıda bulunabilir. Ancak WSS application sayfaları (.aspx) \LAYOUTS isimli bir directory'de tutarak hem özelleştirilmesini önler ve hem de compile edilmesini devre dışı bırakarak güvenliği üst seviyede tutar. Bu sayfaların fiziksel olarak aşağıdaki dizinde tutulmaktadır.

c:\program files\common files\microsoft shared
\web server extensions\12\TEMPLATE\LAYOUTS

Her yeni Web Application oluşturulduğunda \LAYOUTS directory sanal _layouts directoy'sine map edilir. WSS'de farklı siteler açıldığında buralardaki sanal _layouts directory'sine map edilerek de application'lara ulaşılabilir.

Rerefence: Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattisonand, Daniel Larson

The Web Part Life Cycle

Method/Event
Description
OnInit
Handles initialization of the control.
OnLoad
Handles the Load event.
CreateChildControls
Creates any child controls that are used as part of a composite control.
EnsureChildControls
Ensures that CreateChildControls has executed. Use this to ensure that a control you are referencing exists before accessing its data.
OnPreRender
Handles or initiates tasks such as data loading that must complete before the control can render. Asynchronous page tasks should be started from this method.
Page.PreRenderComplete
The page fires the PreRenderComplete event after all controls have completed their OnPreRender methods and the page has completed asynchronous tasks.
Render
Renders the entire control, including the outer tags and Web Part chrome.
RenderContents
Renders the contents of the control only, inside of the outer tags and style properties.

Rerefence: Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattisonand, Daniel Larson

12 Temmuz 2011 Salı

Programming Against the WSS Object Model

Another important aspect of WSS development is programming against the WSS object model. The core types provided by the WSS programming model are exposed through a standard WSS assembly named Microsoft.SharePoint.dll.

Let’s look at a simple example. Imagine you have just created a console application, and you have added a reference to Microsoft.SharePoint.dll. The WSS object model exposes an SPSite class that serves as an entry point into the WSS object model at the site collection level. Each site within a site collection is represented as an SPWeb object. Each list within a site is represented as an SPList object. Here’s a simple example using the WSS object model to access the top-level site within a target site collection and discover all its lists.

using Microsoft.SharePoint;
namespace Hello_WSS_OM {
  class Program {
    static void Main() {
      string sitePath = "http://litwareinc.com";
      // enter object model through site collection.
      SPSite siteCollection = new SPSite(sitePath);
      // obtain reference to top-level site.
      SPWeb site = siteCollection.RootWeb;
      // enumerate through lists of site
      foreach (SPList list in site.Lists) {
        Console.WriteLine(list.Title);
      }
      // clean up by calling Dispose.
      site.Dispose();
      siteCollection.Dispose();
    }
  }
}

You should observe the two calls to the Dispose method at the end of this code example. Several object types in the WSS object model, such as SPSite and SPWeb, use unmanaged resources and must be disposed of in a timely manner. If you fail to do this and simply rely on the garbage collector of the .NET Framework to reclaim memory, your code can cause problems by consuming far more memory than it needs. As a rule of thumb, when you create a disposable object, you are also responsible for calling Dispose on it. However, object references obtained through the WSS Web application’s SPContext should not be disposed.

Rerefence: Inside Microsoft Windows SharePoint Services 3.0 by Ted Pattisonand, Daniel Larson