European Silverlight 4 & Silverlight 5 Hosting BLOG

BLOG about Silverlight 5 Hosting and Its Techologies - Dedicated to European Windows Hosting Customer

European WCF Hosting :: RIA Services and Authentication

clock October 12, 2011 08:22 by author Scott

Authentication is the third in a series of posts covering the key concepts of RIA Services using the Book Club application to digger deeper and go beyond the basics. Links to the first two posts on validation and authorization as well as an overview of the application/source code are at the end of this post.

Authentication Overview

Like authorization, RIA Services provides a higher level programming model, and out-of-the-box, but extensible solution. Authentication answers the question:

"Do these credentials represent a valid user?"

Credentials might be user name and password, or any other piece of data that can be used to verify that the user is who he/she says they are. Generally, a side-effect of authentication is to produce a representation of the user, usually represented as an IPrincipal, as well as establishing an authenticated session for the client to use in making subsequent requests.

RIA Service defines an authentication service as a domain service that implements IAuthetication<TUser> where TUser is application's notion of a user that brings together identity, roles and settings that span across client and server.

RIA Services also provides an out-of-box implementation based on the standard asp.net membership, roles and profile infrastructure services. If you use the business application template, this is all setup for you by default. However RIA Services also lets you implement your own authentication service when you want to use your own custom credential store, or a different authentication mechanism such as OpenID.

This post covers using authentication and the User object on client and server, as well as building a custom forms authentication service that works against the application's data model.

Using Authentication on the Client

I created an inplace-LoginControl with a number of visual states (Unauthenticated, CredentialInput, Authenticating and Authenticated) as shown here.



Authentication functionality is accessed through a class called WebContext on the client. WebContext represents the functionality provided by the home web server to the client application. This is how WebContext is initialized in the application:

public partial class WebContext {

    partial void OnCreated() {
        Authentication = new FormsAuthentication() {
            DomainContext = new AuthenticationContext()
        };
    }
}

The FormsAuthentication implementation uses a DomainContext to work against the corresponding DomainService implementing IAuthentication on the server. We'll see this service implementation below.

Looking at LoginControl implementation, the authentication-related functionality is invoked when the Submit and Logout buttons are clicked:

private void OnSubmitButtonClick(object sender, RoutedEventArgs e) {
    LoginParameters loginParameters =
        new LoginParameters(userNameTextBox.Text, passwordBox.Password);

    WebContextBase.Current.Authentication.Login(loginParameters,
        delegate(LoginOperation operation) {
            if (operation.HasError || (operation.LoginSuccess == false)) {
                MessageBox.Show(...);
                operation.MarkErrorAsHandled();
                return;
            }

            // Use the resulting User object
            userLabel.Text = "Welcome " + WebContext.Current.User.DisplayName;
        }, null);
}

private void OnLogoutButtonClick(object sender, RoutedEventArgs e) {
    WebContextBase.Current.Authentication.Logout(/* throwOnError */ false);
}

The resulting User object can be used imperatively as shown in the code above, or declaratively via data-bindings.

Using Authentication on the Server

The User object can also be used on the server, for example by other domain services. Here is a snippet of code from the BookShelfService:


[RequiresAuthentication]
public class BookShelfService : LinqToEntitiesDomainServiceEx<BookClubEntities> {
    private User _user;

    public BookShelfService(User user) {
        _user = user;
    }

    public IQueryable<Book> GetBooks() {
        return ObjectContext.Books.Where(b => b.MemberID == _user.MemberID).
                                    OrderByDescending(b => b.AddedDate);
    }

    public override void Initialize(DomainServiceContext context) {
        base.Initialize(context);

        // This allows authorization rules to get access to the current user
        AuthorizationContext customAuthContext =
            new AuthorizationContext(context);
        customAuthContext.Items[typeof(User)] = _user;

        AuthorizationContext = customAuthContext;
    }
}

The domain service has been marked with the authorization rule stating the service requires authentication. Consequently, RIA Services will ensure that there is a valid IPrincipal whenever this service is invoked. However, the service also requires a User object to be passed in into constructor, so it can use it when retrieving shared by the current user, or when initializing an AuthorizationContext to pass along the User in into authorization rules.

In order to pass in custom values through the constructor, one needs to implement a custom DomainServiceFactory. The default one only works for domain services with default parameterless constructors. In the application, I have implemented a simple domain service factory, that uses hardcoded logic, but in a larger application, the general idea is to use an IoC container and call into that from the custom DomainServiceFactory.

internal sealed class DomainServiceFactory : IDomainServiceFactory {
    private IDomainServiceFactory _defaultFactory;

    public DomainServiceFactory(IDomainServiceFactory defaultFactory) {
        _defaultFactory = defaultFactory;
    }

