Tag Archives: Mobile

One design to rule them all – Responsive design

In the last few years, the use of mobile devices to surf the web has increased significantly.

According to some researchers, by 2015, more mobile devices than desktop computers will be used to access the web. Mobile devices come in different sizes and capabilities. And since the desktop experience just isn’t good for mobile users, what are the options for improving the experience of mobile users on your website?

Improving the user experience across devices

Optimizing the user experience of a website across different devices is a complex process. Not only do you have to take into account the screen resolution of each device, but you also need to consider its capabilities (such as touch or pointer-based) and device size (1024×768 might be clearly readable for everyone on a 20-inch monitor but might result in a very bad experience on a 5-inch screen).

When you are planning improvements to the user experience of your website on mobile devices, there is no silver bullet approach. You have to research who your users are, which devices they use, and what they are trying to achieve on your website.

You also have to have clear goals for what purpose your website serves and how it should guide your visitors in the process of becoming your customers.

You have several options for improving the user experience of a public-facing website. Which one you choose depends on the different factors that apply to your scenario.

Mobile websites

In the past, when the web technology wasn’t as sophisticated as it is nowadays, it was a common practice to provide mobile users with a separate mobile website to optimize their experience. Being hosted on a separated URL, such as http://m.contoso.com, the mobile site would have a user experience optimized for mobile devices.

In some scenarios, organizations would even go a step further and optimize the copy on the mobile website. When a user navigated to the website using a mobile device, the main website would detect the use of a mobile device and automatically redirect the visitor to the mobile version.

It’s not that hard to imagine that building and maintaining two different sites is not only costly but also time consuming. Every update has to be done separately. Even then, with the diversity of today’s mobile devices, the questions remain whether a single mobile website would suffice and whether you wouldn’t need more websites to reach the whole spectrum of your customers.

Being able to reuse the content across the main and mobile websites simplifies the content management process. But the need to separately maintain the functionality of both websites makes it hard to justify this approach in most scenarios.

Mobile apps

One of the recent developments of the mobile market is the increased popularity of companion apps. By using the native capabilities of specific devices, you can build rich mobile apps to support different use cases. There is no better user experience on a mobile device than the native one offered by the device itself. For more information, see Build mobile apps for SharePoint 2013.

But is it realistic to build separate apps for all the different scenarios and for all the different mobile devices used to navigate the website? Although mobile apps are of great value for supporting specific use cases, there is still the need to access the information on the website from a mobile device in a user-friendly way.

Responsive web design

Instead of building separate mobile sites for mobile devices, what if we could have one website that automatically adapts itself to the particular device?

Responsive web design is a concept based on the ability to separate the design from the content on a website. Using the CSS media queries capability implemented in all modern browsers, and based on the screen dimensions of the specific device, you can load different style sheets to ensure that the website is presented in a user-friendly manner. And because CSS has its limitations, you can use JavaScript to further optimize the interface and interaction of a website on mobile devices. For more information, see Implementing your responsive designs on SharePoint 2013.

From the search engine optimization (SEO) perspective, responsive web design is the recommended way to optimize public-facing websites for mobile devices. After all, since the same HTML is sent to every device, it’s sufficient for an Internet search engine to index the content once, and it can be sure that the search results will apply the search query on every device.

Implementing responsive web design on a public-facing website is relatively easy assuming you start planning for it from the beginning. The great advantage of responsive web design above other approaches is that you maintain your website once to support a variety of audiences, and the different experiences are future-proof as they depend on the devices’ dimensions rather than their identity.

The following figures show how the sample Contoso Electronics website is displayed on different devices using responsive web design. Figure 1 shows the screen shot taken on a desktop device.

Figure 1. The Contoso Electronics website displayed on a desktop deviceFigure 1. The Contoso Electronics website displayed on a desktop device

Figure 2 shows how the Contoso Electronics website looks like on different mobile devices.

Figure 2. The Contoso Electronics website displayed on mobile devicesFigure 2. The Contoso Electronics website displayed on mobile devices

SharePoint 2013 device channels

One of the new capabilities of SharePoint 2013 is device channels. You can use device channels to optimize how a website is displayed on different devices. By defining different channels and associating different devices with them, you can use different master pages to optimize how the website is presented to the user.

Figure 5 shows a sample configuration of device channels for a public-facing website built with SharePoint 2013.

Figure 3. Device channels configured for a public-facing website built on SharePoint 2013Figure 3. Device channels configured for a public-facing website built on SharePoint 2013

Whereas responsive web design uses a device’s screen size to determine the presentation layer, device channels in SharePoint 2013 use the identity of the browser on the particular device to decide which presentation style to use.

Depending on how many different devices your site visitors use, managing the different devices and experiences can become complex. By using device channels, you get more flexibility in controlling the markup of your website for the different devices. Another benefit of using device channels is that you can serve different content to different devices, whereas the same content is served when using responsive web design. With device channels, you can apply additional optimizations to your website, such as resizing images and videos server-side using the renditions capability, which further improves the performance and user experience of your website. For more information, see How to: Manage image renditions in SharePoint 2013.

With all the different options at our disposal, which one should we use to get the best results?

Improving the user experience of a public-facing website in SharePoint 2013

First and foremost, it’s important to note that SharePoint 2013 supports all the methods mentioned above for improving user experience on mobile devices.

Whether you’re looking at building a separate website for mobile users, supporting certain use cases with a mobile app, implementing responsive web design, or using device channels, it can all be implemented in your website on top of SharePoint 2013.

Not only does SharePoint 2013 not stand in your way, but it also supports you in implementing some of those improvements.

For example, using the cross-site publishing capability, you can easily publish the centrally managed content on both the main and the mobile websites. With the Search REST API, you can have your content published in your mobile app, and if you’re looking at optimizing the presentation of your website across different devices, SharePoint 2013 offers plenty of features to help you.

With all these techniques at your disposal, it is up to you to decide which method, or combination of methods, is the best choice for what you’re trying to achieve. While you might be interested in supporting a particular complex process with a dedicated mobile app, it might still be of added value to ensure that everyone, regardless of their device, can access all the information on your website.

In most scenarios, it’s easy to choose whether or not the particular optimization technique offersadded value. A slightly more difficult choice, partly due to the similarity of both methods, is whether you should use responsive web design or device channels to optimize the presentation of your website for mobile devices.

