Sep 12 2014

10 steps to optimize SharePoint performance

Mohammed Al-Atari

URL:http://www.networkworld.com/article/2210265/tech-primers/10-steps-to-optimize-sharepoint-performance.html

SharePoint, the fastest growing product in Microsoft’s history, is used to store reams of documents, meaning application performance is a key component for successful SharePoint deployment and adoption. Here are 10 steps to improve the performance of your SharePoint Servers.

SharePoint, the fastest growing product in Microsoft’s history, is used to store reams of documents, meaning application performance is a key component for successful SharePoint deployment and adoption. Here are 10 steps to improve the performance of your SharePoint servers.

Step 1: Separate user and database traffic

A common misconception is that servers connected to a high-speed network segment will have plenty of bandwidth to perform all required operations. But SharePoint places a tremendous amount of demand on SQL — each request for a page can result in numerous calls to the database, not to mention service jobs, search indexing and other operations.

10 things we love about SharePoint 2010

In order to mitigate the conflict between user and database traffic, connectivity between front-end servers and SQL should be isolated, either via separate physical networks or virtual LANs. Typically this requires at least two separate network interface cards in each front-end Web server with static routes configured to ensure traffic is routed to the correct interface. The same configuration may also be applied to application and index server.

Step 2: Isolate search indexing

A typical medium server farm consists of one or more Web front-end servers, a dedicated index or application server and a separate SQL database server. Search traffic initiated by the index server must be processed by the same servers responsible for delivering user content. In order to prevent search and user traffic from conflicting, an additional server may be added to the farm, which is dedicated solely to servicing search queries (in smaller environments, the index server may also serve this function). The farm administrator would then configure the search service to perform crawls only against this dedicated server. This configuration may reduce traffic to the Web front-end servers by as much as 70% during index operations.

Step 3: Adjust SQL parameters

One quick way to avoid future headaches is to provision the major SharePoint databases on separate physical disks (or LUNs if a storage-area network is involved). This means one set of disks for search databases, one for temporary databases and still another for content databases. Additional consideration should be given to isolating the log files (*.ldf). Although these do not incur the same level of I/O as other files, they do play a primary role in backup and recovery and they can grow to several times the size of the master database files.

Another technique is to proactively manage the size and growth of individual databases. By default, SQL grows database files in small increments, either 1MB at a time or as a fixed percentage of database size (usually 10%). These settings can cause SQL to waste cycles constantly expanding databases, and prevents further data from being written while the databases are expanding. An alternative approach is to pre-size the databases up to the maximum recommended size (100GB) if space is available and set auto growth to a fixed size (e.g. 10MB or 20MB).

Step 4: Defragment database indexes

SQL Server maintains its own set of indexes for data stored in various databases in order to improve query efficiency and read operations. Just as with files stored on disk, these indexes can become fragmented. It is important to plan for regular maintenance operations, which includes index defragmentation. Special care should be taken to schedule these types of operations as they are resource-intensive and, in many cases, can prevent data from being written to or read from the indexes.

Step 5: Distribute user data across multiple content databases

Most SharePoint data is stored in lists: tasks, announcements, document libraries, issues, picture libraries, and so forth. A great deal of this data is actually stored in a single table in the content database associated with the site collection. Regardless of how many sites and subsites are created within the SharePoint hierarchy, each site collection has only one associated content database. This means that a site collection with thousands of subsites is storing the bulk of the user data from every list in every site in a single table in SQL.

This can lead to delays as SQL must recursively execute queries over one potentially very large dataset. One way to reduce the workload is to manage the mapping of site collections to content databases. Administrators can use the central administration interface to pre-stage content databases to ensure that site collections are associated with a single database or grouped logically based on size or priority. By adjusting the ‘maximum number of sites’ setting or changing database status to “offline”, administrators can also control which content database is used when new site collections are created.

Step 6: Minimize page size

For SharePoint users connected to the portal via a LAN it is easy to manage content and find resources, but for users on the far end of a slower WAN link the heavyweight nature of a typical SharePoint page can be a real performance-killer.

If you have many remote users, start with a minimal master page, which, as the name implies, removes unnecessary elements and allows designers to start with a clean slate that only contains the base functionality required for the page to render correctly.

Second, most SharePoint pages contain links to supporting files, including JavaScript and style sheets, which require additional time to retrieve and execute. Designers can alter how SharePoint pages retrieve these files using a technique called “delayed loading”, which essentially loads the linked files in the background while the rest of the page is rendering.

Step 7: Configure IIS compression

SharePoint content consists of two primary sources — static files resident in the SharePoint root directories (C:\Program Files\Common Files\Microsoft Shared\12 for 2007 and \14 for 2010) and dynamic data stored in the content. At runtime, SharePoint merges the page contents from both sources then transmits them inside an HTTP response to the requesting user. Internet Information Server (IIS) versions 6 and 7 both contain various mechanisms for reducing the payload of HTTP responses prior to transmitting them across the network. Adjusting these settings can reduce the size of the data transmitted to the client, resulting in shorter load times and faster page rendering.

IIS compression settings can be modified from a base value of 0 (no compression) to a maximum value of 10 (full compression). Adjusting this setting determines how aggressive IIS should be in executing the compression algorithms.

Step 8: Take advantage of caching

Much of the content requested by users can be cached in memory, including list items, documents, query results and Web parts. Site administrators can configure their own cache profiles to meet different user needs. Anonymous users, for example, can be assigned one set of cache policies while authenticated users are assigned another, allowing content editors to get a more recent view of content changes than general readers. Cache profiles can also be configured by page type, so publishing pages and layout pages behave differently, and administrators have the option to specify caching on the server, the client, or both.

In addition, the SharePoint Object Cache can significantly improve the execution time for resource-intensive components, such as the Content Query Web Part. For example, large objects that are requested frequently, such as images and files, can also be cached on disk for each Web application to improve page delivery times.

Step 9: Manage page customizations

SharePoint Designer is a useful tool for administrators and power users but page customization can be harmful to overall performance. When customization occurs, the entire page content, including the markup and inline code, is stored in the database and must be retrieved each time the page is requested. This introduces relatively little additional overhead on a page-by-page basis, but in larger environments with hundreds or even thousands of pages, all that back-and-forth to the database can add up to significant performance degradation.