    public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context) {
        if ((domainServiceType == typeof(BookShelfService)) ||

            (domainServiceType == typeof(BookClubService))) {
            User currentUser =
                Authentication.GetUser<User, AuthenticationService>(context);

            DomainService domainService =
                (DomainService)Activator.CreateInstance(domainServiceType,
                                                        currentUser);
            domainService.Initialize(context);

            return domainService;
        }

        return _defaultFactory.CreateDomainService(domainServiceType, context);
    }

    public void ReleaseDomainService(DomainService domainService) {
        if ((domainService is BookShelfService) ||
            (domainService is BookClubService)) {
            domainService.Dispose();
        }
        else {
            _defaultFactory.ReleaseDomainService(domainService);
        }
    }

    public static void Setup() {
        // Call this from Global.asax.cs in the Application's Start event handler
        if (!(DomainService.Factory is DomainServiceFactory)) {
            DomainService.Factory =
                new DomainServiceFactory(DomainService.Factory);
        }
    }
}

Notice the use of the helper class, Authentication, that allows you to correctly instantiate the authentication service on the server, invoke it and retrieve the User object corresponding to the current authenticated principal. This helper class is in the RIAEssentials framework (link below). The resulting User object is passed in when constructing BookShelfService.

Book Club Data Model

Before we see the actual Authentication service implementation It is worth taking a quick look at the data model behind the Book Club application:




As you see, one of the tables is the Member table. It is intrinsically tied to various other tables by virtue of multiple associations. It also contains information about the user, such as display name, last login date, joined date etc. As such, I'd like my authentication implementation to use this Member table from my data model directly.

The User Object

One of the key things to think about in your application is what constitutes the User object than spans across client and server. What is the state you want to expose to the client for visualization purposes, and what is the state you want to have quick access to within the context of an authenticated session? These are the questions to ask.


The UserBase object provides the ability to track Name and Roles. The User object in the application is defined as follows to add additional properties:

public class User : UserBase {
    public string DisplayName { get; set; }
    public int MemberID { get; set; }
}

I added DisplayName, so it can be used on the client in the UI. I also added the MemberID, so this information can be used on the server on subsequent requests (for example, when doing authorization to ensure a user can only update a book they own - see the authorization post for that example). The User object will be populated from the Member entity from the data model.

Implementing Authentication

Authentication builds on the same domain services infrastructure you use to define your operations/tasks in your application. There are two approaches to implementing authentication:

1. Derive from the out-of-box AuthenticationService base class. This provides a default implementation that leverages the asp.net membership, roles and profile infrastructure.

2. Implement IAuthentication on your domain service and do whatever you like based on your unique scenarios when implementing Login, Logout and other methods of the interface. This is especially useful if you're not using the asp.net infrastructure services or want to use some custom auth mechanism.

In my case, I want to use my own DAL and its notion of members, so I am going to build my own custom authentication service. However, I don't really want to implement the intricacies of forms authentication, which aren't specific to my application, such as setting up HTTP cookies. I only want to write the parts that interact with my data model (very much in spirit with the rest of RIA Services - focus on your application logic, and not the on-wire or service plumbing).

I am going to use a base class called FormsAuthenticationService which implements the guts of forms authentication, and is provided as part of the RIAEssentials framework, that you can easily reuse in your own applications. With that handy base class, here is all I have to do is implement ValidateCredentials, and produce a valid User object using my data model:

[EnableClientAccess]
public class AuthenticationService : FormsAuthenticationService<User> {

    protected override User ValidateCredentials(string name, string password, string customData) {
        User user = null;
        using (BookClubEntities bookClubObjectContext = new BookClubEntities()) {
            Member member =
                bookClubObjectContext.Members.Where(m => m.MemberAlias == name).
                                              FirstOrDefault();

            if ((member != null) &&
                Authentication.ValidatePassword(password, member.PasswordHash)) {
                user = new User() {
                    Name = name,
                    MemberID = member.MemberID,
                    DisplayName = member.MemberName
                };

                if (member.LoginDate != DateTime.UtcNow.Date) {
                    member.LoginDate = DateTime.UtcNow.Date;
                    bookClubObjectContext.SaveChanges();
                }
            }
        }

        return user;
    }
}

Also note how the validation method tracks the last login date, which is something that is captured within the data model.

In the initial version of the Book Club app, the code was [incorrectly] storing passwords in the database. In reality it was a detail that I had yet to get to. Since I am now writing about authentication, I have fixed this. The database stores password hashes, rather than passwords in clear text. This required a small schema update, so you'll need to recreate the database and run the BookClub.sql SQL script before you run the code.

Any application code that uses the authentication service only depends on the contract defined by IAuthentication (whether it is the server, or the client), giving you freedom to implement what it means to authenticate and produce a User object as you desire.

Authentication over HTTPS

If you use forms authentication or even basic authentication (i.e. anything that transfers a user name/password as clear text from client to server), you would be advised to use HTTPS.

This takes a little bit of setup, i.e. setting up an HTTPS site binding, that goes beyond the scope of this post. However RIA Services makes it easy to declaratively indicate that a particular domain service should only be exposed to the world using a secure endpoint, once you've handled the server configuration.

[EnableClientAccess(RequiresSecureEndpoint = true)]
public class AuthenticationService : FormsAuthenticationService<User> {
}



European Silverlight 4 Hosting :: WCF 4.0 Automatic Formatting with Jquery Ajax