Responsive web design and device channels comparison

Responsive web design and the SharePoint 2013 device channels capability are similar in how they let you optimize a single website to be displayed in a user-friendly way on different devices. Despite this similarity, there are a few important differences between both approaches. Table 1 presents a comparison of the different properties of both approaches.

Device channels Responsive web design
Device management Property management
Different HTML for every channel Same HTML for every device
More management (support for new devices) Future proof (device size)
More flexibility Limited by CSS support and capabilities
Custom Vary-By User Agent response header required Preferred by Internet search engines
Table 1. Comparison of device channels and responsive web design

Applying user experience

First of all, there is a difference in how both approaches determine which user experience should be applied for the particular user. Responsive web design uses the size of the screen to determine how the content should be laid out in the browser’s window. Device channels, on the other hand, use the identity of the browser to load the suitable channel.

While responsive web design can cause different experiences to be loaded depending on the size of the browser window, device channels will always load the same experience for the same device regardless of the browser window size. Using device channels can have great advantages, for example, from the troubleshooting point of view where the user and the helpdesk employee would see the same interface despite the possible differences in their screen resolutions or browser window sizes.

Page markup

Another difference between device channels and responsive web design is how the page contents are served. Responsive web design changes only the presentation layer of the website. Although you can hide some pieces of the page in the browser using CSS, they are still present in the website’s code and therefore loaded. When using device channels, you can use different master pages to ensure that only the relevant markup is served to users. Additionally, you can use the device channel panels to further control the content elements loaded on specific pages.

Although device channels allow for better control of the rendered HTML and therefore optimized performance of the website, more effort is required to ensure that Internet search engines will properly deal with all the different versions of the website presented to different devices. You can achieve this by using the Vary-By User Agent response header, but it has to be done manually.

Future-proofness

Responsive web design uses the size of the browser window to distinguish between the different experiences. This is a robust approach, and the chances are low that a new device will appear on the market that has a poor user experience despite the configured breakpoints. One reason for that might be related to some specific capabilities of such devices, but again, chances of this are very rare.

SharePoint 2013 device channels are based on the identity of the browser used to open the website. There are two challenges with this approach. First of all, in some situations it might be impossible to distinguish between the same browser installed on the same operating system but on two devices with distinct capabilities. Second, if a new device appears on the market, you would have to verify that this device is assigned to the right device channel on your website.

Choosing the right approach for optimizing the user experience

Although responsive web design and device channels are very similar, their capabilities differ and they have different impact when used for optimizing a website for mobile devices. Due to their similarities and their own strength, choosing between the two approaches is often difficult. Why not combine both approaches to get the best of what they offer?

Combining responsive web design and device channels

An interesting scenario worth considering is to combine responsive web design and SharePoint 2013 device channels to benefit from the strengths of both approaches.

When combining responsive web design and device channels, you could use responsive web design to create the baseline cross-device experience. Depending on your design for the different breakpoints, using responsive web design could be good for the 80%, or maybe even 90%, of the optimizations. The remainder—whether they’re caused by how the web design changes between the breakpoints or by the capabilities of the different devices that should be supported—could be covered by device channels and device channel panels.

By using responsive web design to build the baseline for the cross-browser experience, we benefit from its future-proofness and robustness. For the specific exceptions, we can benefit from the granular control that SharePoint device channels offer us.

Advertisements

Using jQuery Mobile and ASP.NET to Pass Data from one Page to another

ASP.NET developers working on either Web Forms or ASP.NET MVC can integrate jQuery Mobile into their Web sites to create rich mobile Web apps. jQuery Mobile is a lightweight JavaScript framework for developing cross-platform mobile/device Web applications.

In mobile application development, you as a developer must think about how to utilize available space in the best possible manner. For this purpose sometimes the UI needs to be divided in separate pages. In such cases, you may need to transfer value(s) entered in one page, on the second page for the further processing.

Consider a scenario where the end user is asked to select the Product Category on Page 1 and based upon that, Page 2 displays products under that category. To get this done, values must be passed from page 1 to page 2.

In jQuery Mobile, $.mobile object provides the changePage() method which accepts the page url as a first parameter and the values to be transferred as a second parameter using JSON based data. In this article, we will see, how values are passed from one page to another in an ASP.NET application.

Step 1: Open Visual Studio and create a new ASP.NET empty web application, name it as ‘ASPNET_Mobile_PassingValuesAcrossPages’. In this application, using the NuGet Package Manager, add the latest jQuery and jQuery Mobile libraries.

Step 2: To the project, add a new class file, name it as ‘ModelClasses.cs’ and add the following classes in it:

public class Category {     public int CategoryId { get; set; }     public string CategoryName { get; set; } }

public class Product {     public int ProductId { get; set; }     public string ProductName { get; set; }     public int Price { get; set; }     public int CategoryId { get; set; } }

public class CategoryDataStore : List<Category> {     public CategoryDataStore()     {         Add(new Category() { CategoryId = 1, CategoryName = “Food Items” });         Add(new Category() { CategoryId = 2, CategoryName = “Home Appliances” });         Add(new Category() { CategoryId = 3, CategoryName = “Electronics” });         Add(new Category() { CategoryId = 4, CategoryName = “Wear” });     } }

public class CategoryDataSource {     public List<Category> GetCategories()     {         return new CategoryDataStore();     } }

public class ProductDataStore : List<Product> {     public ProductDataStore()     {         Add(new Product() { ProductId = 111, ProductName = “Apples”, Price = 300, CategoryId = 1 });         Add(new Product() { ProductId = 112, ProductName = “Date”,   Price = 600, CategoryId = 1 });         Add(new Product() { ProductId = 113, ProductName = “Fridge”, Price = 34000, CategoryId = 2 });         Add(new Product() { ProductId = 114, ProductName = “T.V.”,   Price = 30000, CategoryId = 2 });         Add(new Product() { ProductId = 115, ProductName = “Laptop”, Price = 72000, CategoryId = 3 });         Add(new Product() { ProductId = 116, ProductName = “Mobile”, Price = 40000, CategoryId = 3 });         Add(new Product() { ProductId = 117, ProductName = “T-Shirt”, Price = 800, CategoryId = 4 });         Add(new Product() { ProductId = 118, ProductName = “Jeans”, Price = 700, CategoryId = 4 });     } }