To prevent this problem, administrators should implement a policy that restricts page customizations to only those situations where it is absolutely necessary. Site collection and farm administrators also have the option to disable the use of Designer or, when necessary, use the ‘reset to site definition’ option to undo changes and revert back to the original content.

Step 10: Limit navigation depth

One of the most significant design elements on any portal site is the global, drop-down, fly-out menu at the top of each page. It seems like a handy way to navigate through all the various sites and pages — until it becomes so deep and cluttered that all ability to navigate beyond the first few levels is lost completely. Even worse, fetching all the data to populate the navigation menus can be resource-intensive on sites with deep hierarchies.

SharePoint designers have the ability to customize the depth and level of each navigation menu by modifying the parameters for the various navigation controls within the master page. Administrators should limit that depth to a manageable level that does not impact performance.

Eric Shupps is a SharePoint MVP who specializes in SharePoint performance to help organizations better understand the different ways and places SharePoint performance can be improved. This article was written in partnership with Idera.


Sep 12 2014

SharePoint 2013 Certifications

Mohammed Al-Atari
  1. MCSD: SharePoint Applications (Solutions Developer(
    The globally recognized standard for developer excellence

    Exams

 

  1. MCSE: SharePoint (Solutions Expert(
    The globally recognized standard for IT professionals

    Exams

 

List of Sites provide a exams
http://www.examcollection.com
http://www.pass4sure.com
http://www.testking.com
http://www.braindumps.com


Nov 26 2013

12 Excellent Free Tools for Monitoring Your Site’s Uptime

Mohammed Al-Atari

 

A website or web application’s high availability is very crucial; users who constantly encounter problems accessing the content of a site will not likely come back. For web applications – poor uptimes means users won’t be confident about your product: if they constantly experience issues with your apps’s availability, they will likely look for another solution that isn’t as problematic.

It’s essential that your sites and web apps are constantly accessible to your users. In this article, you will find free and useful monitoring tools to help you know when your website or web application becomes unavailable.

1. Site24x7

Sites24x7 is a simple website-monitoring tool for keeping track of your website or web application’s availability. It tests your uptime in several global locations such as Singapore, the Netherlands, and New Jersey so that you can be assured that your website is being served in major regions of the world at optimal page load times.

2. Are My Sites Up?

 Are My Sites Up? is a straightforward free web tool for being alerted when your websites are down. With Are My Sites Up?, you can monitor up to five different websites, receive email and text message alerts so that you have constant awareness of your sites’ uptime, and checks performed 25 times a day.

3. mon.itor.us

 mon.itor.us is a free site monitoring tool with loads of useful features that will help you maintain a high uptime. By providing you with a ton of information about your site and web server, you can quickly spot potential issues that relate with your site’s availability. mon.itor.us has an intuitive dashboard GUI, the ability to send you downtime alerts via email, text message, and RSS, monitoring from multiple geographical locations, and real-time visitor monitoring. It’s a simple-to-use tool boasting a low setup time (sign-up and installation) of only five minutes.

4. Montastic

 Montastic is a free, quick, and easy-to-use tool for keeping constant knowledge of your websites’ availability. Developed by Metadot, Montastic sends you warnings whenever your site crashes (and when it comes back up) through email, RSS, or their Windows and Mac widget. Montastic lets you monitor up to 100 sites per account, supports monitoring for HTTP and HTTP Secure connections, and a simple and elegant end-user interface.

5. ServerMojo

 ServerMojo is a simple-to-use service for supervising your web server’s uptime. It alerts you via IM, Twitter, and email when your site is unavailable. ServerMojo permits you to monitor one site at one-hour intervals.

6. HostTracker

 HostTracker is a free web tool for monitoring site availability. You can monitor up to two websites at a time and get free weekly, monthly, quarterly, and yearly reports on your web server’s performance. HostTracker provides distributed monitoring, tracking of useful data on site availability for diagnostics, and alerts of issues via email, IM, and/or SMS. HostTracker’s front page features a nice utility widget for instantly checking your website’s availability: you simply enter your URL and it will ping your server.

7. Observu

 Observu is a very simple tool intentionally designed for rapid set-up and ease of use. With Observu, you can monitor an unlimited amount of websites/web servers, which is great for multi-site owners who want a hassle-free way of keeping track of what’s going on with their web properties.

8. InternetSeer

 InternetSeer has a free standard service that offers 60-minute intervals for monitoring your site’s uptime and performance. It gives you site availability and page response time reports, real-time error notifications, and a weekly report on your server’s performance for diagnostics.

9. FreeSiteStatus

 FreeSiteStatus is a web-based application that provides email alerts of your site’s downtime, a monitoring interval of 60 minutes, and a distributed monitoring network of 13 global locations. FreeSiteStatus also has a nifty tool on the site called “Quick Test” for instantly checking your site services’ performance and availability (i.e. HTTP, POP3, MySQL, FTP, and more).

10. SiteUptime

 SiteUptime is a free tool that lets you monitor one site at 30 or 60-minute intervals from four geographical locations. You can monitor your HTTP (web server), POP3 (email server), FTP server, and more using SiteUptime. It also gives you the option to display your availability statistics publicly, which you can use as a site widget to show off your site or web application’s high-availability. Check out the live demo of SiteUptime.

11. Basic State

 Basic State is a free monitoring tool for uptime, server, and network failures of your site. Basic State checks your website at 15-minute intervals and sends you notifications via email or text message when something goes kaboom. With a simple sign-up process that will get you set up in no time and the ability to keep tabs on any number of sites, Basic State is a solid option to consider when looking into site monitoring tools.

12. Livewatch

 Livewatch allows you to get alerts when your site is unavailable via email, SMS, phone, IM, and even Twitter. It can record and create PDF reports for site failures so that you can keep track of downtime events for documentation and troubleshooting. They also have a nice and simple web tool for instantly checking your site availability called Free HTTP Check that quickly checks your web server’s availability.

What tool do you use to for monitoring uptime/availability?

Do you have a tool not on the list that you use for your sites and applications? Do you have positive or negative experiences that you’d like to share about the tools featured here? Please do share your thoughts and opinions with us in the comments.


Nov 19 2013

Tweetsharp

Mohammed Al-Atari

    PM> Install-Package TweetSharp

This project is no longer actively developed by its creator. v2.3.1 is the final release. If someone forks this project and proves active and interested ongoing development, I will transfer this repo to them.Forks must respect OSS and copyright law with respect to attribution, etc., etc.

Addressing issues with deserialization

In some cases, and mostly reported when trying to access the timeline of a protected user, the deserializer can get into an infinite recursion state that causes a StackOverflowException. The ability to reproduce this comes and goes, as it’s mainly due to some brittleness in the serializer caused by trying to anticipate too many possible branches of code. Currently this use case seems to work. Twitter’s JSON structures are not typical class-with-properties mappings meaning they need custom conversion. After several years, this code looks long in the tooth and probably will run into similar issues now or in the future. You can override the serializer by either setting the TwitterService.Deserialize property instantiation or using the constructor overload, if you have the appetite to replace it with something better. – Daniel

Introduction

TweetSharp is a Twitter API library that greatly simplifies the task of adding Twitter to your desktop, web, and mobile applications. You can build simple widgets, or complex application suites using TweetSharp. The second version, a rewrite, was designed to be lighter, faster, and more intuitive than the original. You write fewer lines of code, make fewer decisions, and get better results. Visual Studio T4 templates are employed to automatically generate new API methods from a simple text-based DSL.

Open source support

This project is open source software. I am happy to accept any reasonable pull requests, and the code is written with Visual Studio T4 templates, making it ridiculously easy to extend for any API methods that Twitter introduces in the future. Historically, almost no pull requests are received, so please plan accordingly, engage commercial support, or help out!

Commercial support

I no longer offer commercial support services for TweetSharp. It is now in its final state. TweetSharp V2 in general wouldn’t have been possible without the sponsorship of SmartParents.

SmartParents

Learn the Twitter API

Make sure you visit (http://dev.twitter.com) to get acquainted with the Twitter API. Most of the time, confusion around the methods in this library are a result of not understanding Twitter’s requirements, or the OAuth authentication workflow.

Hello, Twitter

using TweetSharp;

// In v1.1, all API calls require authentication
var service = new TwitterService(_consumerKey, _consumerSecret);
service.AuthenticateWith(_accessToken, _accessTokenSecret);

var tweets = service.ListTweetsOnHomeTimeline(new ListTweetsOnHomeTimelineOptions());
foreach (var tweet in tweets)
{
    Console.WriteLine("{0} says '{1}'", tweet.User.ScreenName, tweet.Text);
}

OAuth Authentication

The first step to accessing the Twitter API is to create an application at (http://dev.twitter.com). When that process is complete, your application is issued a Consumer Key and Consumer Secret. These tokens are responsible for identifying your application when it is in use by your customers. Once you have these values, you can create a new service and pass them in.

Authenticating a client application (i.e. desktop)

using TweetSharp;

// Pass your credentials to the service
TwitterService service = new TwitterService("consumerKey", "consumerSecret");

// Step 1 - Retrieve an OAuth Request Token
OAuthRequestToken requestToken = service.GetRequestToken();

// Step 2 - Redirect to the OAuth Authorization URL
Uri uri = service.GetAuthorizationUri(requestToken);
Process.Start(uri.ToString());

// Step 3 - Exchange the Request Token for an Access Token
string verifier = "123456"; // <-- This is input into your application by your user
OAuthAccessToken access = service.GetAccessToken(requestToken, verifier);

// Step 4 - User authenticates using the Access Token
service.AuthenticateWith(access.Token, access.TokenSecret);
IEnumerable<TwitterStatus> mentions = service.ListTweetsMentioningMe();

Authenticating a browser application

using TweetSharp;

public ActionResult Authorize()
{
    // Step 1 - Retrieve an OAuth Request Token
    TwitterService service = new TwitterService("consumerKey", "consumerSecret");

    // This is the registered callback URL
    OAuthRequestToken requestToken = service.GetRequestToken("http://localhost:9090/AuthorizeCallback"); 

    // Step 2 - Redirect to the OAuth Authorization URL
    Uri uri = service.GetAuthorizationUri(requestToken);
    return new RedirectResult(uri.ToString(), false /*permanent*/);
}

// This URL is registered as the application's callback at http://dev.twitter.com
public ActionResult AuthorizeCallback(string oauth_token, string oauth_verifier)
{
    var requestToken = new OAuthRequestToken {Token = oauth_token};

    // Step 3 - Exchange the Request Token for an Access Token
    TwitterService service = new TwitterService(_consumerKey, _consumerSecret);
    OAuthAccessToken accessToken = service.GetAccessToken(requestToken, oauth_verifier);

    // Step 4 - User authenticates using the Access Token
    service.AuthenticateWith(accessToken.Token, accessToken.TokenSecret);
    TwitterUser user = service.VerifyCredentials();
    ViewModel.Message = string.Format("Your username is {0}", user.ScreenName);
    return View();
}

xAuth Authentication

If you are building a mobile application and want to benefit from a seamless authentication experience with no additional steps for the user, you need to enroll your application in Twitter’s xAuth support. You must complete this step in order for xAuth to function correctly.

using TweetSharp;

// OAuth Access Token Exchange
TwitterService service = new TwitterService("consumerKey", "consumerSecret");
OAuthAccessToken access = service.GetAccessTokenWithXAuth("username", "password");

OAuth Delegation with Echo

Twitter provides OAuth Echo support, which allows you to use other services like TwitPic by delegating the user’s existing credentials. TweetSharp uses Hammock both internally and as a tool for you to make delegated requests. This example shows how you would use TweetSharp and Hammock together to post an image on TwitPic using OAuth. You could use any HTTP client as long as you add the same request meta-data.

using TweetSharp;
using Hammock;

TwitterService service = new TwitterService(consumerKey, consumerSecret);
service.AuthenticateWith("accessToken", "accessTokenSecret");

// Prepare an OAuth Echo request to TwitPic
RestRequest request = service.PrepareEchoRequest(); 
request.Path = "uploadAndPost.xml";
request.AddFile("media", "failwhale", "failwhale.jpg", "image/jpeg");
request.AddField("key", "apiKey"); // <-- Sign up with TwitPic to get an API key
request.AddField("message", "Failwhale!");

// Post photo to TwitPic with Hammock
RestClient client = new RestClient { Authority = "http://api.twitpic.com/", VersionPath = "2"};
RestResponse response = client.Request(request);

Discovering API Methods

TweetSharp uses a consistent method naming convention to help you locate the method you’re looking for. In general, methods that return multiple results begin with List, while methods that return a single result begin with Get. Most methods, like the Twitter API, have additional parameters for obtaining pages of results rather than the default count. Keep in mind that paging methods have limits that you can confirm at (http://dev.twitter.com). Here’s a sample of some of the most common Twitter API methods:

using TweetSharp;

TwitterStatus GetTweet(new GetTweetOptions { Id = 12345 });
TwitterStatus SendTweet(new SendTweetOptions { Status = "Hello, world!" });

IEnumerable<TwitterStatus> ListTweetsOnHomeTimeline(new ListTweetsOnHomeTimelineOptions { SinceId = 12345 ));
IEnumerable<TwitterStatus> ListTweetsMentioningMe(new ListTweetsMentioningMe { SinceId = 12345 ));

Dealing with Twitter API Rate Limiting

Twitter limits the frequency of all API calls in a variety of ways, to help ensure the service is not abused. This means that your applications will have to account for possible rate limit shortages at the user and API endpoint level. Client applications that are meant for public consumption usually use the rate limit profile of users that are logging in to their application. You can find out more about rate limiting at (https://dev.twitter.com/docs/rate-limiting/1.1).

TweetSharp provides two ways to access rate limiting data. You can either make an explicit API call to retrieve it, or inspect the TwitterResponse‘s RateLimitStatus property, if it’s available. The latter option conserves HTTP traffic, as the information is embedded in the HTTP response itself.

using TweetSharp;

TwitterService service = new TwitterService("consumerKey", "consumerSecret");
service.AuthenticateWith("accessToken", "accessTokenSecret");

// Option 1 - Retrieve from the API (a list of all endpoints and rates)
TwitterRateLimitStatusSummary rate = service.GetRateLimitStatus();

// Option 2 - Retrieve from the response (scoped to the last request)
IEnumerable<TwitterStatus> mentions = service.ListTweetssMentioningMe(new ListTweetsMentioningMeOptions());
TwitterRateLimitStatus rate = service.Response.RateLimitStatus;
Console.WriteLine("You have used " + rate.RemainingHits + " out of your " + rate.HourlyLimit);

Asynchronous Methods

TweetSharp supports executing methods asynchronously, and provides two styles of operation. The first is a delegate style, where you pass an Action into the named method after any optional parameters. ThisAction provides you with both the expected response that you would get if you called the method sequentially, as well as the response info you would have accessed on TwitterService‘s Response property.

Asynchronous operation (delegate style)

using TweetSharp;

TwitterService service = GetAuthenticatedService();
IAsyncResult result = service.ListTweetsOnHomeTimeline(
    (tweets, response) =>
        {
            if(response.StatusCode == HttpStatusCode.OK)
            {
                foreach (var tweet in tweets)
                {
                    Console.WriteLine("{0} said '{1}'", tweet.User.ScreenName, tweet.Text);
                }
            }
        });

In addition to delegate-based asynchronous methods, TweetSharp lets you simplify asynchronous operations with the familiar .NET Begin/End pattern. This style of operation involves calling the same methods as the synchronous style, but prefixing the method with Begin. Similarly, to retrieve the results you were looking for, you call the appropriate method beginning with End, with the option to provide a timeout value.

Asynchronous operation (begin/end style)

using TweetSharp;

var service = GetAuthenticatedService();
IAsyncResult result = service.BeginListTweetsOnHomeTimeline(new BeginListTweetsOnHomeTimelineOptions());
IEnumerable<TwitterStatus> tweets = service.EndListTweetsOnHomeTimeline(result);

foreach (var tweet in tweets)
{
    Console.WriteLine("{0} said '{1}'", tweet.User.ScreenName, tweet.Text);
}

Using Windows Phone

TweetSharp is designed with Windows Phone 7 in mind. Each sequential method on TwitterService also has an asynchronous equivalent for Windows Phone. Rather than expect a response, each method asks for a delegation Action to perform, which provides the expected result, as well as a wrapper class to help you handle unexpected results in your application.

using TweetSharp;

Dispatcher dispatcher = Deployment.Current.Dispatcher;
TwitterService service = new TwitterService("consumerKey", "consumerSecret");
service.AuthenticateWith("accessToken", "accessTokenSecret");

// Example: Getting Mentions
service.ListTweetsMentioningMe(new ListTweetsMentioningMeOptions(), (statuses, response) =>
{
    if(response.StatusCode == HttpStatusCode.OK)
    {
        foreach (var status in statuses)
        {
            TwitterStatus tweet = status;
            dispatcher.BeginInvoke(() => tweets.Items.Add(tweet));
        }
    }
    else
    {
        throw new Exception(response.StatusCode.ToString());
    }
});

// Example: Posting a Tweet
service.SendTweet(new SendTweetOptions { Status = "Tweeting with #tweetsharp for #wp7"}, (tweet, response) =>
{
    if (response.StatusCode == HttpStatusCode.OK)
    {
        dispatcher.BeginInvoke(() => tweets.Items.Add(tweet));
    }
    else
    {
        throw new Exception(response.StatusCode.ToString());
    }
});

Data Format Handling

By default, TweetSharp handles serialization and deserialization details for you. Twitter v1.1 only supports JSON serialization. the RawSource property on each model contains the JSON retrieved from Twitter for each object.

If you go one step further and decide you don’t trust our serializer, you can change TwitterService‘sSerializer and Deserializer properties, setting them to Hammock-compatible interfaces, andTwitterService will then defer to your custom serializer in all requests.

using TweetSharp;
using Hammock.Serialization;

MyAwesomeSerializer serializer = new MyAwesomeSerializer();
TwitterService service = new TwitterService("consumerKey", "consumerSecret");
service.Serializer = serializer;
service.Deserializer = serializer;

Handling Errors

There are three ways of handling errors at the Twitter API level.

  • You can use the TwitterResponse object to inspect details about the request and act accordingly. This object is available sequentially using TwitterService‘s Response property, which means the Responseproperty will update after each API call is complete. If you’re using Windows Phone 7, you get theTwitterResponse object passed into each Action delegate, so you know the response you’re accessing belongs to the request that’s returning through the callback.
  • TweetSharp uses a relaxed JSON parsing strategy to mitigate exceptions when API objects change. TweetSharp will return a null value if something went wrong, and the Response object’s TwitterErrorproperty will be populated with more details.
  • If you’re not confident with the deserialization of your object, you can use the RawSource property that exists on all Twitter model objects to inspect the actual JSON response that was returned by Twitter, specific to that object. This means if you returned a collection of tweets, each tweet’s RawSource will contain the JSON for that specific tweet. This is helpful if you want to perform custom parsing or tracing of the raw data.

Error Handling Examples (sequential service calls)

using TweetSharp;

TwitterService service = new TwitterService(_consumerKey, _consumerSecret)();

// Missing authentication; this call will fail
IEnumerable<TwitterStatus> mentions = service.ListTweetsMentioningMe(new ListTweetsMentioningMeOptinos()); 

// Look for bad requests by inspecting the response for important info
if(service.Response.StatusCode == HttpStatusCode.OK) // <-- Should be 401 - Unauthorized
{ 
    // Look for a null object if a real error, or serialization problem, occurred
    if(mentions == null)
    {
        // If a real error occurred, you can get it here        
        TwitterError error = service.Response.TwitterError;
        if(error != null)
        {
            // You now know you have a real error from Twitter, and can handle it
        }
        else
        {
            // It could be an issue with serialization, you can check the content
            var content = service.Response.Response;

            Console.WriteLine(content);

            // And try to deserialize it into something else
            var myError = service.Deserialize<MyTwitterError>(content);
        }
    }
}
else
{
    // Likely this is an error; we don't have to go fishing for it
    TwitterError error = service.Response.TwitterError;
    if(error != null)
    {
        // You now know you have a real error from Twitter, and can handle it
    }
}

Using Twitter Entities

TweetSharp supports Twitter’s entities feature. This feature provides additional metadata for locating mentions, links, and hashtags embedded in tweet text. TweetSharp goes a step further, emulating the entities support for classes that Twitter currently doesn’t support, that implement ITweetable; namely TwitterStatus,TwitterDirectMessage and TwitterSearchStatus. All three of these classes contain an Entities property. This allows you to find these elements in UI columns that contain multiple tweet types, via the ITweetableinterface. To retrieve all of the entities in an ITweetable ordered by where they appear in the text itself, you can call the Coalesce method on the relevant TwitterEntities instance.

Client Development Features

TweetSharp is a bit more than an API wrapper, it also provides support for client application development beyond the data. In this section, TweetSharp’s features specific to developing client applications on the .NET Framework are highlighted.

  • All model objects are [Serializable], implement IPropertyNotifyChanged, use virtual signatures, and implement DataContract / DataMember where supported. This means all of our model objects are persistable in frameworks like NHibernate, observable in WPF, and serializable for over-the-wire communication in WCF.
  • ITweetable and ITweeterTwitterStatusTwitterDirectMessage, and TwitterSearchStatus all implement ITweetable, which is an interface to make it easier to blend tweets from different sources into the same UI display. ITweeter helps encapsulate common user display properties, and TweetSharp even provides emulation of the entity metadata for non-timeline ITweetables; this means that you can access mentions, hashtags, and links embedded in the text of any ITweetable, in the order they appear.

These are the UI interfaces:

public interface ITweetable
{
    long Id { get; }
    string Text { get; }
    ITweeter Author { get; }
    DateTime CreatedDate { get; }
    TwitterEntities Entities { get; }
}

public interface ITweeter
{
    string ScreenName { get; }
    string ProfileImageUrl { get; }
}

Nov 19 2013

Facebook C# SDK – Glimpse into the Future

Mohammed Al-Atari

URL: http://blog.prabir.me/posts/facebook-csharp-sdk-glimpse-into-the-future

 

The Move

I’m excited to announce that Facebook C# SDK will be moving to a new home at Github (https://github.com/facebook-csharp-sdk/facebook-csharp-sdk) along with SimpleJson (https://github.com/facebook-csharp-sdk/simple-json).

Moving forward we will be using Github for source control and bugs/suggestions (all bugs from codeplex have already been migrated) and Github pages for documentation (https://github.com/facebook-csharp-sdk/facebook-csharp-sdk.github.com). Stackoverflow with tag “facebook-c#-sdk” will be used for asking questions.

NuGet packages will be used as primary distribution for compiled binaries. This means Github downloads will not contain all the releases for compiled binaries but rather the most recent binaries only. Developers using Visual Studio earlier then 2010 or Express Editions will require to use the nuget command line tool.

The Future

With the move to Github we are also announcing a pre-release version of vNEXT (v6.0.1-alpha). A lot has happened in the past few months with introduction to Enhanced OAuth Dialog, Open Graph and ETags to name a few that a time has come for us to rethink how we develop Facebook apps. This has lead us to completely rewrite v6 from scratch.

Tons of features has been added to v6 along with removal of existing features which doesn’t make much sense in the present context.

Anonymous Objects as Parameters

One of the most exciting feature to land in v6 is using anonymous object as parameters rather then Dictionary<string,object> or ExpandoObject. (Dictionary and ExpandoObject will continue to work).

var fb = new FacebookClient();
dynamic result = fb.Get("4", new { fields = new[] { "id", "name" } });

GZip/Deflate

GZip/Deflate has been enabled for desktop client profiles (.NET 3.5+). Currently only batch requests returns gzip responses. (https://developers.facebook.com/bugs/235553716524315)

FacebookMediaStream

Rather then converting stream to byte array and using FacebookMediaObject, you can now directly work with FacebookMediaStreams.Stream used in FacebookMediaStream must be manually disposed.

var fb = new FacebookClient(accessToken);
string attachementPath = @"C:\image.jpg";

using (var stream = File.OpenRead(attachementPath))
{
    dynamic result = fb.Post("me/photos",
                                new
                                    {
                                        message = "upload using Facebook C# SDK",
                                        file = new FacebookMediaStream
                                                {
                                                    ContentType = "image/jpg",
                                                    FileName = Path.GetFileName(attachementPath)
                                                }.SetValue(stream)
                                    });
}

ETags

You can now optimize your graph api’s using ETags. For etag you need to pass the special parameter called _etag_

For the first request it should be empty string. _etag_ is specific to Facebook C# SDK.

dynamic result1 = fb.Get("me", new { fields = "id,name", _etag_ = string.Empty});

This will tell the fb c# sdk to return a JsonObject with headers and body.

dynamic headers = result1.headers; // JsonObject of headers.
dynamic body = result1.body; // The actual json response.
// to access the actual json response use result.body.x instead of just result.x
string id = result1.body.id;

Then you can use the etag from the previous response to get the next responses.

dynamic result2 = fb.Get("me", new {fields = "id,name", _etag_ = result1.headers.ETag});
dynamic headers = result1.headers;
// always check if the response has a body.
if(result2.ContainsKey("body")) {
    // we've got the updated response.
    string id = result1.id;
}
else {
    // the last request was the latest.
    // so do nothing.
}

Note: result1.header.ETag (make sure ETag contains the right capitalization). It is exactly how Facebook returns the response header.
when _etag_ is string.Empty it will always return a body, so you don’t need to check result1.ContainsKey(“body”) for it.

ETag support in batch requests

var fb = new FacebookClient(accessToken);

dynamic result = fb.Batch(
    new FacebookBatchParameter("me", new { _etag_ = string.Empty }),
    new FacebookBatchParameter("me", new { _etag_ = "\"ac9e51b60e883e294cc98f35f70a1ec8fdf0e736\"" }),
    new FacebookBatchParameter("me") { Data = new { headers = new Dictionary<string, object> { { "If-None-Match", "\"ac9e51b60e883e294cc98f35f70a1ec8fdf0e736\"" } } } });

Removal of Query/QueryAsync/QueryTaskAsync method

Now that Facebook official supports Fql using graph api, we are removing the Query methods from FacebookClient.

In v6 you can execute Fql query using the following methods.

Single Fql

var result = fb.Get("fql", new { q = "SELECT uid from user where uid=me()" });

MultiQuery Fql:

var resultMulti = fb.Get("fql", new
                                    {
                                        q = new[]
                                                {
                                                    "SELECT uid from user where uid=me()",
                                                    "SELECT name FROM user WHERE uid=me()"
                                                }
                                    });

Named Muliquery:

var resultMultiNamed = fb.Get("fql",
                            new
                                {
                                    q = new
                                    {
                                        id = "SELECT uid from user where uid=me()",
                                        name = "SELECT name FROM user WHERE uid IN (SELECT uid FROM #id)",
                                    }
                                });

Removal of Facebook.Web.dll and Facebook.Web.Mvc.dll

Starting from v6, we are depreciating Facebook.Web.dll and Facebook.Web.Mvc.dll and will no longer be providing it. Over the year we have seen lot of developers using the server side (ASP.NET) as a proxy to Facebook rather then using the Facebook Javascript SDK. We highly encourage users to use both Facebook Javascript SDK and Facebook C# SDK where appropriate. We will continue to support earlier version in v5 branch. Rather then provide Facebook.Web.dll and Facebook.Web.Mvc.dll we will be creating a new repositories in github showing best practices on how to create Facebook apps, Canvas Apps, Windows Phone Apps.

Attributes such as CanvasAuthorize doesn’t make much sense now as the user is now allowed to remove certain permissions and yet grant access to your app when using Enhanced OAuth Dialog. Currently with v5, you will end up with redirect loop incase the user removes the permission.

Since decoding Facebook cookies are not official supported nor documented by Facebook, we are also removing FacebookWebClient. Lot of bug reports in Facebook C# SDK has been based on cookie issues. Starting from v6, you will have to use the Facebook Javascript SDK to get the access token and pass it to the server using secure https connection or use the Facebook OAuth Login Dialog.

Decoding signed request (ParseSignedRequest/TryParseSignedRequest) has been moved to FacebookClient instead.

var fb = new FacebookClient();
dynamic signedRequest = fb.ParseSignedRequest("app_secret", Request.Params["signed_request"]);

Documentation

You can find the documentation of Facebook C# SDK at http://docs.csharpsdk.org/. You can fork https://github.com/facebook-csharp-sdk/facebook-csharp-sdk.github.com/tree/master/docs repository and send us pull requests.

Although we think the current pre-release of v6 has been highly improved in the API point of view, we are still open to changes depending on the feedback we receive. We would love to hear your feedback before the beta release and the final RTW.

Install-Package Facebook -version 6.0.1-alpha

 


Nov 15 2013

Push Notifications with PushSharp for Andriod/Apple/Windows in Vb.net/C#

Mohammed Al-Atari

URL: https://github.com/Redth/PushSharp
Video: http://www.youtube.com/watch?v=MytQ6vqrE5g
S
lide: http://www.slideshare.net/Xamarin/push-notifications-introduction-to-pushsharp-seminar

I Love this control, it help me a lot

A server-side library for sending Push Notifications to iOS (iPhone/iPad APNS), OSX (APNS 10.8+) Android (C2DM and GCM – Google Cloud Message), Chrome (GCM) Windows Phone, Windows 8, Blackberry (PAP), and Amazon (ADM) devices!

PushSharp-Diagram


Nov 12 2013

Android: Scarce Commodities , Memory, and Bitmaps

Mohammed Al-Atari

URL:http://davidjhinson.wordpress.com/2010/05/19/scarce-commodities-google-android-memory-and-bitmaps/
Working on mobile devices forces one to make conscious decisions regarding coding choices, if for no other reason that resources are scarce (memory, screen size, bandwidth). Taking the easy route and ignoring wise mobile programming practices can take what could be a promising application and make it a disappointing user experience.

If you’ve spent any time with the Google Android SDK, and have tried to read a JPEG into a Bitmap using Media.getBitmap, you’ve almost certainly run into this little gem of an error message:

bitmap size exceeds VM budget

Unfortunately, since Android caps all applications’ VMs at 16MB in size, it only takes one or two big image reads to get you into trouble, regardless of all the garbage collection and Bitmap recycles you may try (see code snippet at the end of this post for more on that).

So, what’s a programmer to do?

Well, the only thing one can do is to read only what you need into memory. That means that you won’t be able to read in that 10MB jpeg sitting on your phone (at least, you won’t be able to read it reliably and / or repeatably) without trimming it down a bit.

The code below will do this for you; rather than calling Media.getBitmap, use this readBitmap function instead:

// Read bitmap
public Bitmap readBitmap(Uri selectedImage) {
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 5;
AssetFileDescriptor fileDescriptor =null;
try {
fileDescriptor = this.getContentResolver().openAssetFileDescriptor(selectedImage,”r”);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally{
try {
bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
fileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return bm;
}

The magic fairy dust in this function that allows you to trim down large bitmaps into digestible sizes is the options.inSampleSize property. inSampleSize – in this instance – takes a bitmap and reduces its height and width to 20% (1/5) of its original size. The larger the value of inSampleSize N (where N=5 in our example), the more the bitmap is reduced in size.

There’s also another coding practice that one should always use when dealing with Bitmaps in Android, and that is the use of the Bitmap recycle() method. The recycle() method frees up the memory associated with a bitmap’s pixels, and marks the bitmap as “dead”, meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing.

In my projects, I have a helper function that does cleanup when I am finished using a Bitmap, named clearBitmap:

// Clear bitmap

public static void clearBitmap(Bitmap bm) {

bm.recycle();

System.gc();

}

Dealing with memory errors on Android apps seems to be the “problem child” issue that crops up the most (like too many threads on Blackberry apps – different post for a different day).

But like parenting a problem child, what’s called for is attention and intention to mitigate havoc wreaked.


Nov 11 2013

Android: Showing Badge or Count in App Icon

Mohammed Al-Atari

URL: http://derivedcode.wordpress.com/2013/10/09/showing-badge-or-count-in-android-app-icon/

Showing a badge or count in an Android application is the capability that is supported by launcher application. Android launcher by default does not support the use of badges or counts while they list the application icons. In some android phones like Galaxy S3 etc, we can see that applications like facebook and email client is capable of displaying the count on their application icon, its actually with the help of the samsung launcher (You can google to get the code for the same). But when we consider creating an android application, it should behave the same in all phones with different launchers. We can create a launcher for this purpose, but its not pratical to give our launcher along with our application, because the user might be used with using some other launchers.

So as a workaround, we can make use of the activity-alias in the Android Manifest.

1. As your first step, you need to create app icons with different badges. Say for example, in your application, if you need to show the unread count of messages, you can create app icons with : no-count, count as 1 to 10, count as 10+ (Planning to show the icon with no count, count from 1 to 10 and if more, show it as 10+)

2. Then in manifest for your launcher activity, create activity-aliases which corresponds to the app icons created. In the below example, the launcher activity is MainActivity and I’ve created activity-aliases for the same activity for each app icon naming from a1 to a10 and a10p

<application
    android:allowBackup="true"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.study.MainActivity"
        android:enabled="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity-alias
        android:name=".a1"
        android:enabled="false"
        android:icon="@drawable/icon_1"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a2"
        android:enabled="false"
        android:icon="@drawable/icon_2"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a3"
        android:enabled="false"
        android:icon="@drawable/icon_3"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a4"
        android:enabled="false"
        android:icon="@drawable/icon_4"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a5"
        android:enabled="false"
        android:icon="@drawable/icon_5"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a6"
        android:enabled="false"
        android:icon="@drawable/icon_6"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a7"
        android:enabled="false"
        android:icon="@drawable/icon_7"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a8"
        android:enabled="false"
        android:icon="@drawable/icon_8"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a9"
        android:enabled="false"
        android:icon="@drawable/icon_9"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a10"
        android:enabled="false"
        android:icon="@drawable/icon_10"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
    <activity-alias
        android:name=".a10p"
        android:enabled="false"
        android:icon="@drawable/icon_10p"
        android:label="@string/app_name"
        android:targetActivity="com.example.study.MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
</application> 

3. After creating the activity aliases, to show the appropriate count for the application icon, you need to use the functionality of Enabling and Disabling Manifest Components.

For Example, if your current app icon is showing no count and you need to show the count as 5, then you need to disable the Manifest component “com.example.study.MainActivity” and enable the component “com.example.study.MainActivity.a5″

Code :

Random r = new Random();
        int value = r.nextInt(15); //Your value to show as badge.
        Log.i("DEMO", "Changing : " + value);

        PackageManager pm = getApplicationContext().getPackageManager();

        String lastEnabled = getLastEnabled(); //Getting last enabled from shared preference

        if (TextUtils.isEmpty(lastEnabled)) {
            lastEnabled = "com.example.study.MainActivity";
        }

        ComponentName componentName = new ComponentName(
                "com.example.study", lastEnabled);
        pm.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

        Log.i("DEMO", "Removing : " + lastEnabled);

        if (value <= 0) {
            lastEnabled = "com.example.study.MainActivity";
        } else if (value <= 10) {
            lastEnabled = "com.example.study.a" + value;
        } else {
            lastEnabled = "com.example.study.a10p";
        }

        componentName = new ComponentName("com.example.study",
                lastEnabled);
        pm.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
        Log.i("DEMO", "Adding : " + lastEnabled);
        setLastEnabled(lastEnabled); //Saving last enabled to shared pref

Method to save to preference :

private void setLastEnabled(String value) {
    SharedPreferences pref = PreferenceManager
            .getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = pref.edit();
    editor.putString("LastEnabled", value);
    editor.commit();
}

Method to fetch from Shared preference :

private String getLastEnabled() {
    SharedPreferences pref = PreferenceManager
            .getDefaultSharedPreferences(getApplicationContext());
    return pref.getString("LastEnabled", "");
}

Please keep in mind that even if we enable and disable the component, it will take some time to reflect in the UI, say 15 seconds. Because, the home activity refreshes based on following broadcasts : package_changed, package_added and package_removed , which all are protected broadcasts which can be initiated by system only.

Sample project : (In which the app icon changes in every 15 seconds.)

https://github.com/eldhosembabu/mathokkil


Nov 11 2013

Android : How to change an application icon programmatically in Android? (Badge or Count)

Mohammed Al-Atari

URL:http://stackoverflow.com/questions/1103027/how-to-change-an-application-icon-programmatically-in-android

It’s an old question, but still active as there is no explicit Android feature. And the guys from facebook found a work around – somehow. Today, I found a way that works for me. Not perfect (see remarks at the end of this answer) but it works!

Main idea is, that I update the icon of my app’s shortcut, created by the launcher on my home screen. When I want to change something on the shortcut-icon, I remove it first and recreate it with a new bitmap.

Here is the code. It has a button increment. When pressed, the shortcut is replaced with one that has a new counting number.

First you need these two permissions in your manifest:

<uses-permission android:name=”com.android.launcher.permission.INSTALL_SHORTCUT” />
<uses-permission android:name=”com.android.launcher.permission.UNINSTALL_SHORTCUT” />

Then you need this two methods for installing and uninstalling shortcuts. The shortcut Add method creates a bitmap with a number in it.This is just to demonstrate that it actually changes. You probably want to change that part with something, you want in your app.

// Create bitmap with number in it -> very default. You probably want to give it a more stylish look
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
paint.setColor(0xFF808080); // gray
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(50);
new Canvas(bitmap).drawText(“”+number, 50, 50, paint);
((ImageView) findViewById(R.id.icon)).setImageBitmap(bitmap);

// Decorate the shortcut
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);

// Inform launcher to create shortcut
addIntent.setAction(“com.android.launcher.action.INSTALL_SHORTCUT”);
getApplicationContext().sendBroadcast(addIntent);
}

private void shortcutDel(String name) {
// Intent to be send, when shortcut is pressed by user (“launched”)
Intent shortcutIntent = new Intent(getApplicationContext(), Play.class);
shortcutIntent.setAction(Constants.ACTION_PLAY);

// Decorate the shortcut
Intent delIntent = new Intent();
delIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
delIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

// Inform launcher to remove shortcut
delIntent.setAction(“com.android.launcher.action.UNINSTALL_SHORTCUT”);
getApplicationContext().sendBroadcast(delIntent);
}

And finally, here are two listener to add the first shortcut and update the shortcut with an incrementing counter.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.test);
findViewById(R.id.add).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
shortcutAdd(“changeIt!”, count);
}
});
findViewById(R.id.increment).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
shortcutDel(“changeIt!”);
count++;
shortcutAdd(“changeIt!”, count);
}
});
}

Remarks:

  • This way works also if your App controls more shortcuts on the home screen, e.g. with different extra’s in the Intent. They just need different names so that the right one is uninstalled and reinstalled.
  • The programmatically handling of shortcuts in Android is a well known, widely used but not officially supported Android feature. It seems to work on the default launcher and I never tried it anywhere else. So dont blame me, when you get this user-emails “It does not work on my XYZ, double rooted, super blasted phone”
  • The launcher writes a Toast when a shortcut was installed and one when a shortcut was uninstalled. So I get two Toasts every time I change the icon. This is not perfect, but well, as long as the rest of my app is perfect…

Sep 15 2013

Count checked checkboxes and Check / Uncheck all checkboxes in DataList

Mohammed Al-Atari

URL:http://jiushizhutk.com/wordpress/?p=196

In data controls like DataList, to count the number of checked checkboxes and to check / uncheck all checkboxes are two common functionality. Following is a simple way to implement this.

The DataList structure is something like this with “all” checkbox in HeaderTemplate and individual checkbox in ItemTemplate:

<asp:DataList ID=”DLSample” runat=”server” OnItemDataBound=”dl_OnItemDataBound”>  <HeaderTemplate>   <table>    <tr>     <td>      <asp:CheckBox ID=”cbAll” runat=”server” Text=”All”/>     </td>    </tr>  </HeaderTemplate>  <ItemTemplate>   <tr>    <td style=’width: 10%; text-align: left;’>     <asp:CheckBox ID=”cb” runat=”server”/>    </td>   </tr>  </ItemTemplate>  <AlternatingItemTemplate>   <tr>    <td>     <asp:CheckBox ID=”cb” runat=”server”/>    </td>   </tr>  </AlternatingItemTemplate>  <FooterTemplate>   </table>  </FooterTemplate> </asp:DataList>

1. Register checkbox’s onclick events in DataList’s OnItemDataBound event.

protected void dl_OnItemDataBound(object sender, DataListItemEventArgs e) {  if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)  {   ((CheckBox)e.Item.FindControl(“cb”)).Attributes.Add(“onclick”, “CountChecked();”);  }  else if (e.Item.ItemType == ListItemType.Header)  {   CheckBox cb = (CheckBox)e.Item.FindControl(“cbAll”);   cb.Attributes.Add(“onclick”, “CheckUncheckAll(” + cb.ClientID + “);”);  } }

2. Write the javascript funtion to loop through all individual checkboxes and count the number of checked checkboxes

function CountChecked() {  var dl = document.getElementById(“<%=DLSample.ClientID %>”);  var inputs = dl.getElementsByTagName(“input”);  var count = 0;  for (var i = 0; i < inputs.length; i++) {   if (inputs[i].checked == true && inputs[i].type == “checkbox”) {    count++;   }  }  var lbl = document.getElementById(“<%=lblCheckBox.ClientID %>”);  lbl.innerHTML = count; }

3. Write the javascript to check / uncheck all checkboxes when checking / unchecking that “all” checkbox

function CheckUncheckAll(cb) {  var count = 0;  var dl = document.getElementById(“<%=DLSample.ClientID %>”);  var inputs = dl.getElementsByTagName(“input”);  for (var i = 0; i < inputs.length; i++) {   if (inputs[i].type == “checkbox” && inputs[i] != cb) {    inputs[i].checked = cb.checked;    count++;   }  }  var lbl = document.getElementById(“<%=lblCheckBox.ClientID %>”);  if (cb.checked == true)   lbl.innerHTML = count;  else   lbl.innerHTML = “0″; }

View the sample at the link below :

CheckBoxes Sample