Blog of Sundar Narasiman

Overview of ASP.NET MVC Views and HTML Helpers

In ASP.NET web forms the request to an URL goes to a physical file on the web server. In ASP.NET MVC application the request to an URL does not represent a physical file, rather it invokes a method in a class (controller action). A controller action in an ASP.NET MVC application typically returns a View most of the times, however it can also perform other actions like returning a file or re-directing to another controller action.

A sample Controller action looks like below

http://serverurl/ControllerName/ActionName

http://serverurl/Home/Index

Home is the default controller that we will get when we create an ASP.NET MVC application in Visual Studio. Index is the default controller action that comes default in Visual Studio.

ASP.NET MVC framework works based on certain conventions. For every controller a sub-folder gets created under Views. For every controller action, a .cshtml file gets created under the respective sub-folder inside Views folder.

Now let’s move to understand HTMLHelpers. ASP.NET web forms have server controls which is used for data entry and UI form processing. In ASP.NET MVC we don’t have server controls, we need to rely on HTML Controls for data entry and UI form processing.

1. BeginForm

The BeginForm helper method denotes the start of an HTML form and it renders an HTML form element. The BeginForm method has 13 overrides and the i’m using the following  version of override in this post

   @using (Html.BeginForm("Index", "Home", FormMethod.Post))
        { 
        
        }

2.RadioButton helper

The Radio button helper helps us to render a RadioButton control. It can be bounded to a model property, which also can be set with values and group for the RadioButton.

 Male @Html.RadioButtonFor(model => model.Sex,"Male")
                Female @Html.RadioButtonFor(model => model.Sex, "Female")

3.Textbox helper

The @Html.EditorFor helper supports us to render a TextBox control for data capture. It can be bound to a model property.

        @Html.EditorFor(model => model.Age)

4.DropDownListControl

The @Html.DropDownListfor helper control supports us to render a dropdownlist control. It can be databound to a IEnumerable>T> which needs to be type casted as SelectList, while performing data binding.

 @Html.DropDownListFor(model => model.PolicyType, ViewData["PolicyType"] as SelectList)

5.CheckBox Control

The @Html.CheckBox control support us to to render a CheckBox control. It can be data bound to a boolean property in the Model.

@Html.CheckBoxFor(model=>model.ReceiveMails)

6.Label Control

The @Html.Label control supports us to render a Label control, whose literal value is bound from a string property in the Model.

 @Html.LabelFor(model => model.Age, new { @class = "control-label col-md-2" })

 

7. ActionLink Control

The @Html.ActionLink control supports us to link to an action method in a controller when the link is clicked.

  @Html.ActionLink("Back to List", "Index")

With the above briefing, i will be creating a View to capture the details for generating an InsuranceQuotation. The Model object definition looks like below :-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MVCDemo2.Models
{
    public class InsurancePolicy

    {

        public string FirstName { get; set; }
        public string LastNane { get; set; }
        public int Age { get; set; }
        public string Sex { get; set; }
        
        public string PolicyType { get; set; }

        public int PolicyTerm { get; set; }
        public int SumAssured { get; set; }

        public bool ReceiveMails { get; set; }


    }
}

My end goal is to create a View (shown below) to capture the details for generating Quotation.

image

The definition of my View ‘GenerateQuote.cshmtl’ looks like below :-

@model MVCDemo2.Models.InsurancePolicy

@{
    ViewBag.Title = "GenerateQuote";
}

<h2>GenerateQuote</h2>



@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>InsurancePolicy</h4>
        <hr />
        @Html.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LastNane, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LastNane)
                @Html.ValidationMessageFor(model => model.LastNane)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Age, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Age)
                @Html.ValidationMessageFor(model => model.Age)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Sex, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                Male @Html.RadioButtonFor(model => model.Sex,"Male")
                Female @Html.RadioButtonFor(model => model.Sex, "Female")
                @Html.ValidationMessageFor(model => model.Sex)
            </div>
        </div>

        

        <div class="form-group">
            @Html.LabelFor(model => model.PolicyType, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.PolicyType, ViewData["PolicyType"] as SelectList)
                @Html.ValidationMessageFor(model => model.PolicyType)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PolicyTerm, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.PolicyTerm)
                @Html.ValidationMessageFor(model => model.PolicyTerm)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.SumAssured, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.SumAssured)
                @Html.ValidationMessageFor(model => model.SumAssured)
            </div>
        </div>

        <div class="form-group">

            @Html.LabelFor(model=>model.ReceiveMails)
            @Html.CheckBoxFor(model=>model.ReceiveMails)
           
        </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

