Amazon Ad

Wednesday 19 June 2013

504 Gateway Time-out - The web server is not responding, ASP.NET WCF Service.

Hi Folks,

I was facing a problem in my phonegap android mobile app with ASP.NET WCF REST Service, The error used to say 504 Gateway Time-out - The web server is not responding.

But the app was working on many devices but was giving this error on some devices including Samsung S3 I747.

My first impression was the problem is with the web server. I checked the performance which was ok and also checked the code which was .net wcf with LINQ which was also giving result on a decent speed and time.

I also restarted my IIS to clear the cache but still no affect the same error was produced again on the same device.

The first step i took was to enable error tracing in IIS, Which is available in IIS under name "Failed Request Tracing Rules". I activated this with error codes 400,402,500,504 to find out what causes this problem.

When i checked the log files it showed me the error code which was 402 when tried to connect with samsung s3 phone. Here is how i sorted out the problem in three easy steps.


Step 1: Since this error is a status code in a browser my first doubt was that the browser might not be supporting some configuration. So i added the below line in my web.config file

<system.web>
    <browserCaps userAgentCacheKeyLength="256" />

Step 2: Since my WCF service was expecting to give the result in a big time so i decided to increase my response time, close time,receive time, open time and close time. So i added the following line in my web.config file

<bindings>
      <webHttpBinding>
        <binding closeTimeout="10:01:00" openTimeout="10:01:00" receiveTimeout="10:01:00" sendTimeout="10:01:00" maxBufferPoolSize="524288000" maxReceivedMessageSize="65536000" useDefaultWebProxy="true" allowCookies="false" crossDomainScriptAccessEnabled="true" name="cabservicebinding">
          <security mode="None"></security>
        </binding>
      </webHttpBinding>
    </bindings>

Step 3: To activate caching in my WCF results, I also decided to add the following line in web.config in system.servicemodel tag

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

After this, I restarted my IIS and the things started to work fine. Hope this helps to you all.

Thanks
Ritesh Tandon

Sunday 16 June 2013

A circular reference was detected while serializing an object of type

Hi Folks,

I was working with LINQ to SQL classes and was having problem when WCF was returning a List<T> but was returning "A circular reference was detected while serializing an object of type T". This was frustrating as everything seems fine and there was no problem in C# code.

But when i researched i found that LINQ generated classes have many other attributes and also if there are any relational tables the dependencies would be there for the classes which may have reference for child table classes which may cause circular reference. I searched a lot and found that JSON.NET (open source) solves the problem. I downloaded JSON.NET from  http://json.codeplex.com/releases/.(Please note that in .NET 4.5 JSON.NET comes in built) and  the problem was solved. Here is the code in WCF operationcontract

public string GetEmployees()
{
using(EmployeeDbContext context=new EmployeeDbContext())
{
List<Employee> list=new List<Employee>();
list=(from p in context where p.Salary>=10000 select p).ToList();
string jsonstring=JsonConvert.SerializeObject(list,Formatting.Indented, 
                            new JsonSerializerSettings { 
                                   ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
                            });
}
}

To reverse the code would be Employee mylist=JsonConvert.DeserializeObject<Employee>(list);

Thanks
Ritesh


Tuesday 11 June 2013

How to Invoke WCF DELETE in ASP.NET

Hi Folks!,

I was facing a problem while invoking DELETE method in WCF. Here is how  i managed to do it.

Step 1. Create a WCF Service.

Create a new WCF service and name it as MyService.svc

using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.SqlClient;
using System.Data;
namespace WCFASPNET
{
public class MyService : MyServiceInterface
    {
public string GetAllUsers()
        {
//return all users
}
public string DeleteDept(String ID)
        {
//delete department
}
}

Step 2. Add operation contracts in the WCF Service Interface file.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WCFASPNET
{
   [ServiceContract]
    public interface MyServiceInterface
    {

        [OperationContract]
        [WebGet(UriTemplate = "/MyUsersList", ResponseFormat = WebMessageFormat.Json)]
        string GetAllUsers();

        [OperationContract]
        [WebInvoke(Method = "DELETE", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/DeleteDept/{ID}")]
        string DeleteDept(String ID);

    }
}

Step 3. Add Cross Domain Ajax Code in Global.asax file.

Add the Application_BeginRequest event in Global.asax file

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }

Step 4. Configure web.config file.

<system.serviceModel>
        <services>
            <service name="WCFASPNET.MyService" behaviorConfiguration="RESTBehavior">
                <endpoint address=""  binding="webHttpBinding" bindingConfiguration="ServiceBinding" behaviorConfiguration="MyEndpointBehavior" contract="WCFASPNET.MyServiceInterface"/>
            </service>
        </services>
        <bindings>
            <webHttpBinding>
                <binding crossDomainScriptAccessEnabled="true" name="ServiceBinding">
                    <security mode="None"></security>
                </binding>
            </webHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="RESTBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
                <behavior>
                    <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior name="MyEndpointBehavior">
                    <webHttp defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="false" helpEnabled="true"/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>

Step 5. Call WCF Delete from jquery

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="js/jquery-1.4.1.js"></script>
</head>
<body>
    <script language="javascript" type="text/javascript">
        //getuser();
        deleteuser();
        function deleteuser() {
            $.ajax({
                type: "DELETE",
                url: "MyService.svc/DeleteDept/1",
                data: '{}',
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    // Play with response returned in JSON format.
                    alert(data.toSource());
                },
                error: function (msg) {
                    alert("Error" + msg);
                }
            });
        }
        function getuser() {
            $.ajax({
                type: "GET",
                url: "MyService.svc/MyUsersList",
                data: '{}',
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    // Play with response returned in JSON format.
                    alert(data.toSource());
                },
                error: function (msg) {
                    alert("Error" + msg);
                }
            });
        }
        </script>
    <form id="form1" runat="server">
    <div>
   
    </div>
    </form>