public class ProductDataSource {     public List<Product> GetProductsByCategoryId(int catId)     {         var Products = from p in new ProductDataStore()                        where p.CategoryId == catId                        select p;

        return Products.ToList();     } }

The above code provides Category and Product entities with data stored in it. The Product is a child of the Category class.

Step 3: In the project, add a WEB API controller class with the following code:

public class CategoryProductController : ApiController {     CategoryDataSource objCatDs;     ProductDataSource objPrdDs;

    public CategoryProductController()     {         objCatDs = new CategoryDataSource();         objPrdDs = new ProductDataSource();     }

    public IEnumerable<Category> Get()     {         return objCatDs.GetCategories();     }

    public IEnumerable<Product> Get(int id)     {         return objPrdDs.GetProductsByCategoryId(id);     } }

Step 4: To define routing for the WEB API class, add a new Global Application Class (Global.asax) in the project and add the following code in the Application_Start method:

protected void Application_Start(object sender, EventArgs e) {     RouteTable.Routes.MapHttpRoute(     name: “DefaultApi”,     routeTemplate: “api/{controller}/{id}”,     defaults: new { id = System.Web.Http.RouteParameter.Optional }     ); }

Step 5: Add two HTML pages, name them as Page_Category.html and Page_Products.html.

Task 6: In both the HTML pages, add the jQuery and jQuery Mobile references:

<link href=”Content/jquery.mobile.structure-1.3.1.min.css” rel=”stylesheet” /> <link href=”Content/jquery.mobile.theme-1.3.1.min.css” rel=”stylesheet” /> <script src=”Scripts/jquery-2.0.2.min.js”></script> <script src=”Scripts/jquery.mobile-1.3.1.min.js”></script>

Add the following HTML in the Page_Category.html page:

<div data-role=”page” id=”catpage”>     <div data-role=”header”>         <h1>Select Category from List</h1>     </div>     <div data-role=”content”>         <div>             <select  id=”lstcat” data-native-menu=”false”>                 <option>List of Categories…..</option>             </select>         </div>         <br />         <br />         <input type=”button” data-icon=”search”            value=”Get Products”  data-inline=”true” id=”btngetproducts” />     </div> </div>

The above code defines a page using <div>  whose data-role attribute is set to page. This page contains a <select> for displaying list of categories in it and an <input> button with a click event on which the control will be transmitted to Page_Products.html page.

In the age_Category.html add the following script. The method loadlistview will make a call to WEB API and retrieve categories. These categories will be added into the <select> with id as lstcat. This method will be executed when the pageinit event is executed. On the click event of the button, the Category Value and Name will be passed to the Page_Products.html.

<script type=”text/javascript”> $(document).on(“pageinit”, “#catpage”, function () {

//Pass the data to the other Page $(“#btngetproducts”).on(‘click’, function () {     var categoryId = $(“#lstcat”).val();     var categoryName = $(“#lstcat”).find(“:selected”).text();     $.mobile.changePage(“Page_Products.html”, { data: { “catid”: categoryId ,”catname”:categoryName}}); });

loadlistview();

///Function to load all categories function loadlistview() {         $.ajax({         type: “GET”,         url: “/api/CategoryProduct”,         contentType: “application/json; charset=utf-8”,         dataType: “json”     }).done(function (data) {         //Convert JSON into Array         var array = $.map(data, function (i, idx) {             return [[i.CategoryId, i.CategoryName]];         });

        //Add each Category Name in the ListView         var res = “”;         $.each(array, function (idx, cat) {             res += ‘<option value=”‘ + cat[0] + ‘”>’ + cat[1] + ‘</option>’;         });         $(“#lstcat”).append(res);         $(“#lstcat”).trigger(“change”);

    }).fail(function (err) {         alert(“Error ” + err.status);     }); } }); </script>

Just look at this piece of code:

$.mobile.changePage(“Page_Products.html”, { data: { “catid”: categoryId ,”catname”:categoryName}});

This code is responsible for passing the CategoryId and Name using JSON expression to the Page_Products.html.

Step 7: Open Page_Products.html and add the following HTML markup:

<div data-role=”page” id=”prodpage” data-add-back-btn=”true”> <div data-role=”header”>         <h1>Products in Category</h1>         <span id=”catName”></span>     </div>          <table style=”border:double” data-role=”table” id=”tblprd”>         <thead>             <tr>                 <td style=’width:100px’>                     ProductId                 </td>                 <td style=’width:100px’>                     ProductName                 </td>                 <td style=’width:100px’>                     Price                 </td>             </tr>         </thead>         <tbody>         </tbody>     </table> </div>

Here the <div> with id as prodpage is set with the attribute as data-role=page. The attribute data-add-back-btn=true, will add the BACK button on the page. On click of this button, we can move back to the Page_Category.html. This is the default style set in jQuery Mobile.

Now here the important thing is how to read values which are send from Page_Category.html in the URL, on the Page_Product.html page. Unlike ASP.NET, in jQuery there is no simple way to read the values passed from one page to another. To read these values we will create a readUrlHelper helper method. This method reads the URL and using JavaScript string functions, reads the Key/Value pairs passed from the Page_Category.html. On the Page_Products.html, add this method using <script> inside the page created using <div> with id as prodpage.

//This helper function will read the URL as //string and provides values for parameters //in the URL function readUrlHelper(pageurl, queryParamName) {     var queryParamValue = “”;

    //Get the Total URL Length     var stringLength = pageurl.length;

    //Get the Index of ? in URL     var indexOfQM = pageurl.indexOf(“?”);

    //Get the Lenght of the String after ?     var stringAfterQM = stringLength – indexofQM;

    //Get the remaining string after ?     var strBeforeQM = pageurl.substr(indexofQM + 1, stringAfterQM);

    //Split the remaining String based upon & sign     var data = strBeforeQM.split(“&”);

    //Iterate through the array of strings after split     $.each(data, function (idx, val) {         //Split the string based upon = sign         var queryExpression = val.split(“=”);

        if (queryExpression[0] == queryParamName)         {             queryParamValue = queryExpression[1];             //If the Query String has Data in Concatination then replace the             //’+’ by blank space ‘ ‘             queryParamValue =  queryParamValue.replace(‘+’, ‘ ‘);         }     });

    return queryParamValue

}

