📜 ⬆️ ⬇️

Create a visual search in IE8 to search for friends on Twitter


With the release of IE8 we got one of the most convenient features in the browser - Visual Search Suggestions.

This article will show how to implement a friend search on Twitter, through a special Visual Search string in IE8. As you type the name, we will see the avatar, the name that the friend has filled out and the current status.
The guide is based on the article Search Provider Extensibility in Internet Explorer from MSDN.


We build WCF REST service.


Create a new Empty Web Site, call it TwitterFriendsSearch

')
Add a new item to the project, WCF Service and call it SuggestService.svc.



This will create the following files:
We change the definition of a service contract (ISuggestService.cs) as follows:
[ServiceContract]
public interface ISuggestService
{
[OperationContract]
string Search( string friend);
}

Open the service implementation (SuggestService.cs). To begin with we will make simple implementation, we will change it a bit later.
public class SuggestService : ISuggestService
{
public string Search( string friend)
{
return "Hello, " + friend;
}
}

To ensure REST support, we add a required WebGet attribute over the service action.
[OperationContract]
[WebGet(UriTemplate = "/Search?q={friend}" ,
BodyStyle = WebMessageBodyStyle.Bare)]
string Search( string friend);

Change WCF service settings (web.config) to support REST. Position the behaviors node and add a new behavior target, under the System.serviceModel section:
< system.serviceModel >
...
< behaviors >
...
< endpointBehaviors >
< behavior name ="REST" >
< webHttp />
</ behavior >
</ endpointBehaviors >
...
</ behaviors >
...
</ system.serviceModel >

In the same section, we place the ad service and location. Replace the wsHttpBinding binding with the webHttpBinding and add the location behavior:
< services >
< service behaviorConfiguration ="SuggestServiceBehavior"
name ="SuggestService" >
< endpoint address =""
binding ="webHttpBinding"
contract ="ISuggestService"
behaviorConfiguration ="REST" />
</ service >
</ services >

Run the project and go to the .svc file. Next, add the UriTemplate, which we announced in the service, with the name of a friend to search:

localhost : 50434 / TwitterFriendsSearch / SuggestService.svc / search? q = guy

The answer should look like “hello, guy”.

We return the search result.


According to the MSDN page, the link to which I cited earlier, the final answer for a visual search should look like this (this answer corresponds to the image I attached at the beginning of the article):
<? xml version ="1.0" encoding ="utf-8" ? >
< SearchSuggestion >
< Query > guy </ Query >
< Section >
< Item >
< Text > guyhaim </ Text >
< Description > @rohitbhargava tinyurl.com/6m9e4g </ Description >
< Url > twitter.com/home </ Url >
< Image source ="http://...normal.jpg"
height ="48" width ="48" alt ="guyhaim" />
</ Item >
< Item >
< Text > Guy Malachi </ Text >
< Description > Yahoo toolbar looks kinda weird. </ Description >
< Url > twitter.com/home </ Url >
< Image source ="http://...normal.jpg"
height ="48" width ="48" alt ="guym" />
</ Item >
< Item >
< Text > guy zohar </ Text >
< Description > switch screen </ Description >
< Url > twitter.com/home </ Url >
< Image source ="http://...normal.jpg"
height ="48" width ="48" alt ="guyzo" />
</ Item >
< Item >
< Text > guyzarz </ Text >
< Description > @ekampf May it rest in peace, in one piece. </ Description >
< Url > twitter.com/home </ Url >
< Image source ="http://...normal.jpg"
height ="48" width ="48" alt ="guyzarz" />
</ Item >
</ Section >
</ SearchSuggestion >

Create the following classes to represent the elements of the response, use the attributes of Xml serialization, to further serialize them to the desired result.
// Image.cs
[XmlType]
public class Image
{
[ XmlAttribute (AttributeName= "source" )]
public string Source { get ; set ; }

[ XmlAttribute (AttributeName = "height" )]
public int Height { get ; set ; }

[ XmlAttribute (AttributeName = "width" )]
public int Width { get ; set ; }

[ XmlAttribute (AttributeName = "alt" )]
public string Alt { get ; set ; }
}
// Item.cs
[XmlType]
public class Item
{
[XmlElement]
public string Text { get ; set ; }

[XmlElement(IsNullable= false )]
public string Description { get ; set ; }

[XmlElement(IsNullable = false )]
public string Url { get ; set ; }

[XmlElement(IsNullable = false )]
public Image Image { get ; set ; }
}

// SearchSuggestion.cs
[XmlRoot(Namespace= "" )]
public class SearchSuggestion
{
public SearchSuggestion()
{
this .Section = new List <Item>();
}

[XmlElement]
public string Query { get ; set ; }

[XmlArray]
public List <Item> Section { get ; set ; }
}

Change the service contract to return a SearchSuggestion response instead of a string. Also add the XmlSerializerFormat attribute to make sure that the response will be serialized to XML.
[ServiceContract]
public interface ISuggestService
{
[OperationContract]
[WebGet(UriTemplate = "/Search?q={friend}" ,
BodyStyle = WebMessageBodyStyle.Bare)]
[XmlSerializerFormat]
SearchSuggestion Search( string friend);
}