This completes this article. My next post on ASP.NET MVC is here.

 Subscribe to my blog

Various options of passing data from ASP.NET MVC Controller to View

In ASP.NET MVC framework, we have got various options for passing data from Controller to View. Some of the options that i know and used are listed below :-

1. Use a strongly typed model object

2. Use a dynamic type (using @model syntax)

3.Use a ViewBag

This article focuses on explaining the above three methods of passing data from Controller to View.  Let’s create a simple ASP.NET MVC application to demo this one. Since there is a Cricket world cup fever going now, i will be creating a sample MVC application to display list of countries.

I’m adding the below model to the project

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; 

namespace MVCDemo1.Models
{
    public class Countries
    { 

        public String Name { get; set; }
        public string Group { get; set; }
        public string DressColor { get; set; }
        public int NoOfTropies { get; set; }
    }
} 

I’ll be creating a new controller by name Country to handle various types of views(strongly typed views, loosely typed views and views accessing viewbag objects directly for the model Countries.

In the CountryController.cs, i’m setting up the values for CountryCollection

List<Countries> oCountries = new List<Countries> { 
        new Countries{Name="India",NoOfTropies=2,Group="A",DressColor="Blue"},
        new Countries{Name="Australia",NoOfTropies=3,Group="B",DressColor="Yellow"},
        new Countries{Name="SouthAfrica",NoOfTropies=0,Group="C",DressColor="Purple"}

        };

1.Use a strongly typed model object to pass data from Controller to View

In this approach, I’m adding a Controller action by name ‘StrongView’ to return the View for ActionResult.

public ActionResult StrongView()
        {

            return View(oCountries);

        }

Right click on the controller action and Add a View by choosing the Model class, which makes it a Strongly typed view.

image

Run the Solution and the View with CRUD operations look like below.

image

At the top of the View, model is referenced strongly which makes it Strongly typed View.

@model IEnumerable<MVCDemo1.Models.Countries>

Now, let’s move to the approach #2.

 

2. Use a dynamic type (@model syntax) to pass data from Controller to View

Let’s add another controller action by name ‘LooseView’ for passing loosely typed objects from Controller to View.

 public ActionResult LooseView()
        {

            return View(oCountries);
        
        }

Right click on the Controller action, Add View and do not choose any model class, that will make it as dynamically typed.

image

At the top of the View add a reference to dynamically typed view and Grab the Model data from dynamic object.

@model dynamic
@{
    ViewBag.Title = "LooseView";
}

<h2>LooseView</h2>

@foreach(var oCountry in Model)
{
    @oCountry.Name;
}

image

Now let’s move to the approach #3.

3. Use ViewBag to pass the data from Controller to View

Now let’s add a Controller action by name ‘ThirdView’ which sets the Country Collection and returns the View.

  public ActionResult ThirdView()
        {
            ViewBag.Countries = oCountries;
            return View();

        }

Let’s add a View by name ‘ThirdView’

image

I’ll be fetching the Model object from ViewBag and rendering it in the View.

@{
    ViewBag.Title = "ThirdView";
}

<h2>ThirdView</h2>

@foreach (var oCountry in ViewBag.Countries)
{
    @oCountry.Name;
}

image

 Subscribe to my blog

How to get list items in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can fetch the list items of a SharePoint list in SharePoint 2013 online using REST. For the purpose of demonstration, I’ll be using a SharePoint hosted app.

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and name it as ‘GetListItemsREST’

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint.com/_api/web/lists/GetByTitle(‘Shared%20Assets’)/items.

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered.

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>
  

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given full-control permission for site-collection. Otherwise, it will not be able to fetch the fields collection.

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" />
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Read" />
  </AppPermissionRequests>

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’

var executor = new SP.RequestExecutor(AppWebUrl);

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/lists/GetByTitle('Site%20Assets')/items?@target='" + HostWebUrl

Open the App.js and paste the following code

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});