clock October 10, 2011 06:49 by author Scott

at this time I am going to look at Automatic Formatting in WCF 4.0.That is one of the great addition in WCF Web HTTP programming model(WCF RESTful). By using this feature it’s dynamically determine the format for the service operation. Previously, if consumed JSON and XML format for the same operation of the service then must have defined two different operations with explicitly annotated RequestFormat parameter of the WebGetAttribute and WebInvokeAttribute attributes.

For getting json format in WCF 3.5

[OperationContract]
[WebGet(RequestFormat = WebMessageFormat.Json)]
string GetJsonData();

For getting Xml format in WCF 3.5

[OperationContract]

[WebGet(RequestFormat = WebMessageFormat.Xml)]
string GetXmlData();

Now we have option either go with explicit as above or go with new automatic way .By default Automatic format selection is disable due to backwards compatibility and when it’s enabled, it would automatically get the best format in which to return the response. WCF infrastructure actually checks the type which is contained the request messages of Accept Header. The first priorities for media types, if it’s not found in Accept Header than its checks the content-type of the request message and if content-type would not give the suitable response than it would be used default format setting which is defined by RequestFormat parameter of the WebGetAttribute and WebInvokeAttribute attributes and at the last if there is no any default format setting than it would be used value of the DefaultOutgoingResponseFormat property.

1. Priorities of media types in request message’s Accept Header.
2. The content-type of the request message.
3. The default format setting in the operation.
4. The default format setting in the WebHttpBehavior.

Automatic format selection depends on AutomaticFormatSelectionEnabled property. It can be enabled programmatically or using configuration, for getting the clarification I would like to show example of it with Jquery, using  jquery I will be getting the different  format by calling the same operation of the service, for keeping it simple I am enabling the AutomaticFormatSelectionEnabled through standard endpoints, so let’s start it.

First I am going to create an empty web application JqueryWithWCF and hosting it at IIS.



I am going to add following items in the solution.

- WCFService item named 
RestfulService.svc
-
html page named 
jqueryPage.htm
- jquery scripts
file



We have to add System.ServiceModel.Web
 reference for working with WCF RESTful services.



Now let’s look at the
IRestfulService.cs code

namespace WCFRestfulService
{
    [ServiceContract]
    public interface IrestfulService
    {
        [OperationContract]
        [WebGet(UriTemplate = "/data")]
        string GetData();
    }
}

I added ServiceContract attribute at intrface to expose the service and OperationContract attribute for expose the operation out of the world ,now we have to add WebGet attribute with property name UriTemplate=”/data”, it means, it can be called using UriTemplate property name.

Look at the RestfulService.cs code

namespace WCFRestfulService
{
    public class RestfulService : IrestfulService
    {
        public string GetData()
        {
            return "WCF 4.0 has introduced
            a new property \"automaticFormatSelectionEnabled\"";
        }
    }
}

There is nothing special I did, just implemented IRestfulService interface and return a string.

Here is very key part for enabling the Automatic formate, we have Three different ways to enable the automaticFormatSelectionEnabled ,

1. Using Coding with ServiceHost object we can enable it.
2. Using webhttp behavior option
3. Using the standard endpoints

I am going with standard endpoints, because in standard endpoints we don’t need to configure each and every attribute , it has already configured the some attribute build in , so here is the configuration



As we can see in the above, I have commented behavior and serviceHostEnviroment tag, because we don’t need to service metadata and I have add the standard endpoint with “automaticFormatSelectionEnabled” attribute with value true.

That’s it, we have made a restful service and we can get the JSON or XML format by using single operation.

Now we have to put code at jqueryPage.htm page , here is the code of the page

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <style type="text/css">
        ul{
            border:1px solid black;
            overflow:hidden;
            width:270px;
        }
        li {
            list-style-type:none;
            float:left;
            padding:5px;        
        }
    </style>
    <script src="Scripts/jquery-1.6.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">

        $(function () {

            // javascript object for getting all the jquery objects
            var pageElements = {
                actionButton: $('#btnAction'),
                xmlRadio: $('#rdoXml'),
                jsonRadio: $('#rdoJson'),
                xmlLabel: $('#lblGetXml'),
                jsonLabel: $('#lblGetJson'),
                isXML: true,
                dataTypeValue: 'XML'                
            };

            // set the button value on page load
            SetButtonValue(pageElements.xmlRadio, pageElements.xmlLabel,
                           pageElements.actionButton);

            //click event of xml radio button
            pageElements.xmlRadio.bind('click', function () {
                pageElements.isXML = true;
                SetButtonValue(pageElements.xmlRadio, pageElements.xmlLabel,
                           pageElements.actionButton);
            });

            //click event for json radio button
            pageElements.jsonRadio.bind('click', function () {
                pageElements.isXML = false;
                SetButtonValue(pageElements.jsonRadio, pageElements.jsonLabe
,

                           pageElements.actionButton);
            });

            //click event of the action button
            pageElements.actionButton.bind('click', function () {

                if (!pageElements.isXML) {
                    pageElements.dataTypeValue = 'JSON';
                } else {
                    pageElements.dataTypeValue = 'XML';
                }

                //jquery ajax method for getting the result
                $.ajax({
                    type: 'GET',
                    url: '/WCFRestfulService/RestfulService.svc/data',
                    contentType: 'application/json; charset=utf-8',                    
                    dataType: pageElements.dataTypeValue,
                    processdata: true,
                    success: function (msg) {                        
                        AjaxSuccess(msg, pageElements.isXML);
                    },
                    error: function (msg) {
                        alert(msg.error);
                    }
                });
            });
        });

        //it will call when the ajax hit successful
        function AjaxSuccess(result,isXML) {
            if (isXML) {
                alert($(result).find('string').text());
            } else {
                alert(result);
            }
        }

        //set button value on click on radio buttons
        function SetButtonValue(elem,label,button) {
            var buttonAction = $('#btnAction');
            if (elem.is(':checked')) {
                button.val(label.text());
            }
        }
    </script>
