Saturday, July 16, 2011

Have you deleted your list edit or display webpart?

If you or anybody else intentionally or unintentionally deleted view or edit item webpart in editform.aspx or dispform.aspx page or if you one day come and see your list menu url for edit or view item redirect you to the home page instead of list forms pages, you can fix your page by:
1- open both editform.aspx and dispform.aspx in SharePoint Designer.
2- copy the webpart code from incorrupt page to corrapt one inside WebPartPages:ListFormWebPart tag.
3- if the corrupt page is editform.aspx change ControlMode from Display to Edit and FormType from 4 to 6 and if your corrupt page is dispform.aspx do it vice versa
4- Save your file and close the Designer

I highlighted those parts you need to change:
<WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main"><ZoneTemplate>
<WebPartPages:ListFormWebPart runat="server" __MarkupType="xmlmarkup" WebPart="true" __WebPartId="{CF23ABCB-183A-4333-9E4F-898160A14A94}" >
<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
  <Title>پیشنهادات و انتقادات</Title>
  <FrameType>Default</FrameType>
  <Description />
  <IsIncluded>true</IsIncluded>
  <PartOrder>1</PartOrder>
  <FrameState>Normal</FrameState>
  <Height />
  <Width />
  <AllowRemove>true</AllowRemove>
  <AllowZoneChange>true</AllowZoneChange>
  <AllowMinimize>true</AllowMinimize>
  <AllowConnect>true</AllowConnect>
  <AllowEdit>true</AllowEdit>
  <AllowHide>true</AllowHide>
  <IsVisible>true</IsVisible>
  <DetailLink />
  <HelpLink />
  <HelpMode>Modeless</HelpMode>
  <Dir>Default</Dir>
  <PartImageSmall />
  <MissingAssembly>وارد کردن این جزء وب ممکن نیست.</MissingAssembly>
  <PartImageLarge />
  <IsIncludedFilter />
  <ExportControlledProperties>true</ExportControlledProperties>
  <ConnectionID>00000000-0000-0000-0000-000000000000</ConnectionID>
  <ID>g_cf23abcb_183a_4333_9e4f_898160a14a94</ID>
  <ListName xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">{437B63DD-D5CE-4C66-8931-21318AD31AF2}</ListName>
  <ListItemId xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">0</ListItemId>
 
<ControlMode xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">Display</ControlMode> 
 <TemplateName xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">ListForm</TemplateName> 
 <FormType xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">4</FormType> 
<ViewFlag xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">1048576</ViewFlag>
</WebPart>
</WebPartPages:ListFormWebPart>
</ZoneTemplate></WebPartPages:WebPartZone>

Sunday, June 26, 2011

Custom properties in visual web parts

When you are developing visual web parts in SharePoint 2010 and you need to have custom properties in your web part you need to know few things in order to connect the webpart class file to user control code behind file in order to have access to the web part properties in the user control code behind file.  Following are the steps that you should go through:


1- put your custom properties in the web part class file.
    example:
        private static string _fbaurls = "";
        [System.Web.UI.WebControls.WebParts.WebBrowsable(true),
        System.Web.UI.WebControls.WebParts.Personalizable(PersonalizationScope.Shared),
        System.Web.UI.WebControls.WebParts.WebDisplayName("آدرس سیستمهای Forms Authentication "),
        System.Web.UI.WebControls.WebParts.WebDescription("آدرس سسیتمهای Forms Authentication را در این قسمت وارد کنید. برای جداسازی آنها از علامت ; استفاده کنید."),
        System.ComponentModel.Category("تنظیمات"),
        System.ComponentModel.DefaultValue("")]

        public string FBAUrls
        {
            get { return _fbaurls; }
            set { _fbaurls = value; }
        }

2- then you need to change the
CreateChildControls method as below to convert the page controls to the user control class:
        protected override void CreateChildControls()
        {
            SystemLinksWPUserControl control = (SystemLinksWPUserControl)Page.LoadControl(_ascxPath);
            Controls.Add(control);
        }

3- like the piece of code below define a consumer property in user control code behind file:
        private static string _fbaurls;
        public string FBAUrls
        {
            get { return _fbaurls; }
            set { _fbaurls = value; }
        }