function successHandler(data) {

    var jsonObj = JSON.parse(data.body);
    var results = jsonObj.d.results;
    var resultcount = results.length;
    var finalresult;

    var i;
    var tempobject;


    for (i = 0; i < resultcount - 1; i++)
    {
        tempobject = results[i];
        finalresult = finalresult+ "Item title is" + tempobject["Title"] + "Item id is " + tempobject["Id"];
        
    }
   
    document.getElementById("message").innerText = finalresult;
  

   
    
   
    
}



function errorHandler(data, errorCode, errorMessage) {


    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);

    executor.executeAsync({
        url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/lists/GetByTitle('Site%20Assets')/items?@target='" + HostWebUrl + "'",
        method: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            
        },
        success: successHandler,
        error: errorHandler
    });

}

Run the above piece of code and you will be see the below result.

image

 Subscribe to my blog

How to get a SharePoint group in SharePoint 2013 Online using REST

In this post, we’ll see how to get a SharePoint Group in SharePoint Online using REST. I’ll be using a SharePoint hosted app for the purpose of demonstration.

Launch Visual Studio 2013.

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint/_api/web/sitegroups(index)

index – an integer that refers a group uniquely in the site.

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered.

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given the following permission.

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" />
  </AppPermissionRequests>

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’.

var executor = new SP.RequestExecutor(AppWebUrl);

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/sitegroups(index)?@target='" + HostWebUrl + "'",

e)Copy and paste the following code in the App.js (replace Ii t the existing code over there)

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});


function successHandler(data) {

    var jsonObj = JSON.parse(data.body);
    var results = jsonObj.d;
    document.getElementById("message").innerText = "Field title is" + results["Title"] + "Field Id is" + results["Id"];

}

function errorHandler(data, errorCode, errorMessage) {


    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);

    executor.executeAsync({
        url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/sitegroups(3)?@target='" + HostWebUrl + "'",
        method: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose"
        },
        success: successHandler,
        error: errorHandler
    });

}

Run the above piece of code, now you will be able to get the title and id for the site collection group (no: 3).

image

 Subscribe to my blog

 

How to get SharePoint fields collection in SharePoint 2013 Online using REST

In this post, we’ll see how we can fetch the fields collection of a SharePoint web in SharePoint 2013 online using REST. For the purpose of demonstration, I’ll be using a SharePoint hosted app.

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and name it as ‘GetFieldsREST’

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint/_api/web/fields

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>
  

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given full-control permission for site-collection. Otherwise, it will not be able to fetch the fields collection.

 <AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
  </AppPermissionRequests>

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’

var executor = new SP.RequestExecutor(AppWebUrl);

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/fields?@target='" + HostWebUrl + "'",

Open the App.js and paste the following code

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});


function successHandler(data) {

    var jsonObj = JSON.parse(data.body);
    var results = jsonObj.d;
    document.getElementById("message").innerText = "Field title is" + results["Title"] + "Field Id is" + results["Id"];

}

function errorHandler(data, errorCode, errorMessage) {


    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);

    executor.executeAsync({
        url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/fields?@target='" + HostWebUrl + "'",
        method: "POST",
        body: "{ '__metadata': { 'type': 'SP.Field' }, 'Title': 'Comments', 'FieldTypeKind': 3 }",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose"
        },
        success: successHandler,
        error: errorHandler
    });

}

image

This completes this demo.

 Subscribe to my blog

How to get SharePoint 2013 web property using REST in SharePoint Online