</head>
<body>    
    <div>
        <ul>            
            <li>
                <input type="radio" name="rdobutton" id="rdoXml"
                 value="Get XML" checked="checked" /></li>
            <li id="lblGetXml">Get XML</li>

            <li>
                <input type="radio" name="rdobutton" id="rdoJson"
                 value="Get JSON" /></li>
            <li id="lblGetJson">Get JSON</li>
        </ul>
        <input type="button" id="btnAction" value="" />
    </div>
</body>
</html>

I have created two radio buttons and a input button, when we hit the button it will call the jquery ajax method and check the pageElements.isXML Boolean value, if its false than JSON format called otherwise XML. For getting the proof i am using firebug, here is the result of firebug when we check radio button with Get XML and Get JSON.



I hope so you enjoyed the post . J



European Silverlight 4 Hosting :: How to Use "ClickMode" for Button Control in Silverlight?

clock September 29, 2011 08:10 by author Scott

In this article let us see the different ways of using the property ClickMode for a Button Control in a silverlight application. As usual, open the visual studio and select the silverlight project.

First let us drag three different Button and TextBlock controls to Stack Panel as shown below into MainPage.xaml. Here i used a property
called "ClickMode" for all the three button controls, But the value assigned to it is different.

For the first button i assigned the value Hover to the ClickMode property, It means that the
click event handler takes place whenever the mouse is hovered onto this button.

For the
second button i assigned the value Press to the ClickMode property, It means that the click event handler takes place whenever the mouse is clicked on this button.

For the third button i assigned the value Release to the ClickMode property, It means that the click event handler takes place whenever the mouse is released from this button. 

        <Button x:Name="btn1" Margin ="5" HorizontalAlignment="Left"
            Foreground="Black" Width="320" Click="OnClick1"
            Content="On Mouse Hover this text will appear below"
ClickMode
="Hover" />


        <TextBlock x:Name="text1" Margin ="0,8,0,0" />

        <Button x:Name="btn2" Margin ="5,5,5,5"  HorizontalAlignment="Left"             Foreground="Black" Width="320" Click="OnClick2"
            Content="On Button Press this text will appear below" ClickMode="Press" />

        <TextBlock x:Name="text2" Margin="0,8,0,0" />

<Button x:Name="btn3" Margin ="5,5,5,5" HorizontalAlignment="Left" Click="OnClick3" Width="320" Content="On Button Release this text will appear below" ClickMode="Release"/>

        <TextBlock x:Name="text3" Margin ="0,8,0,0" />

Now I am writing the code for button click events in the MainPage.xaml.cs

public
MainPage()
        {
            InitializeComponent();          

        }
        void OnClick1(object sender, RoutedEventArgs e)
        {
            btn1.Foreground = new SolidColorBrush(Colors.Blue);
            text1.Text = "On Mouse Hover this text will appear below.";
            text2.Text = "";
            text3.Text = "";
        }

        void OnClick2(object sender, RoutedEventArgs e)
        {
            btn2.Foreground = new SolidColorBrush(Colors.Green);
            text1.Text = "";
            text2.Text = "On Button Press this text will appear below.";
            text3.Text = "";
        }

        void OnClick3(object sender, RoutedEventArgs e)
        {
            btn1.Foreground = new SolidColorBrush(Colors.Green);
            btn2.Foreground = new SolidColorBrush(Colors.Blue);
            text1.Text = "";
            text2.Text = "";
            text3.Text = "On Button Release this text will appear below.";
        }

Thats it!!! Just press F5 and see the result. 


The output for the first Button looks like as



The output for the second Button looks like as



Note: For the people who find it difficult to integrate the above
code, I am pasting the complete code here.

MainPage.Xaml:

<UserControl x:Class="SilverlightTest1.MainPage"

    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    xmlns:d=http://schemas.microsoft.com/expression/blend/2008
    xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006
   xmlns:sdk=http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <StackPanel x:Name="LayoutRoot" Background="White" Margin="10">

        <Button x:Name="btn1" Margin ="5" HorizontalAlignment="Left"
            Foreground="Black" Width="320" Click="OnClick1"
            Content="On Mouse Hover this text will appear below" ClickMode="Hover" />

        <TextBlock x:Name="text1" Margin ="0,8,0,0" />

        <Button x:Name="btn2" Margin ="5,5,5,5"  HorizontalAlignment="Left"
            Foreground="Black" Width="320" Click="OnClick2"
            Content="On Button Press this text will appear below" ClickMode="Press" />

        <TextBlock x:Name="text2" Margin="0,8,0,0" />