4- in last step, map the properites in web part class file and user control code behinde file together in CreateChildControls method. It should be something like this:
        protected override void CreateChildControls()
        {
            SystemLinksWPUserControl control = (SystemLinksWPUserControl)Page.LoadControl(_ascxPath);
            control.FBAUrls = this.FBAUrls;
            controls.Add(control);
        }

Friday, June 3, 2011

Lync Server 2010 and SharePoint Integration

Lync Server 2010 is the new generation of Office Communications Server . According to "Lync 2010 Integration" article in technet:

With Lync and Microsoft SharePoint Server integration, Lync users can do the following:
  • Use the Skill view, in Lync search results, to search Microsoft SharePoint Server 2010 My Site pages for people with specific skills or expertise
  • Access their SharePoint Server 2010 My Site profile page from the Lync - Options dialog box
  • On a SharePoint Server page, view a user’s Lync presence indicator and its associated menu or contact card
Here is the step by step guide for deploying Lync Server 2010 Enterprise Edition which I found it complete and useful to getting start (just as a note, in this guide audio and video conferencing feature weren't enabled during topology building step, if you want to have this features you must enable "conferencing, which includes audio, video, and application sharing" in "select features" page).


After your successful installation, you can find Microsoft Lync Server 2010 Client and Device Deployment Guide here .

One of the cool improvements in Lync Server 2010 in comparison with OCS 2007 is its administration Control Panel. It provides a graphical user interface to manage configurations and users which I liked it the most.
To find out about clients features see Lync server 2010 Client Features Comparison Table and just for final point all features that we have had in live meeting and office communicator now is gathered in only Lync client.

    Friday, May 6, 2011

    RSS Reader WebPart in MOSS 2007

    If you want SharePoint 2007 built-in RSS Reader webpart read your SharePoint content and you get this error message inside the webpart after configuration :

    "The RSS webpart does not support authenticated feeds"

    then you need to change the authentication method from NTLM to Kerbrous and if you don't want to do that you can install an alternative RSS Reader webparts like the one below to get rid of the error message:

    P.S: After some slight changes to the source code, this webpart works greatly in our environment.

    Friday, April 22, 2011

    Thursday, April 7, 2011

    Export to excel and lookup fields problem

    When you use lookup fields or any custom fields based on lookups, and you use the "Export to Spreadsheet" in lists or documents library Action Menu, the lookup columns are exported with their seprator characters and IDs (for example Book1#;12 instead of just Book1)  which is very unpleasant for end users. For OOT lookup fields if you don't select "Allow Multiple Values" you cannot see the problem otherwise it exists. It seems that it is the way that these things works.Because of not finding any workaround or solution I added a custom "Export to Excel" menu option to export the list items to excel file without additional unwanted information. Below is the code:

    elements.xml

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
        <!-- Add the action to the List Toolbar Actions Menu Dropdown -->
        <CustomAction Id="Vana.ExportListActionsToolbar"
          RegistrationType="List" 
          GroupId="ActionsMenu"
          Location="Microsoft.SharePoint.StandardMenu"
          Sequence="1000"
          ImageUrl="/_layouts/images/menuexportexcel.png"
          Title="Export List To Excel ">
        <UrlAction Url="javascript:function ExportView(){var site='{SiteUrl}';var list='{ListId}';var view=ctx.view;window.open(site + '/_layouts/ExportToExcel/ExportList.aspx?list=' + list + '&amp;view=' + view, 'Download' ,'resizable=0,width=250,height=250' );}ExportView();"/>
        </CustomAction>
    </Elements>

    feature.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <Feature Id="769826dd-9dd2-11db-96ca-005056c00008"
    Title="Export List To Excel"
    Description="This feature adds a Export To Excel command in the Actions menu for Windows SharePoint Services lists."
    Version="1.0.0.0"
    Scope="Web"
    xmlns="http://schemas.microsoft.com/sharepoint/">
        <ElementManifests>
            <ElementManifest Location="elements.xml" />
        </ElementManifests>
    </Feature>

    ExportToExcel.aspx 

     
    <%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase"
      EnableViewState="true" EnableViewStateMac="false" %>
    <%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Assembly Name="WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
    <%@ Import Namespace="Microsoft.SharePoint" %>
    <%@ Import Namespace="System.IO" %>
    <%@ Import Namespace="System.IO.Packaging" %>
    <%@ Import Namespace="System.Collections" %>
    <%@ Import Namespace="System.Xml" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Xml.Serialization" %>
    <%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
    <%@ Import Namespace="Microsoft.SharePoint.WebPartPages" %>
    <%@ Import Namespace="Microsoft.SharePoint.Administration" %>
    <%@ Import Namespace="System.Xml.Xsl" %>

    <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

    <script runat="server">
       protected override void OnLoad(EventArgs e)
         {

           // List GUID
           string listId = "";
           
             listId = Page.Request.QueryString["list"];

          // Current View GUID
           string viewID = string.Empty;
           viewID = Page.Request.QueryString["view"];

             if (listId == null)
             {
                 Page.Response.Write("<p>The list ID parameter ('list') does not exist.</p>");
             }
             else
             {
                 try
                 {
                     using (SPWeb web = SPControl.GetContextWeb(Context))
                     {

                         SPList list = web.Lists[new Guid(listId)];
                         SPView view = list.Views[new Guid(viewID)];
                         SPViewFieldCollection viewfield = list.Views[new Guid(viewID)].ViewFields;
                         bool removeID = false;
                         bool removeCreated = false;
                           
                         SPQuery query = null;
                         if (viewID == null || string.IsNullOrEmpty(viewID))
                         {
                               query = new SPQuery();
                             query.Query = list.DefaultView.Query;
                         }
                         else
                         {
                             query = new SPQuery();
                             query.Query = list.Views[new Guid(viewID)].Query;
                             query.ViewFields = viewfield.SchemaXml;
                             string VFSchema = viewfield.SchemaXml;                     
                             if (!VFSchema.Contains("<FieldRef Name=\""+list.Fields["شناسه"].InternalName+"\" />"))
                             {
                                 removeID = true;
                             }

                             if (!VFSchema.Contains("<FieldRef Name=\"" + list.Fields["ایجاد شده"].InternalName + "\" />"))
                             {
                                 removeCreated = true;
                             }
                         }
                         DataGrid dgTemp = new DataGrid();
                         DataTable dtTemp = list.GetItems(query).GetDataTable();
                       
                         //Remove Unwanted Columns
                         if(removeID)
                            dtTemp.Columns.Remove("ID");
                         if(removeCreated)
                            dtTemp.Columns.Remove("Created");
                         
                         //Replace Internal Names with Normal Names
                         foreach (DataColumn col in dtTemp.Columns)
                         {
                             SPField field = list.Fields.GetFieldByInternalName(col.ColumnName);
                             col.ColumnName = field.Title;
                         }
                       
                         dgTemp.DataSource = dtTemp;
                         dgTemp.DataBind();
                         dgTemp.HeaderStyle.Font.Bold = true;
                         dgTemp.HeaderStyle.Font.Name = "Tahoma";// new System.Drawing.Font("Arial", 8.5F, System.Drawing.GraphicsUnit.Pixel);
                         dgTemp.HeaderStyle.Font.Size = FontUnit.Point(10);
                         dgTemp.HeaderStyle.BackColor = System.Drawing.ColorTranslator.FromHtml("#4F81BD");
                         dgTemp.BackColor = System.Drawing.ColorTranslator.FromHtml("#B8CCE4");
                         dgTemp.AlternatingItemStyle.BackColor = System.Drawing.ColorTranslator.FromHtml("#DBE5F1");
                         dgTemp.ItemStyle.Font.Name = "Tahoma";
                         dgTemp.ItemStyle.Font.Size = FontUnit.Point(9);
                         dgTemp.Attributes.Add("style", "dir:rtl");
                         Response.ContentType = "application/vnd.ms-excel;charset=windows-1251 name=" + "Book" + ".xls";
                         Response.AddHeader("content-disposition", "attachment;filename=" + "Book" + ".xls");
                       
                         Response.Charset = "UTF-8";
                         this.EnableViewState = false;
                         System.IO.StringWriter tw = new StringWriter();
                         System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(tw);
                         dgTemp.RenderControl(hw);
                       
                         //to Omit ;#ID from Lookup Fields 
                         string twTemp = Regex.Replace(tw.ToString(), ">[0-9]+;#", ">");
                         twTemp = Regex.Replace(twTemp, ";#[0-9]+;#", ", ");
                         Response.Write(twTemp);
                       
                         try
                         {

                             Response.End();
                         }
                         catch (Exception ex)
                         {
                         }
                     }
                 }
                 catch (Exception ex)
                 {
                     //Response.Write("Excption : " + ex.Message + " " + ex.StackTrace);
                 }
             }         
         }
     </script>
     <asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
      <table border="0" cellpadding="2" cellspacing="0" style="width: 100%; font-size: 9pt">
         <tr>
          <td valign="top" style="width: 120px" colspan="2">
            <asp:Label ID="ErrorMessage" runat="Server" ></asp:Label>
            </td>
        </tr>  
         </table>
     
    </asp:Content>
    <asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
      ارسال به Excel
    </asp:Content>
    <asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea"
      runat="server">
        ارسال به Excel
    </asp:Content>

    Friday, March 11, 2011

    Dubugging Error No1989080679

     Error (-1989080679) Unable to start debugging on the web server. The web server is not configured correctly. See help for common configuration errors. Running the web page outside of the debugger may provide further information.

    If you receive such an error message when you are executing the visual studio project on you newly configured SharePoint environment, it maybe related to your web.config file, so the work around is as below:
    • open your web.config file
    • change the "debug" property in compilation tag from "false" to "true":
               result <compilation batch="false" debug="true">
    • save and close the file

    Thursday, February 17, 2011

    Folder with Title Column

    When we create a Folder in a SharePoint(2007/2010) Document Library, in "Edit Properties" Page of the Folder we can only change the Name of it. Another point is that the Name of the Folder uses as a part of its URL. 
    Sometimes there is a need to keep the Folder path URL short and also has a kind of description or user friendly name for your Folder. Out of the box, SharePoint default Folder Content Type doesn't support this for some reasons the Title column is hidden and there isn't the possibility of change it. To have such a Folder with Title column you can complete these steps:
    • Navigate to Site Settings > Site Content Types
    • Create a new Content Type and choose "Folder Content Types" as its Parent Content Type
    • Click on Title column of the new created content type and for its Column Settings choose
    • Go to your Document Library and add new created Content Type to it.

    Monday, February 7, 2011

    Filling fields using javascript and web services

    Some days ago there was a request for filling a look up field in New Item page automatically according to the current user information. One of the ways of doing this, is coding for custom field but the other quick and easy way is using JavaScript and web services

    1- Adding a field with default value of [Me] to hold the user name of current user
    2- Adding a content Editor webpart in NewForm.aspx page of List and put the code below inside its source editor:

    <script type="text/javascript" language="javascript">

        var siteCompleteURL = document.URL;
        componentList = siteCompleteURL.split('//');
        siteURL = componentList[1].split('/');

        var curUserLastName = new Array();
        var curUserID = new Array();
        var baseURL = componentList[0] + "//" + siteURL[0] + "/";
        var siteURL = componentList[0] + "//" + siteURL[0] + "/";

        //Get The Value Of Hidden UserName Field
        var curUser = document.getElementById('USERNAMEID').value;


        //Hide The UserName Field and its Label
        document.getElementById('
    USERNAMEID').style.visibility='hidden';
        var nobrTags = new Array();
        nobrTags=document.getElementsByTagName('nobr');
        for (i = 0; i < nobrTags.length; i++) {
        if (nobrTags(i).innerHTML=='UserName')
          nobrTags(i).innerHTML='';
         }

        //Get The LookUp Filed Object
        var expOwnerCID='LOOKUPFIELDID';

        //GUID Of The List We Want To Query
        var listGUID = 'd6e7ebe5-79b1-4e92-b50a-adf6d4c79c6e';

        //Where Statement of Web service Request
        var whereStatement = "<Eq><FieldRef Name=\"_x0646__x0627__x0645__x0020__x06\" /><Value Type=\"User\">"+curUser+"</Value></Eq>";
       
        function GetRootUrl() {
            return siteURL;
        }

        function getNodeValue(obj, tag) {
            return obj.getElementsByTagName(tag)[0].firstChild.nodeValue;
        }

        function QueryListEx(listGuid, where, rowLimit, extractRows) {
            var a = new ActiveXObject("Microsoft.XMLHTTP");
            if (a == null) return null;
            a.Open("POST", GetRootUrl() + "_vti_bin/dspsts.asmx", false);
            a.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
            a.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/sharepoint/dsp/queryRequest");

            var d = '<?xml version=\"1.0\" encoding=\"utf-8\"?>'
        + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
        + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
        + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope\/\">"
        + " <soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope\/\">"
        + " <dsp:versions xmlns:dsp=\"http://schemas.microsoft.com/sharepoint/dsp\">"
        + " <dsp:version>1.0</dsp:version>"
        + " </dsp:versions>"
        + " <dsp:request xmlns:dsp=\"http://schemas.microsoft.com/sharepoint/dsp\""
        + " service=\"DspSts\" document=\"content\" method=\"query\">"
        + " </dsp:request>"
        + " </soap:Header>"
        + "<soap:Body>"
        + "<queryRequest "
        + " xmlns=\"http://schemas.microsoft.com/sharepoint/dsp\">"
        + " <dsQuery select=\"/list[@id='" + listGuid + "']\""
        + " resultContent=\"dataOnly\""
        + " columnMapping=\"attribute\" resultRoot=\"Rows\" resultRow=\"Row\">"
        + " <Query RowLimit=\"" + rowLimit + "\">"
        + " <Where>" + where + "</Where>"
        + " </Query>"
        + " </dsQuery>"
        + " </queryRequest>"
        + "</soap:Body>"
        + "</soap:Envelope>";

            a.Send(d);

            if (a.status != 200)
                return null;

            var xmlDoc = a.responseXML;
            var responseElement = xmlDoc.getElementsByTagName("Row");
            var temp = '';        
            for (i = 0; i < responseElement.length; i++) {
                //Store Title Column Value
                curUserLastName[i] = responseElement[i].getAttribute('Title');

                var expOwner = curUserLastName[i];
               
                //To Execute This Code At The End Of The Page
                Sys.Application.add_load(function () {
                    document.getElementById(
                    getSubControlID(expOwnerCID, g_EntityEditorUpLevelId)).innerHTML = (expOwner);
                    onKeyUpRw(expOwnerCID);
                });
                        }
        }
        QueryListEx(listGUID, whereStatement, 1, true);
    </script>

    A good source for JavaScript API that help me to complete this job:

    Saturday, January 22, 2011

    SharePoint 2010, PowerPivot and Oracle

    Using PowerPivot Service in SharePoint 2010 is a good way of sharing PowerPivot sheets and doing data refresh without the need of installing PowerPivot Add-in on client's machine.

    My first experience of using this service with Oracle 10.2.0.4, was a bit annoying but successful at the end. So, I want to share the points with people who stuck in similar situation and don't know what they should install on their SharePoint server to make a complete connection to Oracle database via already made PowerPivot workbooks.

    Here I summarize those steps I have taken to get it works:
    • Installing and configuring SharePoint and PowerPivot as Microsoft explained in this article.
    If get an unsuccessful error message during SQL Server 2008 what pointed out here (for those who missed the step there is a workaround) may solve your problem.
    In this post the writer describe in Oracle 11G Client Tools  the problem related to the bug No. 3807408 has been resolved. I didn't try it myself but it seems a good alternative.
    • Adding the tnsnames.ora file in NETWORK folder of Oracle Home
    • Restarting the server

      Opening Post - Stay Hungry Stay Foolish

      It's a long time from my first decision of creating a blog to write about my working life. I've lived with SharePoint for 5 years, we spent lots of good and bad moments together, so I want to share my future experiences with this lovely creature here with others.
      and ....
      Today, finally in my birthday I broke the spell and start this blog to start another way of being, to Stay Hungry and Stay Foolish.