In this post, we’ll see how we can access the property of a SharePoint web in SharePoint 2013 online using REST. For the purpose of demonstration, I’ll be using a SharePoint hosted app.

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and and name it as ‘GetWebdetailsREST’

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint/_api/web/title

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>
  

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given read permission for site-collection

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />
  </AppPermissionRequests>

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’

var executor = new SP.RequestExecutor(AppWebUrl);

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/title?@target='" + HostWebUrl + "'",

Open the App.js and paste the following code

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});

// This function prepares, loads, and then executes a SharePoint query to get the current users information
function getUserName() {
   
}



function successHandler(data)
{
    
    var jsonObj = JSON.parse(data.body);
    document.getElementById("message").innerText = "Web title from REST call is"+ jsonObj.d["Title"];

}

function errorHandler(data, errorCode, errorMessage) {
   

    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);
    executor.executeAsync(
        {
            url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/title?@target='" + HostWebUrl + "'",
            type: "GET",
            crossDomain:true,

            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/json;odata=verbose",
                "content-length": 1028,
                "X-RequestDigest": $("#__REQUESTDIGEST").val()

            },
            success: successHandler,
            error: errorHandler
        }
        );

}

image

Now you can see the updated site title in the App. This completes this demo.

 Subscribe to my blog

How to setup multi-factor authentication in Office 365

In this post, we’ll see how we can enable multi-factor authentication for Office 365. The concept of multi-factor authentication has be become increasingly popular nowadays for bringing the additional layer of security hardening. Multi-factor authentication is a form of authentication, which enforces more than one form of authentication to verify the legitimacy of the transactions performed by a user. Nowadays, the most common form of second-form of authentication in to validate the Authorization code by sending it to the user’s mobile devices.

Let’s see the steps to enable multi-factor authentication in Office 365.

Log in to Office 365 admin portal, go to Users –> Active Users.

image

Click setup and you will be presented with the following screen.

image

Click ‘Enable’ link on the bottom right and the following screen will pop-up.

 

image

Click ‘enable multi-factor auth’.

Now you will get a confirmation that multi-factor authentication is enabled for selected accounts.

When I log in next time, it asks for me to setup the second form of authentication.

image

Click ‘Set it up now’.

image

It sends a 6 digit verification code to the registered mobile number. You are all set for multi-factor authentication enabled Office 365 tenant. This wraps up my quick how-to article.

At this point of time, the multi-factor authentication is available for Office 365 Midsize Business, Enterprise plans, Academic plans, Nonprofit plans, and standalone Office 365 plans, including Exchange Online and SharePoint Online. It is not available for Office 365 Small Business and Office 365 Dedicated plans as of now. The detailed Faqs about multi-factor authentication is available here. 

 Subscribe to my blog

Understanding App Only Permission policy in SharePoint 2013 App model

In this post, we’ll understand what is an App Only Permission policy in SharePoint 2013 App model with a sample app project. The SharePoint 2013 App permissions are of three types and they are as follows :-

  • App Only
  • User Only
  • App+User

When the logged in user does not have enough privileges to perform a certain action or set of actions, the App Only permission comes into picture. The App can elevate its permission using the App Only permission or context. A SharePoint 2013 App configured with App Only permission or context can only installed by the site-collection administrator at this point of time.

I’ll be using a Provider hosted app for the purpose of this demonstration. I have a user called ‘User A’ who does not have permission to modify the Title of SharePoint lists in the site-collection. I will be using App Only context to elevate the App’s permission and change the List Title.

I have a list called ‘Announcements’ and I will be changing its Title using App Only permission or context.

image

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and name it as ‘AppOnlyContextApp’

Select the app hosting type as Provider hosted apps.

In order to update the Title of the SharePoint List (at the root of the site-collection), provide the Full Control to Site-Collection.

image

Set App Only permission in the AppManifest.XML file

<?xml version="1.0" encoding="utf-8" ?>
<!--Created:cb85b80c-f585-40ff-8bfc-12ff4d0e34a9-->
<App xmlns="http://schemas.microsoft.com/sharepoint/2012/app/manifest"
     Name="AppOnlyContext"
     ProductID="{b5e637d0-8a34-498c-b8cf-c40b3d0e9ef3}"
     Version="1.0.0.0"
     SharePointMinVersion="15.0.0.0"
