Wednesday, November 27, 2013

Errors that appear in the WCF client app...

I was setting a new server to host my WCF app and I hit the wall with the following error messages. I spent 2 days in solving this problem. I guess, many people is wondering how to resolve these interesting errors.

  • The server has rejected the client credentials.
  • The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.9687500'.
  • The communication object, System.ServiceModel.ServiceHost, cannot be used for communication because it is in the Faulted state.

I have developed a WCF solution in WinForm which allows you to comment out certain settings in the server and client so that you can reproduce the above mentioned error message.

  https://github.com/lauhw/WcfWinForm

Please beware that if you are running the WCF server and client in the same computer, the above error might not appear until you run them in a separate computer.

In a nutshell:
  1. Both server and client config file must have the same settings in the "Binding" record. This includes the "security mode".
  2. The "identity" settings must be the same in both server and client config file.
  3. In the live environment, make sure you remove the "MEX" endpoint unless you want anyone to be able to query the interface.
  4. Don't forget to open the port in the firewall.
In case you are hitting the same error mentioned above, the fastest way to solve this problem is to run the test WCF solution (as mentioned above). Make sure that the test solution works. After that, compare the differences in app.config between the test solution and your solution.

Hope you don't have to spend 2 days to solve the configuration problem. ;)

Monday, September 9, 2013

Controlling the page access permission

For most of the website that requires user logon, there are three types: (1) the system administrators (2) system users and (3) the page that is accessible without logon to the website.

The website will show the functions base on the current user type. For example, system administrator will be able to create user account, updating system settings. For system user, they will be able to access the data entry screen, generate reports. Both user types requires to access different features in the system.

In the design option, we may implement with one of the following security strategy:
  • The features are turn on/off which depends on the permission that has been assigned to the user. With this strategy, the "user" has many "permissions" (i.e., one-to-many relationship).
  • The features are turn on/off which depends on the user falls in which user group. With this strategy, you can have one user in one group or multiple groups (i.e., many-to-many relationship).
  • The simplest way is to add a field in the "user" record to identify it's "user type" (either system administrator or system user). Plus either one of the above strategy. With this design, you will be able to come out with a complex security design that can cater most of the requirements.
In ASP.net, you can implement the first and second strategy easily with either the built-in ASP.net user/role framekwork or show/hide the menu options. I guess most of the websites were implemented in this way.

The most interesting strategy is the third option and the implementation is powerful yet simple. You need to develop three page classes which inherits from Page class. Namely "AdminPage",  "UserPage" and the third one is PublicPage (for public access such as "login" page and "contact us" page).

The detail implementation of the in the AdminPage is to ensure that the current user type is system administrator in OnInit event.

public class AdminPage : Page
{
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

             // if the user has not logged on, jump to "access deny" page.           
             // if current user is not  "system admin", jump to "access deny" page.
  
        }
}

For the UserPage, we don't want the system administrator to access it (this depends on the requirments) :

public class UserPage : Page
{
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
           
             // if the user has not logged on, jump to "access deny" page.
             // if current user is not  "system user", jump to "access deny" page.
  
        }
}

Once the above page classes are ready, you just need to change your ".aspx.cs" parent class to one of the above. By using the Object Oriented Programming, your developer colleagues will be able to find out which page is for admininstrator, user and public (just right click on the AdminPage and choose Find All References). This also reduce the developer comments in the ".aspx.cs" and increase the maintainability.

By inheriting the web page from different parent page class, there is a "gray" area which you are not sure if it should be PublicPage or UserPage. In this case, you might need to declare a new hybrid page class for it and limit the contents between the "public" and "user". But, for me, I prefer to move the "contents" from the page to "user control" (i.e., ".ascx") and limit the contents base on current user type. Then, I create two pages: one inherits from PublicPage and the other from UserPage. By using user control, I'm able to have the page for single audience and I'm able to handle it easily.

Thursday, June 6, 2013

ImageButton (asp.net) failed to work in IE10

When you are running your asp.net website (.net 3.5) in IE10 with some ImageButton-s together with the ScriptManager, you might have a chance in triggering the following error:

Sys.WebForms.PageRequestManagerServerErrorException input string was not in a correct format

To resolve this, you need to add the following script after the end of the "Form" HTML tag.

<script type="text/javascript">
    Sys.WebForms.PageRequestManager.getInstance()._origOnFormActiveElement = Sys.WebForms.PageRequestManager.getInstance()._onFormElementActive;
    Sys.WebForms.PageRequestManager.getInstance()._onFormElementActive = function (element, offsetX, offsetY) {
        if (element.tagName.toUpperCase() === 'INPUT' && element.type === 'image') {
            offsetX = Math.floor(offsetX);
            offsetY = Math.floor(offsetY);
        }
        this._origOnFormActiveElement(element, offsetX, offsetY);
    };
</script>

For more details, please read the following URL:

http://stackoverflow.com/questions/13299685/ie10-sending-image-button-click-coordinates-with-decimals-floating-point-values

Monday, May 27, 2013

Web Service (asmx) vs Handler (ashx)

In ASP.NET environment, it comes with quite extensive way of handling the web request. There is Page class (aspx), Handler (ashx), Web service (asmx), Web service in WCF (asmx), etc. It's all upto the developer to decide the best way to write their program.