To retrieve the Products based upon the CategoryId, add a new method loadproducts inside the prodpage. This methods makes a call to the WEB API service and passes the CategoryId. This method also makes a call to the generatetable helper method to generate HTML table to display products in it based upon the JSON data received by the loadproducts method:

//Method to make call to WEB API and retrieve //Products based upon the CategoryId. function loadproducts(id) {

    $.ajax({         type: “GET”,         url: “/api/CategoryProduct/” + id,         contentType: “application/json; charset=utf-8″,         dataType: “json”     }).done(function (data) {         generatetable(data);     }).fail(function (err) { }); } //Method to generate HTML table rows from the JSON data function generatetable(data) {

    //Convert JSON into Array     var array = $.map(data, function (i, idx) {         return [[i.ProductId, i.ProductName,i.Price]];     });     var tblbody = $(“#tblprd > tbody”);

    var tblhtml = “”;     //Generate the Table for each Row     for (var i = 0; i < array.length; i++) {         tblhtml = tblhtml + “<tr>”;         for (var j = 0; j < array[i].length; j++) {         tblhtml = tblhtml + “<td style=’width:100px’>” + array[i][j] + “</td>”;        }         tblhtml = tblhtml + “</tr>”;     }

    tblbody.append(tblhtml);     $(“#tblprd”).table(“refresh”);

}

Now inside the prodpage subscribe to the pageshow event which will make a call to the readUrlHelper method and loadproducts method

var catId; $(“#prodpage”).on(“pageshow”, function (e) {     var pgurl = $(“#prodpage”).attr(“data-url”);     //Read the value for catid passed from the Page_Category.html     catId = readUrlHelper(pgurl, “catid”);     //Read the value for catname passed from the Page_Category.html    var catName = readUrlHelper(pgurl,”catname”);

   $(“#catName”).text(catName);

   loadproducts(catId);

});

The above code read the CategoryId and CategoryName passed by the Page_Category.html and based upon it the Products are displayed on the page.

Make the Page_Category.html as a startup page and run the application (IE9, FireFox or Chrome) or in Opera Mobile Emulaor.

On Page-Category.html select Categories as below:

jquery-mob-categories

When you click on Get Products , you will be navigated to the Page_Products.html with the following url:

http://localhost:5506/Page_Products.html?catid=1&catname=Food+Items

The URL contains key and value for CategoryId (catid=1) and CategoryName (catname=Food+Items)

In the Page_Products.html, the readUrlHelper method will read CategoryId and CategoryName and based upon this data, Products will be displayed as below:

jquery-transfer- values

Conclusion: In a Mobile application it is very important for the developer to manage the UI and take care of data communication across these pages. If the data passed is complex (more than one key/value pair) then the URL must be read very carefully. In this article, we saw how we can use jQuery Mobile and ASP.NET to transfer values from one page to another.

iPhone SharePoint Apps Shootout

iPhone SharePoint Apps Shootout

 

As we know, Windows SharePoint Services 3.0 and SharePoint Server 2007 are not very mobile friendly, an increasing relevant functionality that will be vastly improved in the just launched SharePoint Foundation 2010 and SharePoint Server 2010. The following 6 iPhone apps come to the rescue with each one promising an iPhone friendly experience in accessing your corporate data stored in SharePoint sites. All but one of the apps use SharePoint web services, specifically lists.asmx, webs.asmx and search.asmx, to get data from SharePoint sites while iSharePhone provides its own server component to handle the communication. So how do they fare?

Features

  Attaché iShare iSharePhone ISP-Browser Moshare Sharetica
Seller LÛCRUM Spyk Software Webstate Petra Troegel Moprise Jacek Rutkowski
Launch Date 2009-06-05 2009-02-26 2009-07-19 2009-12-05 2010-03-23 2009-06-23
Launch Price $2.99 $9.99 Free/$4.99 $5.99 $1.99 $0.99
Current Price (2010-05-11) $0.99 Free Free/$4.99 $0.99 $1.99 $0.99
Version Tested 1.2 1.2.2 1.02 2.5 1.1 1.4
Windows SharePoint Services 3.0 Yes Yes Yes Yes Yes Yes
SharePoint Server 2007 Yes Yes Yes Yes Yes Yes
SharePoint Foundation 2010 Yes Yes No Yes Yes Yes
SharePoint Server 2010 Yes Yes No Yes Yes Yes
Require Server Software No No Yes No No No
SSL No Yes Yes Yes Yes Yes
Browse sub-sites No Yes Yes Yes No No
Browse lists & libraries Yes Yes Yes Yes Yes Yes
Edit & add list items No Yes No No No No
Read Documents Yes Yes Yes Yes Yes Yes
Upload documents No No No No No No
Offline documents viewing No No No No No Yes
Email documents No No Yes No Yes No
Multiple site urls Yes Yes No Yes Yes Yes
Search No Yes Yes No Yes No
Passcode locking No No No No No No

Set Up

Testing involves accessing an out-of-the-box SharePoint Collaboration Publishing Portal with mostly out-of-the-box contents using all the tested iPhone apps. The configurations are:

  1. iPhone 3GS on OS 3.1.3
  2. SharePoint Server 2007 SP2 on Windows Server 2008
  3. SharePoint Server 2010 Beta on Windows Server 2008 R2

Ratings Explained

Rating scores are graded from 1 to 5, with 1 being the poorest and 5 being the best.

  • Usability – How easy to use
  • Design – How pretty are the page design, composition elements, icons and graphics
  • Features – Functionality
  • Performance – Is it slow or fast? Does it crash? Bugs?
  • Value – Value for money

Attaché: SharePoint Client ($0.99 as of 2010-05-11)

attache01.gif attache02.gif attache03.gif attache04.gif attache05.gif attache06.gif

In Attaché, you set up your SharePoint sites in My Sites, giving each site its URL and login credential. SSL connection does not seem to be supported, at least not for the self-signed certificate I set up. There is no default site but as this is the landing page when the app opens, you can specify which site to browse by tapping a site entry.