<Button x:Name="btn3" Margin ="5,5,5,5" HorizontalAlignment="Left" Click="OnClick3" Width="320" Content="On Button Release this text will appear below" ClickMode="Release"/>

        <TextBlock x:Name="text3" Margin ="0,8,0,0" />

    StackPanel>

UserControl>

MainPage.Xaml.cs:

public MainPage()
        {
            InitializeComponent();           

        }
        void OnClick1(object sender, RoutedEventArgs e)
        {
            btn1.Foreground = new SolidColorBrush(Colors.Blue);
            text1.Text = "On Mouse Hover this text will appear below.";
            text2.Text = "";
            text3.Text = "";
        }

        void OnClick2(object sender, RoutedEventArgs e)
        {
            btn2.Foreground = new SolidColorBrush(Colors.Green);
            text1.Text = "";
            text2.Text = "On Button Press this text will appear below.";
            text3.Text = "";

        }

        void OnClick3(object sender, RoutedEventArgs e)
        {
            btn1.Foreground = new SolidColorBrush(Colors.Green);
            btn2.Foreground = new SolidColorBrush(Colors.Blue);
            text1.Text = "";
            text2.Text = "";
            text3.Text = "On Button Release this text will appear below.";
        }

Happy coding



European WCF Hosting :: Use dataset across WCF service

clock September 16, 2011 06:50 by author Scott

Some times you need to return a set of data from a WCF service and When you are working with ado.net, dataset is the obvious reason you wish at your client side. But passing dataset can make service less interoportable because in that case you are forced to use dataset on your client code. Second point is that dataset might become very bulky as per size of the data grows. Instead, passing dataset we can pass compressed byte array of dataset from WCF service and consume it like a byte array on client end. After Uncompression, either you can convert it into dataset or you can use this XML in any other form you want.

For this, lets first create a WCF service:

[OperationContract]
public byte[] GetEmployee(string BranchId)
{
string sQ = "Select EmpId, EmployeeName from EmployeeMaster";

SqlConnection objConn = new SqlConnection("Data Source=[YourServer];Initial Catalog=[Database];User ID=[UserName];Password=[Password];MultipleActiveResultSets=True");
SqlCommand objCom = new SqlCommand(sQ, objConn);
SqlDataAdapter objDa = new SqlDataAdapter(objCom);
DataSet objDs = new DataSet();
objDa.Fill(objDs);
//Now we'll convert dataset into byte array and compress it using gzStream.
byte[] binaryDataResult = null;
MemoryStream memStream = new MemoryStream();
GZipStream gzStream = new GZipStream(memStream, CompressionMode.Compress);
objDs.WriteXml(gzStream);
binaryDataResult = memStream.ToArray();
gzStream.Close();
memStream.Close();
return binaryDataResult;
}

Here, We are first filling dataset from database then after compression using GZipStream, we are converting it to byte array. At client end we will get this byte array and we'll again follow these steps in reverse order.

ServiceClient s = new ServiceClient();
byte[] btEmployee = (byte[])s.GetEmployee("0");
if (btEmployee != null)
{
MemoryStream mEmployee = new MemoryStream(btEmployee);
GZipStream gStreamEmployee = new GZipStream(mEmployee, CompressionMode.Decompress);
DataSet objDsEmployee = new DataSet();
objDsEmployee.ReadXml(gStreamEmployee);
gStreamEmployee.Close();
gvEmployee.DataSource = objDsEmployee;
gvEmployee.DataBind();
}



European Silverlight 4 Hosting :: Tutorial - How to Send Email in Silverlight

clock August 25, 2011 07:07 by author Scott

In this tutorial I will show you how to send email with Silverlight using .NET framework.

1. Create Silverlight Application Using VS 2010



Above GUI xaml like following,



2. Add asp.net Generic Handler in Web.Project



3. Add Static Class and Create Send Email Function.



4. Add code to perform mail sending through the generic handler.



5. Add This Code At SilverLight Project(MainPage.xaml.cs) on send button click.



6. Then, configure the SMTP settign inside the configuration file, here is settings details.



7. Press F5 and run.

Hope it is help!!



European WCF Hosting :: Custom Autocomplete with JQuery and WCF

clock August 17, 2011 08:33 by author Scott

At times you need to show some AutoComplete dropdown below a textbox as you starts typing. So that you can select any suggested text from the below list. Ajax Control toolkit will do this job quite easily but for those who doesn't want to use Ajax Control toolkit, JQuery is like another option by which they can replicate everything available in Ajax Control toolkit quite easily. Here we will see how we can make our own AutoComplete using JQuery and WCF.

Add a textbox and a script manager with reference to service.