>
  <Properties>
    <Title>AppOnlyContext</Title>
    <StartPage>~remoteAppUrl/Pages/Default.aspx?{StandardTokens}</StartPage>
  </Properties>

  <AppPrincipal>
    <RemoteWebApplication ClientId="*" />
  </AppPrincipal>
  <AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
  </AppPermissionRequests>
</App>

Copy and paste the following code for the default.aspx.cs file and I have added the necessary logic in the page_load method to update Title of a particular list.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AppOnlyContextWeb
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_PreInit(object sender, EventArgs e)
        {
            Uri redirectUrl;
            switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))
            {
                case RedirectionStatus.Ok:
                    return;
                case RedirectionStatus.ShouldRedirect:
                    Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);
                    break;
                case RedirectionStatus.CanNotRedirect:
                    Response.Write("An error occurred while processing your request.");
                    Response.End();
                    break;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // The following code gets the client context and Title property by using TokenHelper.
            // To access other properties, the app may need to request permissions on the host web.
            var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);

            using (var clientContext = spContext.CreateUserClientContextForSPHost())
            {
         
                //Load the sharepoint web
                clientContext.Load(clientContext.Web, web => web.Title);
                clientContext.ExecuteQuery();
                Response.Write(clientContext.Web.Title);

                //Load the list-collection in the sharepoint web
                clientContext.Load(clientContext.Web.Lists);                
                clientContext.ExecuteQuery();

                //Change the title of announcment list to some arbitrary title
                clientContext.Web.Lists[1].Title = "SundarAnnouncements";
                clientContext.Web.Lists[1].Update();
                clientContext.ExecuteQuery();


            }
        }
    }
}

Hit F5 and run the App in Visual Studio. Now we can verify the elevation of App permission by using App Only policy, by validating the change in List title.

image

 Subscribe to my blog

Visual Studio 2013 Update3 released

Visual Studio 2013 Update3 was released on 04’th August 2014. The update3 has got the following important components.

a)Azure SDK 2.4

b)Windows Phone 8.1 update

c) Multi-device Hybrid Apps CTP 2.0

More details are found in Somasegar’s blog http://blogs.msdn.com/b/somasegar/archive/2014/08/04/visual-studio-2013-update-3.aspx

How to get list of Fields in a SharePoint List in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can get the list of Fields in a SharePoint List in SharePoint 2013 Online using CSOM. I’ll be using a Console application for the purpose of demonstration.

Open Visual Studio 2013.

File –> New Project –> Visual C# –> Console Application and name it as ‘GetFieldsCSOM’

Add a reference to the ‘Microsoft.SharePoint.Client’ and ‘Microsoft.SharePoint.Client.Runtime’ assemblies

Import the following namespaces

using Microsoft.SharePoint.Client;
using System.Security;

The following code will invoke the GetbyTitle method of Lists class and access the Fields property collection.

namespace GetFieldsCSOM
{
    class Program
    {
        
        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

        static void Main(string[] args)
        {
            //Replace it with the url of your tenant or your site-collection
            string SiteUrl = "https://yoursite.sharepoint.com";
            System.Uri oUri = new System.Uri(SiteUrl);
            using (ClientContext oClientContext = new ClientContext(SiteUrl))
            {
                //Replace it with your user id for SharePoint Online
                string UserName = "userid@yoursite.onmicrosoft.com";
                //Replace it with your password
                string Password = "password";
                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);
                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);
                oClientContext.Load(oClientContext.Web.Lists.GetByTitle("TestList").Fields);
                oClientContext.ExecuteQuery();
                FieldCollection oFieldCollection = oClientContext.Web.Lists.GetByTitle("TestList").Fields;

                foreach(Field oField in oFieldCollection)
                {
                    Console.WriteLine(oField.Title);
                
                }
                Console.ReadLine();
            }
        }
    }
}

image

 Subscribe to my blog