The Lists page lists your default site’s lists and libraries together in one grouping. Not all lists and libraries are supported. Unsupported ones are not shown. There are no visual cues if there are sub-folders and items under each entry. Refresh button is also not available. For each list and library item in listing view, the title is shown. In the case of document item, a second line adds the document last modified date and time. For event item, a second line adds the event start and end date and time.

Tapping a document item opens up the document if the file format is readable by iPhone. Document properties are not available. When properties are available for a list item like event or contact, each property value is shown in one line with truncation. Landscape mode is available, giving the property value more room to show before truncation.

For contacts stored in SharePoint, you can add them to iPhone’s Address Book. You can also tap a contact’s phone number to make a call, or send an email to the listed address.

Ratings
Usability 2
Design 2
Features 1
Performance 3
Value 4
Verdict 12

iShare (Free as of 2010-05-11)

iShare01.gif iShare02.gif iShare03.gif iShare04.gif iShare05.gif iShare06.gif iShare07.gif

In iShare, you set up your SharePoint sites in Settings, giving each site its URL and login credential. If you have more than one site, you can specify which one to browse by tapping a site entry as the current site.

The Browse page lists your default site’s sub-sites, lists and libraries in separate groupings. For lists and libraries, an items count total is shown for each entry, adding the number of sub-folders and list or library items, followed by a next arrow. For each list and library item in listing view, the title is shown. In the case of document item, a second line adds the document size and the last modified date and time which strangely is always blank.

To read a document, tap the document title. The document will open up if the file format is readable by iPhone. Tapping the next icon of a list or document item opens up a detail page. Every property value is listed in full with no truncation.

Besides browsing, iShare can also add and edit list items. For lists, tapping the plus icon at the top right allows user to add a list item. When you are at the detail page, tapping the Edit button at the top right allows user to edit or delete the list item.

The Search page adds the ability to perform a full site search. Unfortunately the search results do not have paging and are apparently limited to around 40 matches in my test. If a match returns a document, tapping it will open up the document directly. If a match returns a site or a page, tapping it will open the site or page in browser mode.

Ratings
Usability 4
Design 4
Features 3
Performance 4
Value 5
Verdict 20

iSharePhone (Free/$4.99 as of 2010-05-11)

iSharePhone01.gif

iSharePhone02.gif iSharePhone03.gif iSharePhone04.gif iSharePhone05.gif iSharePhone06.gif

iSharePhone is the only app here that requires a server component to be installed. Each iPhone client license costs $4.99. The first one is included for free so that you can try out the server. This licensing model is quite rare in the iPhone apps world. It bypasses Apple’s cut in a normal sale or in-app purchase model.

Server installation is pretty straightforward. You specify a TCP and a SSL port for the server component to communicate, a SMTP server name or IP address for the emailing of documents, and the SharePoint URL. As such, the server component ties with a single site or site collection only. One thing to take note is to make sure those ports are open in the firewall. The installation creates an iSharePhone web site at the ports specified with custom IIS remote objects utilizing SharePoint API. An iSharePhone Manager is also installed. It allows configuration of ports and SMTP information and management and purchase of additional iPhone licenses.

You set up your one SharePoint site in Settings under User settings. You enter the login credentials (username without domain), your email address, the site’s URL, TCP port and toggle to use SSL.

The Portal page lists your site’s sub-sites at the top, follows by lists and libraries in one grouping. If there are sub-folders, list or library items under each entry, a next arrow is shown. For each list and library item in listing view, the title is shown. Unlike the other apps, there is no refresh icon when you are browsing the site.

Tapping the next icon of a list or document item opens up a detail page. Every property value is listed in full with no truncation. To read a document, tap the document title. The document will open up if the file format is readable by iPhone. To email a document, tap the email icon at the top right. Start typing the recipient’s name and matching results from your iPhone’s contact list will be listed below for your selection. Click Send and the document will be sent via the pre-configured SMTP server as an attachment.

The Search page adds the ability to perform a full site search. The search results do not have paging and are a bit different than what I would get using the site’s native search. I think there is some filtering performed as I noticed no form pages in the search results. If a match returns a document or a page, tapping it will open up the detail page for the item. If a match returns a site, tapping it will browse the site as if you are in the Portal page.

Ratings
Usability 4
Design 4
Features 3
Performance 3
Value 3
Verdict 17

ISP-Browser ($0.99 as of 2010-05-11)

isp-browser01.gif isp-browser02.gif isp-browser03.gif isp-browser04.gif isp-browser05.gif isp-browser06.gif

ISP-Browser has gone through some welcomed bug fixes in the latest release, an improvement over the previous crashy versions. To start, you set up your SharePoint sites in Settings, giving each site its URL and login credential. If you have more than one site, you can specify which one to browse by setting a site as default by first tapping a site entry. It then goes to an Edit site page where you would need to check the Default checkbox and the Save Data button, a procedure that is very PC like, not iPhone like. There is a Start screen option in Settings where you toggle between Browse and Favorites. If the option is set to Browse, the app will immediately switch to the Browse page to list the contents of your default site when it launches.

The Browse page lists your default site’s lists, libraries and sub-sites (new in V2.5) in separate groupings. For lists and libraries, an items count total is shown for each entry, adding the number of sub-folders and list or library items, follows by a next arrow. For each list and library item in listing view, the title is shown along with the last modified date and time follows by a next icon. In the case of document item, the document size is also shown.

Tapping a list or document item opens up the Properties page. Each property is listed in a one-liner. If the property value is too long to fit, it will be truncated follows by a next arrow. Although ISP-Browser has a landscape mode, the property value stays truncated at the same position. Tapping the next arrow opens up a full page showing the property value in its entirety. To read a document, tap the document icon at the top left. The document will open up if the file format is readable by iPhone. Event or calendar list is given a special treatment where you could navigate forward or backward easily through months by using the special navigation near the top.

At the top right of a list or library, there is a favorite button which can be used to save the current list or library as your favorites. Unfortunately only the name of a list or library is shown in the Favorites page. There is no way to tell which site a list or library belongs to. Deletion of favorites is done using the remove text link, away from the standard iPhone edit UI.

Ratings
Usability 3
Design 4
Features 2
Performance
Value 4
Verdict 16