Let's compare the Web Service (asmx) and Handler (ashx):
  • With Web Service you can run your Visual Studio and add the web service as web reference. This will create the necessary classes for you. With web service, the serialization and deserialization of the data object will be handle by .Net framework. This simply means that you can work with Web Service without having deep knowledge in the "background" process.
  • With Handler you must find out what is the parameter to be pass to the handler. No code generator that is able to help out over here. It provides very basic features to serve the request and you will have to serialize/deserialize your data objects manually (you may use JavaScriptSerializer to deal with the JSON data). It does not limit you from returning the data in JSON, XML or CSV format. It's all depend on your design.
With Web Service, it saves you from lots of codes in the serialization process. With Handler, it allows to develop low level request & response. Both has it's own pros and cons.

There is no conclusion on which one is better. It goes back to you to choose which one is suitable for the project that you work on.

Thursday, April 25, 2013

Session is not missing in the Handler

I still remember the first time that I'm developing with generic handler (.ashx) and found out that the session is missing. This is because the handler implements only the basic feature (as compared to Page class).

In order for the AJAX call accessing the session information, your handler must implement the following interface:

    System.Web.SessionState.IRequiresSessionState

OR

    System.Web.SessionState.IReadOnlySessionState

That's all you need.

Saturday, March 2, 2013

Posting data in JSON format to the ASP.NET website

When you are posting data using JQuery AJAX, you may call $.post() method to submit the data. We normally post the "data" by specifying the parameter name and value into the "data" parameter in the $.post() method. But, it will be very tedious to add new field to the data parameter when you already have lots of fields. To ease the coding maintenance, you may post the data in JSON format. This is quite simple by instantiating a new Object and set the property with values.

For example, I wrote this script in a HTML file:

    <script src="../Scripts/jquery-1.7.js" type="text/javascript"></script>
    <script type="text/javascript">
        function postJson() {
            var m = {
                myname: 'abc',
                myage: 10
                // add more properties here
            };
            var url = 'post_json.aspx';
            $.post(url, JSON.stringify(m), function (d) {
                if (d && d == 'ok') {
                    alert('ok');
                }
                else {
                    alert('failed');
                }
            });
        }
    </script>

Below is the "post_json.aspx" which you may use Handler (.ashx) to avoid the ASP.NET page life cycle.

using System.Web.Script.Serialization;

    public partial class post_json_post_json : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {      
            string json_text = this.Request.Form[0];
            JavaScriptSerializer js = new JavaScriptSerializer();
            CInfo my_obj = (CInfo)js.Deserialize(s, typeof(CInfo));

            this.Response.Write("ok");
            this.Response.End();
        }
    }

This is the data class that I'm using in this demo:

    public class CInfo
    {
        public string myname { get; set; }
        public int myage { get; set; }
    }

By using this technique, you will be achieving the following:
  • Easy to maintain the JavaScript coding by replacing the data parameter in the $.post() with a stringify data in JSON format.
  • Easy to maintain the code in ASP.NET - this is because you just need to declare a class which contains all the properties which is same as the data in JSON format. You may declare a property with other class type as well and also supporting object array.

Saturday, January 19, 2013

Improving the web app by using AJAX + Handler

The following diagram explains the way to improve the web application response and reduces the server load by using AJAX call to the Handler.


For example, the "default.aspx" allows the user to post message and view all the messages. In the default.aspx, you will not use the GridView control to show all the messages. Instead, you make AJAX requests to the LoadMessage.ashx and show the result in the default.aspx. In this way, no viewstate and no ASP controls will be generated by LoadMessage.ashx.

The LoadMessage.ashx may return the result in 2 ways:
  • formatted result (with HTML/TABLE tags or whatsoever) OR
  • result in JSON format. Of course, the result in JSON format requies lesser bandwidth. But, you need to write some Javascript to format the result and show it in the default.aspx.
Another function provided by PostMessage.ashx will be a lot simpler. When the user type their message in the default.aspx (at the client site), you just need to retrieve the message from the screen and then make AJAX calls to the PostMessage.ashx (with the appropriate parameters).

Friday, January 11, 2013

Handler (ashx) VS Page (aspx)

We used to do development with Page (aspx) which comes with lots of rapid application development feature such as postback handling, drag & drop support, etc. But, this becomes expensive when the application is hosted in the Internet (not in a LAN). The viewstate, the control object instance generation, etc are all come with a price. A more complicated situation is that when you try to use AJAX (ScriptManager + UpdatePanel), the performance become questionable (when traffic goes up) and the coding become very complicated.

On the other hand, Handler (ashx) is a class that provides very basic functionality as compared to Page. There is no visual designer for Handler. No viewstate. No control object generation. No postback. You have to handle everything by yourself. The advantage of Handler as compared to Page is the performance (by giving up all the rapid application development features).

With JQuery and JSON, implementing AJAX become very easy. Modifying the DOM objects at the client site become easier as well. Using JQuery AJAX call to the Handler will boost up the performance because the viewstate is no longer require to transmit back and fore between the server and the client. At the server side, it also does not requires to re-generate all the control object instances.

Try this out:
  • Design a data entry form in Page (aspx).
  • Click on the Submit button and the client will make a AJAX call to the Handler (ashx) with the user input values.
  • Then, the Handler will return the result in JSON format to the client.
  • The client will then check the result and make the appropriate response.
 Benefits of using Handler (ashx) + Page (aspx):
  • Faster response time
  • Reduce the data to be transmitted between the server and the client.
  • The server CPU load will reduce due to the Page call is lesser.
 Challenges:
  • The developer requires to more JavaScript/JQuery knowledge.
  • Harder to debug.
  • Because the input controls in the Page is sometimes unpredictable (in .Net 3.5), getting the input field with JQuery will become troublesome.