</body>
</html>

Thursday 6 June 2013

ASP.NET SignalR, $.connection.chatHub is undefined

Hi Folks,

I was working with SignalR and was not able to run the program due the error $.connection.chatHub is undefined, i.e my Hub object was undefined in javascript. Here is how i was able to solve the problem :

I am assuming that you already have got all the files from NuGet command prompt for VS2010 or Have installed aspnetcomponents for VS2012.

If not for VS 2010

Go to nuget command and type

PM> Install-Package Microsoft.AspNet.SignalR -pre

For VS2012

Download the asp.net components installer for VS2012 to get the SignalR template.

Please go step by step

Step 1. Check global.asax file, Make sure you have

<%@ Import Namespace="Microsoft.AspNet.SignalR" %>

<%@ Import Namespace="Microsoft.AspNet.SignalR.Hosting" %>

void Application_Start(object sender, EventArgs e)
 {

        // Code that runs on application startup
        RouteTable.Routes.MapHubs();
 
}

Step 2. Check the javascript files, The problem might be the old version of javascript files. Please make sure you have
<script src="js/jquery1.8.js" type="text/javascript"></script>
<script src="js/json2.js" type="text/javascript"></script>
<script src="js/jquery.signalR-1.1.2.min.js" type="text/javascript"></script>
<script src='<%: ResolveClientUrl("~/signalr/hubs") %>' type="text/javascript"></script>

make sure that its not <%= ResolveClientUrl("~/signalr/hubs") %> it should be <%: ResolveClientUrl("~/signalr/hubs") %> in the src of the script tag
referencing javascript.

Step 3. Make sure that the Hub class is in App_Code folder, For ex. here the Hub class (i.e ChatHub class) is defined as

using System;

using System.Collections.Generic;

using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Hubs;

public class ChatHub : Hub

{

    public override Task OnConnected()
    {
        return base.OnConnected();
    }

    public override System.Threading.Tasks.Task OnDisconnected()
    {
        return base.OnDisconnected();
    }

 

   public void Send(string message)
 
   {
     
Clients.All.broadcastMessage(message);
   }

    public void Send(string message, string ConnectionId)
    {
        Clients.Client(ConnectionId).addMessage(message);
    }


}

Step 4: In my aspx page my SignalR code is
   <body>
    <script src="js/jquery1.8.js" type="text/javascript"></script>
    <script src="js/json2.js" type="text/javascript"></script>
    <script src="js/jquery.signalR-1.1.2.min.js" type="text/javascript"></script>
    <script src='<%: ResolveClientUrl("~/signalr/hubs") %>' type="text/javascript"></script>
    <script type="text/javascript" charset="utf-8">
        var chat = $.connection.chatHub;
        $.connection.hub.start().done(function () {
            alert('Connected');
            //Send Data to Hub Class
            chat.server.send("Welcome to SignalR, SignalR Demo Message From Client");
        });
        //To get the server message broadcasted
       chat.client.addMessage = function (message) {
           alert('Message from server '+message);
       });
   </script>
</body>
And here you go, Run the program and the error would be resolved. Still in case you are getting any problem/error please revert back.

For MVC4

Do the Following :

Step 1. Your Global.asax file should look like

            RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

i.e RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true }); line should be there before, BundleConfig and RouteConfig.

Step 2. In _Layout.cshtml, After meta tag your code should look like

       @Styles.Render("/Content/css")
        @Scripts.Render("/bundles/modernizr")
        @*@Scripts.Render("/Scripts/jquery-1.8.2.min.js")*@
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("/Scripts/jquery.signalR-1.1.2.min.js")
        @Scripts.Render("/signalr/hubs")
        <script type="text/javascript">
            $(document).ready(function ()
            {
                var chatHubClient = $.connection.chatHub;
                alert(chatHubClient);
                $.connection.chatHub.start(function () {
                    chatHubClient.join('TEST');
                });
            });
        </script>

Please note that i have commented the jquery-1.8.2.min.js as MVC jquery bundle would fulfill the jquery package requirement.

Step 3. Create your Hub Class, Please make sure that its NOT in App_Code folder, otherwise you would receive the error "An item with the same key has already been added.".

Follow these simple steps and you will be able to run the SignalR code in MVC4.


Thanks
Ritesh Tandon

How to implement Captcha v3 in ASP.NET

 I was facing an issue of dom parsing in my website. I finally resolved it by using Google Captcha V3. Step 1: Get your keys from https:...