Moshare ($1.99 as of 2010-05-11)

moshare01.gif moshare02.gif moshare03.gif moshare04.gif moshare05.gif moshare06.gif moshare07.gif moshare08.gif

Moshare is the most visually stunning app here. Icons are pretty and colors are appealing. You set up your SharePoint sites in Sites, giving each site its URL and login credential. If you have more than one site, you can specify which one to browse by setting a site as default during the set up.

The app lists your default site’s lists and libraries together in one grouping. Not all lists and libraries are supported. Unsupported ones are not shown. There is no refresh button. For each entry, the last modified date and time and an items total count is shown. The count adds the number of sub-folders and list or library items under each entry. For each list and library item in listing view, the title is shown. In the case of document item, a second line adds the document last modified date and time. In most listing views, entries can be sorted by item type, title, created date or modified date by tapping the sort buttons at the bottom of the screen.

Tapping a document item opens up the document if the file format is readable by iPhone. When a document is opened, there is an email icon and a link icon at the bottom of the screen. Clicking the email icon allows you to compose an email with the document included as an attachment. Clicking the link icon copies the document URL to iPhone’s clipboard. Document properties are not shown. When properties are available for a list item like event or contact, each property value is shown in full.

For contacts stored in SharePoint, you can add them to iPhone’s Address Book. You can also tap a contact’s phone number to make a call, or send an email to the listed address. Search is available but results seem to be limited to 20 matches.

Ratings
Usability 2
Design
Features 2
Performance 1
Value 2
Verdict 12

Sharetica ($0.99 as of 2010-05-11)

Sharetica01.gif Sharetica02.gif Sharetica03.gif Sharetica04.gif

You set up your SharePoint sites at Home, giving each site its URL and login credential. If begin to browse by tapping the site entry.

The Lists page lists your default site’s lists and libraries together in a single grouping, with each entry showing an items count and a next arrow. Sub-sites are not shown. The items count total is the sum of sub-folders and list or library items. Hidden lists are also shown which I find confusing. It will be better if there is an option to show or hide hidden lists. For each sub-folder, list and library item in listing view, the title is shown.

Tapping a list or document item opens up the Field Values page. Each property is listed in a one-liner. If the property value is too long to fit, it will be truncated. There is no way I know of to read the full property value other than rotating the iPhone to go to landscape mode where you would see more of the property value. For document item, tap Read Document at the top opens up the document if the file format is readable by iPhone.

Documents that are opened and read are automatically stored for offline viewing. They are listed under the section Cache – downloaded files (offline) at Home. There is no option to choose which document is to be stored for offline viewing though you can edit the list later.

Ratings
Usability 2
Design 3
Features 2
Performance 2
Value 4
Verdict 13

Conclusion

All 6 apps offer limited feature sets in its present state. For more advanced operations, SharePoint web services are not the easiest thing in the world to work with. One app bypasses this restriction and uses its own custom server component.

Price ranges from free to $4.99, a bargain if we consider the fact that SharePoint is an enterprise product and the non-free SharePoint Server costs upwards of tens of thousands of dollars. However my value rating has to take into account how iPhone apps are normally priced.

At the bottom of the ratings scale are Attache, Moshare and Sharetica. For Moshare, usability takes a second place to page design. Light green text on white are hard to read. The items count is too small. It usually takes me a few taps to bring down the top menu as the trigger region is again too small. I do very much like the ability to email a document as an attachment though. However response time is frustratingly slow when opening up document libraries. For Attaché and Sharetica, they are priced low but poor usability again mars these 2 apps. Sharetica is the only app that offers offline viewing of document though.

Neck and neck up the list are ISP-Browser and iSharePhone. While ISP-Browser has a bookmark feature called Favorites, iSharePhone allows emailing of documents, without having to download the documents first. However it is the only app that requires a custom server component. Most IT departments may be reluctant to install it in a production environment.

The winner of this shootout belongs to iShare. The app supports browsing of sub-sites, addition and editing of list items, and search. It has relatively good usability and is marked down from a normal price of $9.99 to free since February. So what are you waiting for? Download a copy and try it out.

Duet Enterprise – Creating and Deploying a Mobile Adapter Class for Business Data Action Web Parts

Learn how to create a mobile adapter class to display mobile views for Business Data Action Web Parts.

In Microsoft SharePoint 2010, mobile views are available for both the Business Data Builder Web Part and the Business Data Item Web Part. In the Starter Services site of Duet Enterprise for Microsoft SharePoint and SAP, a mobile view is available for only the Business Data Item Web Part. You must define a mobile adapter class to make mobile views available for other Business Data Web Parts. This topic describes how to write a mobile adapter class for Business Data Action Web Parts.

The procedures in this section describe how to create and deploy a mobile adapter class for displaying Business Data Action Web Parts.

The following are the basic steps to create and deploy a mobile adapter class:

  1. Create a mobile adapter class for Business Data Action Web Parts.
  2. Edit the compat.browser file.
  3. Register your adapter as a safe control.