<asp:ScriptManager ID="scr" runat="server">
<Services>
<asp:ServiceReference Path="~/Service.svc" />
</Services>
</asp:ScriptManager>
<div>
<label for="city">
Your city:
</label>
<input id="Question" type="text" />
</div>

Add this JQuery in head tag of your page.

<script type="text/javascript" language="javascript">
$("#Question").bind('keyup', function (e) {
var str = "";
if (e.keyCode == 13) { return false; }
var left = $("#Question").offset().left;
$("#autocom").remove();
$("#Question").after("<div id='autocom' class='popup'><div>")
SecServices.Service.GetTagString($("#Question").val(),
function (data) {
$("#autocom").append("<table cellpadding='1' cellspacing='1' width='100%'>");
$.each(data, function (index, elem) {
$("#autocom").append("<tr><td onclick='setText(this)' class='popuptd'>" + elem.Question + "</td></tr>");
});
$("#autocom").append("</table>");
});

$("#autocom").slideDown('slow');
$("#autocom").css("left", left);
$("#autocom").width($("#Question").width);
$("#Question").bind("keypress", "setTextKeyPress");
$("#autocom").bind('focusout', function () {
$("#autocom").slideUp('slow');
});
});
function setText(td) {
$("#Question").val($(td).html());
$("#autocom").slideUp('slow');
}
</script>
Add Some style
<style type="text/css">
.popup
{
background-color:#F0F0F0;
padding-left:100px;
overflow:auto;
position:absolute;
border:1px solid gray;
padding: 5px 5px 5px 5px;
}
.popuptd
{
color:Black;
}
.popuptd:hover
{
border: 1px solid #F4A83D;
}

</style>
and finally create a WCF service.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
[ServiceContract(Namespace = "RelSecServices")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
[OperationContract]
public Questions[] GetTagString(string term)
{
using (RelsecModel.RelsecEntities context = new RelsecModel.RelsecEntities())
{
var query = from c in context.msSecurityQuestions
where c.Question.StartsWith(term)
select new Questions() { id = c.Id, Question = c.Question };
return query.ToArray();
}
}
}



European WCF Hosting :: jQuery autocomplete with Asp.Net WCF service

clock August 5, 2011 09:19 by author Scott

In this article below version of scripts are used

jQuery version 1.4.1

jQuery UI version 1.8.6

We will create 2 example with WCF service.

First of all we will create a WCF service and configure it to response as json format.

We will bind endpoint with webHttpBinding. We will create service with name “AutoComplete” and our interface will be IAutoComplete. We will create an endpoint behavior which uses webHttp behavior. So our web.config file will have configuration as below.

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="jQueryExamples.Services.AutoComplete.AutoCompleteBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttpEndpoint">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
        <service behaviorConfiguration="jQueryExamples.Services.AutoComplete.AutoCompleteBehavior"
            name="jQueryExamples.Services.AutoComplete.AutoComplete">
            <
endpoint address="" binding="webHttpBinding"                    
contract
="jQueryExamples.Services.AutoComplete.IAutoComplete"

                      behaviorConfiguration="webHttpEndpoint">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
</
system.serviceModel>

Now we will add reference of System.ServiceModel.Web to our application, because we will be using some of its features.

Example 1

In our first example of jQuery autocomplete, we will create a WCF service method which will return simple string array.

In our interface we will create method GetTagString which will return us string array.