Now we return in the Search SearchSuggestion method with default values ​​instead of a string.
public SearchSuggestion Search( string friend)
{
SearchSuggestion suggestion = new SearchSuggestion
{
Query = friend
};

suggestion.Section.Add( new Item
{
Text = friend,
Description = "Hello, " + friend,
Url = "http://blogs.microsoft.co.il/blogs/bursteg" ,
Image = new Image
{
Source = "http://tinyurl.com/burstegprofileimage" ,
Alt = "Guy Burstein" ,
Width = 48,
Height = 48
}
});

return suggestion;
}

If we now start the project and go back to the link that we used earlier, we should get the following result:
<? xml version ="1.0" encoding ="utf-8" ? >
< SearchSuggestion xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd ="http://www.w3.org/2001/XMLSchema" >
< Query > omer </ Query >
< Section >
< Item >
< Text > omer </ Text >
< Description > Hello, omer </ Description >
< Url > blogs.microsoft.co.il/blogs/bursteg </ Url >
< Image source ="http://tinyurl.com/burstegprofileimage"
height ="48"
width ="48"
alt ="Guy Burstein" />
</ Item >
</ Section >
</ SearchSuggestion >


Adding a visual search in Internet Explorer


Add a new Xml file to the project and call it FriendsSuggestion.xml. This file contains detailed information about the browser search plugin and should look like this:
<? xml version ="1.0" encoding ="UTF-8" ? >
< OpenSearchDescription xmlns ="http://a9.com/-/spec/opensearch/1.1/" >
< ShortName > Friends Search </ ShortName >
< Url type ="text/html"
template ="http://localhost:50434/TwitterFriendsSearch/
SuggestService.svc/search?q={searchTerms}"
/>
< Url type ="application/x-suggestions+xml"
template ="http://localhost:50434/TwitterFriendsSearch/
SuggestService.svc/search?q={searchTerms}"
/>
< Image height ="16"
width ="16"
type ="image/icon" > twitter.com/favicon.ico </ Image >
</ OpenSearchDescription >

Add the Default.aspx page. Create a JavaScript function in it that registers the plugin in the browser:
< script type ="text/javascript" >
function Register() {
window.external.AddSearchProvider( 'FriendsSuggestion.xml' );
}
</ script >

Create an HTML button that will register the search plugin.
< form id ="form1" runat ="server" >
< div >
< button onclick ='Register();' > Click Here </ button >
</ div >
</ form >

Run the project again, go to Default.aspx. Click on the button.



Now we go to the search field, try to write there the name of a friend. At this stage, we will see only the default value, since we did not implement the search support on Twitter.



Find friends on Twitter


Finally, we got to implement the search for friends on Twitter, but this part of the code can be changed to suit your needs.
In the implementation of the service, delete the default values ​​and make an HTTP request to Twitter to get a list of friends (replace “bursteg” with your login)
string url = string .Format(
"http://twitter.com/statuses/friends/{0}.xml" , "bursteg" );
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
reader.Close();

Next, use Linq2Xml to parse the answer and get a list of friends, according to the search criteria:
XDocument document = XDocument .Parse(response, LoadOptions.None);
var query = from e in document.Root.Descendants( "user" )
where e.Element( "name" ).Value.Contains(friend) ||
e.Element( "screen_name" ).Value.Contains(friend)
select new Item
{

Text = e.Element( "name" ).Value,
Image = new Image
{
Source = e.Element( "profile_image_url" ).Value,
Alt = e.Element( "screen_name" ).Value,
Width = 48,
Height = 48
},
Description = (e.Element( "status" ) == null ? "" :
HttpUtility.HtmlDecode(e.Element( "status" ).Element( "text" ).Value)),
Url = ( String .IsNullOrEmpty(e.Element( "url" ).Value) ?
"http://twitter.com/home" :
e.Element( "url" ).Value)
};

Finally, add these items to the search tip.
suggestion.Section.AddRange(query);

The full version of the Search method should look like this:
public SearchSuggestion Search( string friend)
{
SearchSuggestion suggestion = new SearchSuggestion();
suggestion.Query = friend;

string url = string .Format( "http://twitter.com/statuses/friends/{0}.xml" , "bursteg" );
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
reader.Close();

XDocument document = XDocument .Parse(responseString, LoadOptions.None);
var query = from e in document.Root.Descendants( "user" )
where e.Element( "name" ).Value.Contains(friend) ||
e.Element( "screen_name" ).Value.Contains(friend)
select new Item
{

Text = e.Element( "name" ).Value,
Image = new Image
{
Source = e.Element( "profile_image_url" ).Value,
Alt = e.Element( "screen_name" ).Value,
Width = 48,
Height = 48
},
Description = (e.Element( "status" ) == null ? "" :
HttpUtility.HtmlDecode(e.Element( "status" ).Element( "text" ).Value)),
Url = ( String .IsNullOrEmpty(e.Element( "url" ).Value) ?
"http://twitter.com/home" :
e.Element( "url" ).Value)
};

suggestion.Section.AddRange(query);
return suggestion;
}

Now when we are looking for a friend, we will see his name, avatar and current status in the search suggestions.


Source code of the project.

Source: https://habr.com/ru/post/68226/


All Articles