To create a mobile adapter class for Business Data Action Web Parts

  1. In Microsoft Visual Studio 2010, create a new class library project named DuetMobileCustomization. Add references to the System.Web assembly and Microsoft.SharePoint.dll assembly.
  2. Add a using statement for the Microsoft.SharePoint.WebPartPages namespace. Depending on the details of your adapter implementation, add using statements for other namespaces. Commonly, mobile adapters make calls to types in the System.Web.UI.MobileControls namespace, Microsoft.SharePoint namespace, and Microsoft.SharePoint.MobileControls namespace.
  3. Add a class named WebPartClassMobileAdapter, where WebPartClass is a placeholder for the name of the Web Part that you are adapting. For example, if you are adapting the BusinessDataActionsWebPart, name the adapter class BusinessDataActionsWebPartMobileAdapter. This class should inherit from the WebPartMobileAdapter class.
  4. Add a namespace named MyCompany.SharePoint.WebPartPages.MobileAdapters. (Replace MyCompany with your company’s name.)
  5. Copy the following code into the new BusinessDataActionsWebPartMobileAdapter class.
    Copy
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Security.Permissions;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI.MobileControls;
    
    using Microsoft.BusinessData.MetadataModel;
    using Microsoft.BusinessData.MetadataModel.Collections;
    using Microsoft.BusinessData.Runtime;
    
    using Microsoft.SharePoint.Portal.MobileControls;
    using Microsoft.SharePoint.MobileControls;
    using Microsoft.SharePoint.Utilities;
    using Microsoft.SharePoint.WebControls;
    using Microsoft.SharePoint.WebPartPages;
    using Microsoft.SharePoint.Portal.WebControls;
    using Microsoft.Office.Server.Diagnostics;
    
    namespace Microsoft.SharePoint.WebPartPages
    {
        public class BusinessDataActionsWebPartMobileAdapter : WebPartMobileAdapter
        {
  6. Because the WebPartMobileAdapter.Control property cannot be overridden, you might have to create a custom version of it by hiding and replacing it. You can do this by declaring a new Control property in your derived class by using the new keyword, as shown in the following example.
    Copy
    protected new BusinessDataActionsWebPart Control
            {
    [Microsoft.SharePoint.Security.SharePointPermission(System.Security.Permissions.SecurityAction.Demand, 
    ObjectModel = true)]
                get { return base.Control as BusinessDataActionsWebPart; }
            }

    For more information about how to create a custom version of WebPartMobileAdapter.Control and hiding and replacing it, and why you might have to do this, see the Control property.

  7. If the default implementation of the CreateControlsForSummaryView method of the WebPartMobileAdapter class is not appropriate for mobile access to the Web Part in your specific implementation, override it. An override should create any necessary child controls and add them to the Controls collection in the order in which they should appear on a mobile device. The display should contain at least a small icon and a title for the summary view on a mobile device. If those are the only display elements that that you must have, you do not have to override the CreateControlsForSummaryView method. The WebPartMobileAdapter class contains two helper methods you can use to create your display: CreateWebPartIcon() and CreateWebPartLabel().When you must display more information than what appears in the default summary view (for example, when your adapted Web Part has multiple child items that are the same type), you can add a count of the total number of children to the summary view by placing a Label control after the icon and title. The following code shows how to do this.
    Note Note
    This example assumes that the custom Web Part that you are adapting has a Count property of type String that returns the total number of child items.
    Copy
    protected override void CreateControlsForSummaryView()
            {
                this.CreateControlsForWebPartHeader();
                this.CreateControlsForBusinessDataActions();
            }
    
            private void CreateControlsForWebPartHeader()
            {
                Image iconImage = this.CreateWebPartIcon(WebPartIconLink.NoLink);
                iconImage.BreakAfter = false;
                this.Controls.Add(iconImage);
                this.Controls.Add(this.CreateWebPartLabel());
            }
    
            private void CreateControlsForBusinessDataActions()
            {
                try
                {
                    IList<string> result = this.Control.SelectedActions;
                    try
                    {
                        if (this.Control.BdcEntity != null)
                        {
                            IList<IAction> displayActions = GetActionsToDisplay(this.Control.BdcEntity);
                            result = new List<string>();
    
                            foreach (IAction action in displayActions)
                            {
                                Link l = new Link();
                                l.Text = action.Name;
    // This example does not create the Parameter value. 
    // Add logic to set the action of the parameter before storing this value in the Link Navigation URL.
                                l.NavigateUrl = action.Url;
                                this.Controls.Add(l);
                            }
                        }
                    }
                    catch (MetadataException)
                    {
                        // Metadata error. Just default to returning the Web Part's selected Actions.
                        result = this.Control.SelectedActions;
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
    private IList<IAction> GetActionsToDisplay(IEntity entity)
            {
                IList<IAction> result = new List<IAction>();
                INamedActionDictionary namedActionDictionary = entity.GetActions();
                if (namedActionDictionary.Count != 0)
                {
                    // First add all the currently selected actions.
                    foreach (string selectedActionName in this.Control.SelectedActions)
                    {
                        if (namedActionDictionary.ContainsKey(selectedActionName))
                        {
                            result.Add(namedActionDictionary[selectedActionName]);
                        }
                        // else
    
                    }
    
                    // Action may not be in the SelectedActions list,
                    // but the Web Part is configured to display new actions and
                    // this action is not one of the explicitly de-selected ones. Add it to UI.
                    if (this.Control.DisplayNewActions)
                    {
                        foreach (IAction action in namedActionDictionary.Values)
                        {
                            if (!result.Contains(action)
                                && !this.Control.DeselectedActions.Contains(action.Name))
                            {
    
                                result.Add(action);
                            }
                        }
                    }
                }
    
                return result;
            }
    
            public void cmd_Click(object sender, EventArgs e)
            {
                string CommandText = ((Command)sender).Text;
    
            }
  8. If the default implementation of CreateControlsForDetailView is not appropriate for mobile access to the Web Part in your specific implementation, override it. The default implementation renders an icon and title followed by a message that states that there is no detailed view for the Web Part. If you have overridden the CreateControlsForSummaryView method and do not want to provide a detailed view, override CreateControlsForDetailView and have it do nothing, as shown in the following example.
    Copy
    protected override void CreateControlsForDetailView()
            {
                // No Detail View
            }
  9. To change the icon that appears next to the Web Part title, override one or more of the following properties:
    • SummaryViewTitleIconUrl  The icon that appears next to the title when the Web Part is collapsed.
    • DetailViewTitleIconUrl  The icon that appears next to the title when the Web Part is expanded.
    • TitleIconUrl  The icon that appears next to the title when the mobile device does not support expand or collapse scripting.

    The code in the following example shows how to override the TitleIconUrl property. In this override, if the Web Part displays a list and the list has an icon of its own in its ImageUrl property, that icon is displayed.

    Copy
    protected override string TitleIconUrl
    {
        get
        { 
            SPContext context = SPContext.GetContext(HttpContext.Current);
    
            if (String.IsNullOrEmpty(context.List.ImageUrl))
            {
                return base.TitleIconUrl;
            }
            return context.List.ImageUrl;
        }
    }
  10. Compile the assembly, give it a strong name, and then deploy it either to the global assembly cache or to the \BIN folder of the Web application on every front-end web server in the farm. To deploy it to the global assembly cache, ensure that GlobalAssemblyCache is selected in the Assembly Deployment Target of the Properties pane of your class library project in Visual Studio 2010. This topic assumes that you are deploying to the global assembly cache.

To edit the compat.browser file

  1. In a text editor, open the compat.browser file that is located at \\Inetpub\wwwroot\wss\VirtualDirectories\port_number\App_Browsers\compat.browser, where port_number is the port of the web application. Scroll to the <browser> element that has the refID attribute value of default. This element will have a child element named <controlAdapters> that looks much like the code in the following example.
    Copy
    <controlAdapters>
      <adapter controlType="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        adapterType="Microsoft.SharePoint.WebPartPages.XsltListViewWebPartMobileAdapter, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <adapter controlType="Microsoft.SharePoint.WebPartPages.ListViewWebPart, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        adapterType="Microsoft.SharePoint.WebPartPages.ListViewWebPartMobileAdapter, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <adapter controlType="Microsoft.SharePoint.Applications.GroupBoard.WebPartPages.WhereaboutsWebPart, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
        <adapter controlType="Microsoft.SharePoint.Applications.GroupBoard.WebPartPages.WhereaboutsWebPart, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                         adapterType="Microsoft.SharePoint.Applications.GroupBoard.WebPartPages.WhereaboutsWebPartMobileAdapter, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
                <adapter controlType="Microsoft.SharePoint.WebPartPages.ImageWebPart, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
                         adapterType="Microsoft.SharePoint.WebPartPages.ImageWebPartMobileAdapter, Microsoft.SharePoint, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
    </controlAdapters>
  2. Add an <adapter> element as a child of the <controlAdapters> element. This child element maps your adapter class to the custom Web Part that it adapts. Notice that both the controlType attribute and adapterType attribute are required. The value for both should be the fully qualified name of the class and the four-part name of the assembly. To obtain your adapter assembly’s public key token, in Visual Studio 2010 on the Tools menu, click Get Assembly Public Key. For another way to obtain the public key token, see How to: Create a Tool to Get the Public Key of an Assembly (http://msdn.microsoft.com/en-us/library/ee539398.aspx). For more information about this XML markup, see Browser Definition File Schema (browsers Element) (http://msdn.microsoft.com/en-us/ms228122.aspx). The following code shows one example of an <adapter> element.
    Copy
    <adapter controlType="Microsoft.SharePoint.Portal.WebControls.BusinessDataActionsWebPart, 
    Microsoft.SharePoint.Portal, 
    Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" 
    adapterType="Microsoft.SharePoint.WebPartPages.BusinessDataActionsWebPartMobileAdapter, MobileCustomization, 
    Version=1.0.0.0, Culture=neutral, PublicKeyToken=<assemblyPublic Key>" />
    NoteNote
    To deploy your adapter class to a server farm, you must change the compat.browser file as described earlier on every front-end web server. Do not overwrite the existing compat.browser file with a compat.browser file of your own because this might cancel adapter mappings that are made by other Microsoft SharePoint 2010 solution providers. Consider deploying the adapter as part of a SharePoint 2010 Feature. In the FeatureActivated event handler, create a timer job that adds the required <adapter> element to the compat.browser file on every front-end web server. For detailed information about programmatically editing the compat.browser file on all servers by using a timer job, see How to: Run Code on All Web Servers (http://msdn.microsoft.com/en-us/library/ff464297.aspx).

To register your adapter as a safe control

  1. In your Visual Studio 2010 project, add an XML file named webconfig.CompanyName.xml, where CompanyName is the name of your company or another name that is not likely to be used by any other SharePoint Foundation 2010 solution providers.
    Tip Tip
    We recommend that you register your adapter by deploying it inside a SharePoint 2010 solution. The steps in this section are required only if your development computer is a single front-end web server. A SharePoint 2010 solution enables you to register controls as safe on all front-end web servers when your solution is deployed. For more information about using solution deployment to register controls as safe, see Solutions Overview (http://msdn.microsoft.com/en-us/library/aa543214.aspx), Manually Creating Solutions in SharePoint Foundation (http://msdn.microsoft.com/en-us/library/aa543741.aspx), and Solution Schema (http://msdn.microsoft.com/en-us/library/ms442108.aspx).
  2. Add an <action> element that follows the model in the example below to the file. The TypeName attribute of the <SafeControl> element can be the name of your adapter class, such as UserTasksWebPartMobileAdapter. If you have multiple adapter classes in the same namespace, you can use an asterisk (*) as the value of TypeName.
    Copy
    <action>
       <add path="configuration/SharePoint/SafeControls">
        <SafeControl
          Assembly=" MobileCustomization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=<myPublicKeyToken>"
          Namespace="Microsoft.SharePoint.WebPartPages"
          TypeName="*"
          Safe="True"
          AllowRemoteDesigner="True"
        />
      </add>
    </action>
    Caution noteCaution
    Using an asterisk (*) as the value of TypeName makes every class in the namespace a safe control. If you have some classes in the assembly that should not be designated as safe, move them to a different assembly or avoid using the asterisk (*) value.

    For more information about the <SafeControl> element and web.config files, see How to: Create a Supplemental .config File (http://msdn.microsoft.com/en-us/library/ms439965.aspx) and Working with Web.config Files (http://msdn.microsoft.com/en-us/library/ms460914.aspx).

  3. Save the file. You must now copy it to the %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\CONFIG folder on your development computer. The simplest way to do this on your development computer is to add the following lines to a post-build event command line or to a batch file script.
    Copy
    xcopy /y webconfig.MyCompany.xml "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG"
    stsadm –o copyappbincontent
    NoteNote
    This code assumes that you have followed the recommendations in How to: Add Tool Locations to the PATH Environment Variable (http://msdn.microsoft.com/en-us/library/ee537574.aspx).

    The copyappbincontent Stsadm.exe command performs the action defined by the <action> element in your Web configuration .xml file. In this case, it inserts the new <SafeControl> element of your adapter into the web.config file at the root of the web application. It first removes any existing <SafeControl> elements for the adapter. This lets you rerun the Stsadm command with every build without creating duplicate <SafeControl> elements.) For more information about Stsadm, see Stsadm command-line tool (http://msdn.microsoft.com/en-us/library/cc288981(office.12).aspx).

 

Enhanced by Zemanta