Pages

Monday, 9 February 2015

Sharepoint 2013- app prompting for credentials

I have developed an app in app in office 365 site and every thing went well for app in office 365 site. I have developed same app for share point 2013, using visual studio office development tools. Before deploying app in share point server, we need to check the following list of things in share point server,

  • Create an App Domain-- Done
  • Run Shared Service Instances-- Done
  • Check App Service and SharePoint Subscription services are running in the server-- Done
  • Create Subscription Settings Service Application, Subscription Settings Service Application Proxy through Power shell-- Done
  • Create App Management Service, App Management Service Proxy-- Done
  • Add App prefix-- Done
  • Add App Domain to the List of Intranet Sites in Internet Options-- Done 

Deployed the app in share point site, while accessing the app through share point site, it is prompting for credentials. I have tried many times with different credentials, Redeployed app to share point site and restarted my machine, No luck.. :(

I have googled for the same issue and in Microsoft forums i got some clue on the issue. The issue here is we need set the value for DisableLoopbackCheck registry key.

What is Loop Back Check
From Server 2003 SP1, There is feature called Loop back check related to security. It will makes server can't call by itself through the host name, that share point does. So that share point will prompts us to enter credentials.

i have followed following steps to fix this error,

Go to Registry Editor (Run-->regedit)




Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa




Right-click Lsa--> New--> DWORD Value.



Type DisableLoopbackCheck, and then press ENTER.



Right click on DisableLoopbackCheck--> Modify,




Change value form 0 to 1 and click on OK.



Quit Registry editor and restart computer.

That's it. My issue got fixed and i am able to see my custom app. Hope this help you.

Thursday, 21 August 2014

Sharepoint 2013 - IE11 Issues

Client Object Model Javascript and web url issue:
o   I found the solution. Check the view source of any sharepoint page in SP2013. I found a javascript variable 'L_Menu_BaseUrl' which holds the web relative Url.
o   SharePoint 2013 with IE11: L_Menu_BaseUrl is undefined. Unfortunately these variable disappeared when I updated to IE 11.
o   This problem is present in SP2013 in IE11 only, and the strange thing is that if you switch on the compatibility mode (or changes the user agent string using F12) the variables return.

o   So I replaced the L_Menu_BaseUrl to hidden filed value(get the server side value and pass it in the javascript hidden field variable).

Here is the sample :
<script  type="text/javascript">
function openNew(Callback) {
        var popupURL = document.getElementById('<%=hdnURL.ClientID%>').value;
        //L_Menu_BaseUrl + "/Lists/List1/NewForm.aspx";(don't use the variable when using IE11)
        var options = { url: popupURL };
        if (Callback) {
            options.dialogReturnValueCallback = Function.createDelegate(null, CloseDialog);
        }
        SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', options);
        return false;
    }
function CloseDialog(dialogResult, returnValue) {  //if user click on OK or Save
        if (dialogResult == SP.UI.DialogResult.OK) {
            //refresh parent page
            SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.RefreshPage', SP.UI.DialogResult.OK);
        }
            //if user click on close or Cancel
        else if (dialogResult = SP.UI.DialogResult.cancel) {
            // Do Nothing
        }
    }
<asp:HiddenField ID="hdnURL" runat="server" />

.cs File:
 protected void Page_Load(object sender, EventArgs e)
        {           
                string currentWeb = SPContext.Current.Web.Url;
                hdnURL.Value = currentWeb + "/Lists/List1/NewForm.aspx";               
                Bind_Items();         
        }

Wednesday, 23 July 2014

Checking if Sharepoint SP group exists?

//Check if a group exists in a website
var groupInWeb = GroupExistsInWebSite(SPContext.Current.Web, "MyGroupName");

//Check if a group exists in a site collection
var groupInSite = GroupExistsInSiteCollection(SPContext.Current.Web, "MyGroupName");

private  bool GroupExistsInWebSite(SPWeb web, string name)
{
    return web.Groups.OfType<SPGroup>().Count(g => g.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) > 0;
}
private bool GroupExistsInSiteCollection(SPWeb web, string name)
{
    return web.SiteGroups.OfType<SPGroup>().Count(g => g.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) > 0;
}

Tuesday, 8 July 2014

Building a Better SPGridView C#

Attachment: SmartSPGridView.zip
Sometimes with SharePoint customizations, you run into a scenario where you want to do something that is “just like this OOTB thing, but a little bit different.” Sometimes, that turns out to be trivial. Sometimes it turns out to be a fair amount of work to get what you want. SPGridView is one the latter – sounds great, but takes more work than I’d like to be at feature-parity with the less generic components.
Recently, I had two different projects that wanted something that looked like a ListViewWebpart, but had a more complex data source than a simple view on a list (both involved fetching data from multiple sites within the site collection and joining it to a couple of other lists). Seems simple enough, right? Fetch the data needed from all the source lists (and/or cross-site queries via SPSiteDataQuery) into custom objects, join them together via LINQ-to-Objects, stick the results in a DataTable, display it with SPGridView, and off to the next task, right? Well, yes. It does look right, but sorting and filtering don’t work. Even when you add ObjectDataSource to the mix, there are issues with sorting and filtering getting in each other’s way.
After a bit more digging online, I found a few sources that pointed me in the right direction of what I’d need to do to make it all work:
With these, plus a bit of tinkering, I got it to work like my first client wanted. However, I had to do a lot more work than I wanted to make it happen – until the last piece was in place, it wouldn’t work quite right. Two weeks later, I had another client ask me for almost the same thing (obviously, the data involved was quite a bit different, but the basic idea was the same – custom data fed into a table that looks like a normal SharePoint one). Since I’m a heavy opponent of “reuse by copy and paste”, I thought I’d separate out the “fixes” to the SPGridView from the particulars of this implementation and build a control I could use in the future when this kind of scenario came up.
In my mind, the developer wanting to use this control should only have to provide the information relevant to the problem domain (data, columns) and leave the implementation details (wiring sorting/filtering to work and work together) up to the control. To that end, I present SmartSPGridView:
     using System;     using System.Collections.Generic;     using System.Text;     using Microsoft.SharePoint.WebControls;     using System.Web.UI.WebControls;     using System.Data;     using System.Web.UI;          namespace SPGridDemo    {         /// <summary>        /// Wraps up everything needed for automatic sorting and filtering.           /// </summary>         public class SmartSPGridView : WebControl, INamingContainer        {
            public SmartSPGridView()             {                 // initialize the ObjectDataSource and SPGridView, wire them together and hook in the needed event handlers                 DataSource = new ObjectDataSource()                 {                     SelectMethod = "SelectData",                     TypeName = this.GetType().AssemblyQualifiedName,                     ID="DS",                 };                 GridView = new SPGridView()                 {                    AllowSorting = true,                     AllowFiltering = true,                     AutoGenerateColumns = false,                     FilteredDataSourcePropertyName = "FilterExpression",                     FilteredDataSourcePropertyFormat = "{1} = '{0}'",                     ID="view",                 };                 GridView.DataSourceID = DataSource.ID;                 DataSource.ObjectCreating += new ObjectDataSourceObjectEventHandler(DataSource_ObjectCreating);                 DataSource.Filtering += new ObjectDataSourceFilteringEventHandler(DataSource_Filtering);                 GridView.Sorting += new GridViewSortEventHandler(GridView_Sorting);                 GridView.RowDataBound += new GridViewRowEventHandler(GridView_RowDataBound);             }                  public SPGridView GridView { get; private set; }             public ObjectDataSource DataSource { get; private set; }     
           /// <summary>            /// Add filter header pieces             /// </summary>             void GridView_RowDataBound(object sender, GridViewRowEventArgs e)             {                 if (sender == null || e.Row.RowType != DataControlRowType.Header)                 {                     return;                 }                      SPGridView grid = sender as SPGridView;                     if (String.IsNullOrEmpty(grid.FilterFieldName))                 {                     return;                 }                      // Show icon on filtered column                 for (int i = 0; i < grid.Columns.Count; i++)                 {                     DataControlField field = grid.Columns[i];                          if (field.SortExpression == grid.FilterFieldName)                     {                         Image filterIcon = new Image();                         filterIcon.ImageUrl = "/_layouts/images/filter.gif";                        filterIcon.Style[HtmlTextWriterStyle.MarginLeft] = "2px";                              // If we simply add the image to the header cell it will                         // be placed in front of the title, which is not how it                         // looks in standard SharePoint. We fix this by the code                         // below.                         Literal headerText = new Literal();                         headerText.Text = field.HeaderText;                              PlaceHolder panel = new PlaceHolder();                         panel.Controls.Add(headerText);                         panel.Controls.Add(filterIcon);                              e.Row.Cells[i].Controls[0].Controls.Add(panel);                              break;                     }                 }             }     
            void GridView_Sorting(object sender, GridViewSortEventArgs e)             {                 // sorting loses the FilterExpression, so we have to restore it                 if (ViewState["FilterExpression"] != null)                 {                    DataSource.FilterExpression = (string)ViewState["FilterExpression"];                }            }                void DataSource_Filtering(object sender, ObjectDataSourceFilteringEventArgs e)            {                // save the filter expression built when we add a filter, so we can restore it when sort blows it away                ViewState["FilterExpression"] = ((ObjectDataSourceView)sender).FilterExpression;            }               protected override void LoadViewState(object savedState)            {                base.LoadViewState(savedState);                   // clear the saved filter so we don't restore it if the user sorts                if (Context.Request.Form["__EVENTARGUMENT"] != null &&                    Context.Request.Form["__EVENTARGUMENT"].EndsWith("__ClearFilter__"))                {                    // Clear FilterExpression                    ViewState.Remove("FilterExpression");                }            }    
           void DataSource_ObjectCreating(object sender, ObjectDataSourceEventArgs e)            {                // called by the ObjectDataSource to create an instance of this object                e.ObjectInstance = this;           }                protected override void CreateChildControls()            {                // add the ObjectDataSource and SPGridView as children               base.CreateChildControls();                this.Controls.Add(DataSource);                this.Controls.Add(GridView);            }                protected override void OnLoad(EventArgs e)            {                base.OnLoad(e);                this.EnsureChildControls();            }                public DataTable SelectData()            {                var e = new GetDataEventArgs();               OnGetData(e);                return e.DataTable;            }    
           #region GetData event+args            public class GetDataEventArgs : EventArgs            {                public DataTable DataTable { get; set; }            }            public event EventHandler<GetDataEventArgs> GetData;            protected virtual void OnGetData(GetDataEventArgs e)            {                EventHandler<GetDataEventArgs> eh = GetData;               if (null != eh)                {                    eh(this, e);                }            }            #endregion        }    }

Basically, it’s a UserControl with an ObjectDataSource and SPGridView wired together and with the events needed to get full sorting/filtering working already in place. To use this, all you have to do in your webpart is:
  • Create an instance of SmartSPGridView
  • Hook the GetData event and supply the DataTable
  • Call DataBind() at the appropriate time (OnPreRender works well)
  • Configure and add the view to your webpart (usually in CreateChildControls)
    • Add the columns
    • Populate the FilterDataFields property
    • Add the view to the webpart’s Controls collection
ObjectDataSource makes sorting work, FilterDataFields makes filtering work, and several event handlers keep them from tripping over each other. And, I don’t have to keep fighting the same battle every time I need this kind of solution for a project. Now, I’m off to pick another fight with Sharepoint.
The downloadable version of the code is linked below.