[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "GetTagString?term={term}",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
string[] GetTagString(string term);

In above declaration you will be able to find that apart from OperationContract there are some more attributes are assigned to method. WebInvoke attribute is part of System.ServiceModel.Web. WebInvoke adds meta data to the service method, provide operation behavior and verb on which method will be invoked. Method parameter will define which method will be used for invocation, we will use GET. UriTemplate will define url template in the service and bind url parameter to method parameter. We will use RequestFormat and ResponseFormat as WebMessageFormat.Json.

We will implement the interface and write below method into AutoComplete.svc file.

public string[] GetTagString(string term)
{
    string[] tags = //Your logic to retive tags
    return tags.Where(t => t.StartsWith(term, StringComparison.InvariantCultureIgnoreCase)).ToArray();
}

Currently I have used static array of tags and then filtered it with LINQ to response only those items which are starting with the term our autocomplete have provided.


Now on the aspx page, we will create a html input and then add a script to add auto complete to it.

<div class="ui-widget">
    <label for="tags">
        Tags:
    </label>
    <input id="tags" />
</div>

And our script to initialize autocomplete will be

<script type="text/javascript" language="javascript">
    $(function () {
        $("#tags").autocomplete({
            source: "Services/AutoComplete/AutoComplete.svc/GetTagString"
        });
    });
</script>

In the JavaScript function we have created autocomplete with URL to our AutoComplete.svc as source and followed by our method name which will be requested each time user hit a key.

So it will give us output as below.

This output and method of autocomplete is not much different from the original jQuery example. The only difference is we have created autocomplete with a WCF service.

Example 2

In above example we have created autocomplete with only names. In real life scenario we have different requirements as well. One of the scenario is when we retrieve a tag name we need its id as well. So how we will achieve it with modification in our above example.

To achieve it we need to first change original jquery.ui.autocomplete.js file. We will add our function into this file so that our example works perfect.

As first item we will add a “normalize” option in the autocomplete widget options. Its declaration will be look like-

$.widget("ui.autocomplete", {
        options: {
            appendTo: "body",
            delay: 300,
            minLength: 1,
            position: {
                my: "left top",
                at: "left bottom",
                collision: "none"
            },
            source: null,
            normalize: null
        }
        //Further code

Second step will be the use of normalize function in code. We will modify the call in _response method. Now this method will look like -


_response: function (content) {
    if (content && content.length) {
        content = (this.options.normalize != null) ? this.options.normalize(content) : this._normalize(content);
        this._suggest(content);
        this._trigger("open");
    } else {
        this.close();
    }
    this.element.removeClass("ui-autocomplete-loading");
}

We have put a check that if normalize function defined by us is not null then we will call it otherwise we will call default _normalize function. You must have question that what does this normalize function will do. Normalize function will parse our service response and pass it to autocomplete so that it can generate the output.

HTML for second example is as below -

<div class="ui-widget">
    <label for="tags">
        Tags object:
    </label>
    <input id="tags2" />
    <label id="lblId">
    </label>
</div>

In html we have added a label as “lblId” and we require autocomplete to add id of the tag to this label. You can also use hidden field to store the id. We will modify our WCF method, JavaScript to initialize autocomplete

We will create a class named Tags which will have property of tag name and id.

[DataContract]
public class Tags
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string tagName { get; set; }
}

We have applied DataContract attribute to our class so that it can be transferred with out WCF service.

Our WCF Service Method definition in interface will be as below

[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "GetTagObject?term={term}",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
List<Objects.Tags> GetTagObject(string term);

In above method we have returned a list of our class Tags. Hence implementation of this method will be as follows

public List<Objects.Tags> GetTagObject(string term)
{
    List<Objects.Tags> lstTags = new List<Objects.Tags>();
    //Logic to retive list of tags
    return lstTags.Where(t => t.tagName
    .StartsWith(term, StringComparison.InvariantCultureIgnoreCase))
    .ToList();
}

In above example I have added items manually to list and then filtered it with LINQ to return desired output.

now we will initialize autocomplete with script

$(function () {
    $("#tags2").autocomplete({
        source: "Services/AutoComplete/AutoComplete.svc/GetTagObject",
        normalize: function (items) {
            if (items.length && items[0].label && items[0].value) {
                return items;
            }
            return $.map(items, function (item) {
                return $.extend({
                    label: item.tagName,
                    value: item.id
                }, item);
            });
        },
        select: function (event, data) {
            $('#tags2').val(data.item.tagName);
            $('#lblId').text(data.item.id);
            return false;
        }
    });
});

In above script we have specified two functions in the options. One is normalize and another is select. I will first explain normalize (which I have created with reference from jQuery’s original _normalize function) it will have items as input. When jQuery request to our service it will parse the response as json and pass it to normalize function. In first if block we have checked that whether json output contains label and value as attribute then we will return same items as output to process further. We will note here that if we always want to use label and value as class member then we do not need to modify autocomplete.js file. Now after the if block we have mapped our data with assigning tagName and id to label and value respectively. So autocomplete can parse our item and display us the autocomplete menu.

In select function we will specify that when user select an item how should it be processed with the data. In our case we have assigned tagName to our textbox value and id to our label text.

When we run our code it will provide us output as below



With this logic you can create your own autocomplete and even you can convert your dropdowns into a nice autocomplete.



European Silverlight 4 Hosting :: How to Edit Silverlight Page Data Using Domain Service

clock July 21, 2011 05:33 by author Scott

This post requires to create a Silverlight Business Application in Visual Studio 2010.

1. Open the Mainpage.xaml , Add the following XAML code to see the Save changes and Reject changes button

   1: <Button Content="Save Changes" Click="SaveButton_Click"
         Margin="5" 
   2:        x:Name="SaveButton"></Button>
   3: <Button Content="Reject Changes" Click="RejectButton_Click"
               Margin="5"
   4:         x:Name="RejectButton"></Button>
   5: <TextBlock x:Name="ChangeText" VerticalAlignment="Center"
      Width="Auto"></TextBlock>

2. Add the code for button click event handlers as shown below

   1: private void SaveButton_Click(object sender, RoutedEventArgs e)
   2:  {
   3:   awDept.SubmitChanges(OnSubmitCompleted, null);
   4:  }
   5: 
   6:  private void RejectButton_Click(object sender, RoutedEventArgs e)
   7:  {
   8:    awDept.RejectChanges();
   9:    CheckChanges();
  10:  }
  11: private void CheckChanges()
  12:  {
  13:   EntityChangeSet changeSet = awDept.EntityContainer.GetChanges();
  14:   ChangeText.Text = changeSet.ToString();
  15:   bool hasChanges = awDept.HasChanges;
  16:   SaveButton.IsEnabled = hasChanges;
  17:   RejectButton.IsEnabled = hasChanges;
  18:  }
  19: 
  20: private void OnSubmitCompleted(SubmitOperation so)
  21:  {
  22:    if (so.HasError)
  23:     {
  24:         MessageBox.Show(string.Format("Submit Failed: {0}", so.Error.Message));
  25:         so.MarkErrorAsHandled();
  26:      }
  27:             CheckChanges();
  28:  }

  29: private void departmentDataGrid_RowEditEnded(object sender,
          DataGridRowEditEndedEventArgs e)
  30: {
  31:          CheckChanges();
  32: }

3. Open the Metadata file in server project and add the editable attribute to the Id and modified date as shown below

   1: internal sealed class DepartmentMetadata
   2:         {
   3: 
   4:             // Metadata classes are not meant to be instantiated.
   5:             private DepartmentMetadata()
   6:             {
   7:             }
   8: 
   9:             [Editable(false)]
  10:             public short DepartmentID { get; set; }
  11: 
  12:             public string GroupName { get; set; }
  13:             [Editable(false)]
  14:             public DateTime ModifiedDate { get; set; }
  15: 
  16:             public string Name { get; set; }
  17:         }

4. When you run the application you should be able to see the below screen



European Silverlight WCF Hosting :: WCF AJAX Service Without Configuration

clock July 12, 2011 06:58 by author Scott

This post discusses how to develop Windows Communication Foundation (WCF) service using AJAX and without any configuration settings for WCF. This service can be consumed from Javascript. The service uses a special setting in .svc file which automatically enables an AJAX endpoint.

You can get the AJAX support for WCF through the ScriptManager control.

1. Create a WCF service project in VS 2010

The service contract code as follows

   1: // Define a service contract.
   2:   [ServiceContract(Namespace = "ConfigFreeWCFAjaxService")]
   3:   public interface ICalculator
   4:   {
   5:       [OperationContract]
   6:       double Add(double n1, double n2);
   7:   }

Service Implementation code as follows

   1: public class CalculatorService : ICalculator
   2: {
   3:     public double Add(double n1, double n2)
   4:     {
   5:         return n1 + n2;
   6:     }
   7: }

The SVC file setting as below

   1: <%@ServiceHost
   2:     language="c#"

   3:     Debug="true"
   4:     Service="ConfigFreeWCFAjaxService.CalculatorService"

   5:     Factory="System.ServiceModel.Activation.

          WebScriptServiceHostFactory"
   6: %>

WebScriptServiceHostFactory automatically add the WebScriptEndpoint to the service.

You need to add the following line in script manager control to call the service from javascript

   1:
<asp:ScriptManager ID="ScriptManager" runat="server">
   2:
     <Services>
   3:
         <asp:ServiceReference Path="service.svc" />
   4:
     </Services>
   5:
</asp:ScriptManager>

Calling the service from javascript

<script type="text/javascript">

  function makeAJAXCall()


   {

   var n1 = document.getElementById("num1").value;


   var n2 = document.getElementById("num2").value;

   // Instantiate a service proxy

   var proxy = new  ConfigFreeWCFAjaxService.ICalculator();

  // Call correct operation on proxy      
  proxy.Add(parseFloat(n1), parseFloat(n2), onSuccess, onFail, null);           
  break;


  }

</script>

//This function is called when the result from the service call is received

    function onSuccess(mathResult)

     {

        document.getElementById("result").value = mathResult;


    }

The <system.ServiceModel> element can be completely removed from the web.config if you configure your service as shown in the above.



European Silverlight 4 Hosting :: How to Create Application using Silverlight Business Application Template

clock June 16, 2011 05:46 by author Scott

This post specifically discusses the authentication mechanisms forms and windows. By Default Silverlight Business Application allows the users to register and login with built in controls.

This template also gives you navigation ability where you can easily add Silverlight pages for additional functionality. It also enables authentication, roles and profiles.

1. Select the Silverlight project type



Then, click ok. Notice that the following structure will be created where silverlight pages can be found in Silverlight client project views folder



2. Right click the Silverlight client project and select properties. Notice at the bottom of the project properties of the dialogue box RIA Services link exists between the client and server projects.



3. Hit F5 and you’ll see the home page

4. Click on the login link



5. Click the registration link from above windows then you’ll see the following window



By default Silverlight uses the Forms authentication. To use the windows authentication

Open the web.config file from Silverlight server project and change the authentication mode as shown below

   1: <authentication mode="Windows">
   2: </authentication>

Open the App.xaml.cs for the App.xaml file and change the code as shown in below

   1: /// <summary>
   2:         /// Creates a new <see cref="App"/> instance.
   3:         /// </summary>
   4:         public App()
   5:         {
   6:             InitializeComponent();
   7: 

   8:             // Create a WebContext and add it to the
                 ApplicationLifetimeObjects collection.
   9:             // This will then be available as WebContext.Current.
  10:             WebContext webContext = new WebContext();
  11:             //webContext.Authentication = new FormsAuthentication();
  12:             webContext.Authentication = new WindowsAuthentication();
  13:             this.ApplicationLifetimeObjects.Add(webContext);
  14:         }

Build and run the application, now you will notice login details with windows authentication.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in