Monday, September 11, 2017

Use case IEquatable and Object.Equal

Introduction

One can use IEquatable for comparing two object values. This is useful when we have to check any duplicate enteries. Let me know if you have any better solution to implement the same use case scenario. I have address string in Address object.

String Comparisons

  • Handle whitespace between two words , letters.
  • Handle trailing and leading spaces
  • Handle casing of strings

//Private Member
private List<Address> _addresses;

//Method for update Address and duplicate checks
public string UpdateAddress(Address personAddress)
{
           
string requestCorrelationId = _client.GetCorrelationRequest();
           
var userContext = _sessionService.Get<UserContext>(SessionKeys.UserContext);
           
try
           {
               
if (IsDuplicateAddress(personAddress))
               {
return "Duplicate some Message"
}
}
}

//Private Method
private bool IsDuplicateAddress(Address personAddress)
{
    
return _addresses().Any(p => p.Equals(personAddress));
}

//Implement IEquatable
public partial class Address : IEquatable<Address>
  {
  
       
public string AddressLine1 { getset; }

       
public string AddressLine2 { getset; }

       
public string AddressLine3 { getset; }

       
public string Suburb { getset; }

       
public string State { getset; }

       
public string PostCode { getset; }

       
public string CountryCode { getset; }

       
public long? Id { getset; }


      public bool Equals(Address newAddress)
      {     
          
if (newAddress == nullreturn false;
          
return 
string.Equals(Regex.Replace(newAddress.AddressLine1 ?? 
string.Empty, @"\s"string.Empty), 
Regex.Replace(AddressLine1, @"\s"string.Empty), 
StringComparison.OrdinalIgnoreCase)
              && 
string.Equals(Regex.Replace(newAddress.AddressLine2 ?? 
string.Empty, @"\s"string.Empty), 
Regex.Replace(AddressLine2, @"\s"string.Empty), 
StringComparison.OrdinalIgnoreCase)
              && 
string.Equals(Regex.Replace(newAddress.AddressLine3 ?? 
string.Empty, @"\s"string.Empty), 
Regex.Replace(AddressLine3, @"\s"string.Empty), 
StringComparison.OrdinalIgnoreCase)
              && 
string.Equals(newAddress.CountryCode ?? 
string.Empty,CountryCode, 
StringComparison.OrdinalIgnoreCase)
              && 
string.Equals(newAddress.PostCode ?? 
string.Empty,PostCode, 
StringComparison.OrdinalIgnoreCase)
              && 
string.Equals(newAddress.State ?? 
string.Empty, State, 
StringComparison.OrdinalIgnoreCase)
              && 
string.Equals(Regex.Replace(newAddress.Suburb ?? 
string.Empty, @"\s"string.Empty), 
Regex.Replace(Suburb, @"\s"string.Empty), 
StringComparison.OrdinalIgnoreCase);
      }

      
public override bool Equals(object obj)
      {
          
if (ReferenceEquals(null, obj)) return false;
          
if (ReferenceEquals(this, obj)) return true;
          
if (obj.GetType() != GetType()) return false;
          
return Equals(obj as Address);
      }

      
public override int GetHashCode()
      {
          
unchecked
          {
              
var hashCode = AddressLine1?.GetHashCode() ?? 0;
              hashCode = (hashCode
*397) ^ (AddressLine2?.GetHashCode() ?? 0);
              hashCode = (hashCode
*397) ^ (AddressLine3?.GetHashCode() ?? 0);
              hashCode = (hashCode
*397) ^ (Suburb?.GetHashCode() ?? 0);
              hashCode = (hashCode
*397) ^ (State?.GetHashCode() ?? 0);
              hashCode = (hashCode
*397) ^ (PostCode?.GetHashCode() ?? 0);
              hashCode = (hashCode
*397) ^ (CountryCode?.GetHashCode() ?? 0);
              hashCode = (hashCode
*397) ^ Id.GetHashCode();
              
return hashCode;
          }
      }
  }

Wednesday, September 6, 2017

Myth Buster ReferenceEquals == Equals()

Introduction


ReferenceEquals and Equals and == are pretty much does the same thing.
  • It compares the object reference to SAME instance.
  • Even if the object reference is of the same type and have same value it returns false.


using System;

namespace ConsoleApplication1
{
    
class Program
    {
        
static void Main(string[] args)
        {
      
            
var c1 = new Car(1, "Matiz");
            
var c2 = new Car(1, "Matiz");
           
            
//COMPARES OBJECT REFERENCES OF DIFFERENT INSTANCES OF SAME TYPE
            
Console.WriteLine(c1.Equals(c2));//false
            
Console.WriteLine(ReferenceEquals(c1, c2));//false
            
Console.WriteLine(c1 == c2);//false
        
            
var c3 = c2;
            
//COMPARES OBJECT REFERENCES OF SAME INSTANCES OF SAME TYPE
            
Console.WriteLine(c3.Equals(c2));//true
            
Console.WriteLine(ReferenceEquals(c3, c2));//true
            
Console.WriteLine(c3 == c2);//true

            
Console.Read();
        }

        
private class Car
        {
            
private readonly int _id;
            
private readonly string _name;

            
public Car(int id, string name)
            {
                _id = id;
                _name = name;
            }
        }
    }
}


Tuesday, September 5, 2017

Asp.net MVC MetaDataType attribute

Introduction

Developers working on asp.net mvc with Entity framework, POCO model or swagger generated web api code generation, mvc metadatatype attribute comes very handy. Everyone should be aware of this construct and usage. I want to file this for my reference hence added small reference here.

Asp.net MVC MetaDataType attribute

Specifications:
  • Only applied to partial class
  • Can be used when you have to do additional validation on entity framework generated entity class or Swagger generated api code for client.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
//Class generated from Entity Framework Database First
public partial class YourModelClass
{
    public string YourProperty{get;set;}
}

//Your Partial Class
[MetadataType(typeof(YourModelClassMetaData))]
public partial class YourModelClass
{
}

//The class that add your attributes
public class YourModelClassMetaData
{
    //validation
    [Required]
    public object YourProperty{get;set;};
}

From <http://patrickdesjardins.com/blog/why-it-is-wrong-to-use-the-asp-net-mvc-metadatatype-attribute

Sunday, September 3, 2017

Static Readonly Constant Vs Const Constant

Constant Static ReadOnly vs Const

Sr.No
public  static readonly int iCentury=100;

public const int iCentury=100;
1
Runtime Constant

Compile Time Constant

2
Can intialize integral, floating ,string enum and NEW operator.
private static readonly DateTime _aheadOfMyTime=
new DateTime(2050,1,1,0,0,0);
Compile Time is eventually assigned with literals and can only be used with primitive datatype such as built in integral, floating point type,enum string. You can initialize compile time with new operator. They are limited to numbers and strings value

3
Unlike Const bit of performance overhead.

Better Performance and more efficient
4
Client A=> Assembly A[static readonly iCentury]
Client B=> Assembly A[Static readonly iCentury]

IL generated for client A and B will have reference readonly variable[iCentury] not value

Client A=> Assembly A[const iCentury]
Client B=> Assembly A[const iCentury]

IL generated for client A and B will have values of const not reference Variable
5
In terms of maintenance purpose readonly is more appropriate as client is not required to be compiled only assembly is compiled.

Whereas const require all assembly and dependent client to be build and compiled for each release
6
This is more suitable if constant is prone to change for each release
Not viable if constant value is changing for each release.


Sunday, August 13, 2017

Powershell ISE Cheat sheet

1# How to Comment Multi line code in ISE editor

Put cursor on start of code. Select Shift +Alt and move down arrow key to end of code line. Then press Shift +#

2# How to open/load web page ?

start-process -FilePath "www.google.com.ua"


Thursday, August 3, 2017

Sitecore XFrameOptionsHeaderModule and Chrome 60.0.3112.78 (official build) (64-bit) x-frame-options SAMEORIGIN Refused to display

Introduction

Chrome Side of story:-
X-Frame-Option Same origin issue appeared in Chrome version 60+ and it came surprising when browser started upgraded from lower version to this version. What if such issue appeared in production where your platform is dependent on third party service provider such as payment gateway through IFrame or any data layer that injects data to your system. Well the point is everything boils down to how secure you want to create a platform.

Your site- Domain ABC- Allow access to Domain XYZ[SameOrigin will not work]
Chrome version 60 and above enforce this and check this X-frame-options.

What happened next?
It started throwing below error in developer tool f12 - console

Refused to display https://abc' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
iframe-tunnel.js:60 GET https://xyz net::ERR_BLOCKED_BY_RESPONSE


Sitecore MVC Side of story:-

From sitecore 8.1 update 3 onwards sitecore introduce default module to add X-FRAME-OPTION Sameorigin using below module

One can check this in web.config file
 type="Sitecore.Web.XFrameOptionsHeaderModule, Sitecore.Kernel" name="SitecoreXFrameOptionsHeaderModule"/>
Reference


Probable Solution

using System.Web.Mvc;

namespace Test.Filters
{
    public class RemoveXFrameOptionsAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Headers.Remove("X-Frame-Options");
            base.OnResultExecuted(filterContext);
        }
    }
[RemoveXFrameOptions]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
}
//or 
//this worked for us.
public class TestController : Controller
{
    [RemoveXFrameOptions]
    public ActionResult Index()
    {
        return View();
    }
}

https://stackoverflow.com/questions/35466242/removing-x-frame-options-header-for-a-specific-controller-only

Bit of background

Why x-frame-options SameOrigin thing? This is required to avoid CLICK JACKING.

https://www.codeproject.com/Articles/291562/Asp-net-web-application-Security-Review-Dos-Dont

My final Say

Sitecore should add this in their KB site to be more explicit so that customer is aware of such changes.

Thursday, July 20, 2017

IIS Log Parser and important troubleshooting queiries

Understand your IIS Log better

There are cases when even asp.net and sitecore application level logs doesn't provide much of an information.The reason behind is some request is just processed by IIS webserver but never executed at application server i.e sitecore or asp.net pipeline.

This is where HTTP.Sys , Failed Request Tracing and IIS logs comes into picture. This is not when you looking for memory leak or CPU utilization.But this is certain some of the pattern of page execution or 500 internal server exception indirectly contributes to memory leak or CPU utilization. Always visit your IIS logs post performance load test. This will help you align your performance results with incoming request made in IIS.

Long story short. Download log parser studio if you have IIS log to analyze. This is very handy tool.

https://gallery.technet.microsoft.com/office/Log-Parser-Studio-cd458765

Query#1 Http.5xxx


SELECT TO_LOCALTIME( TO_TIMESTAMP( date, time ) ),
    cs-username,
    sc-status,
    sc-substatus,
    cs-uri-stem,
    time-taken as time_taken_MS,
    DIV(time-taken,60000) as timetaken_MM,
    cs-method, 
    cs-uri-query ,
    Count(*) AS Total
    From '[LOGFILEPATH]'
    Where sc-status = 500
    Group By cs-username, sc-status, cs-uri-stem, cs-uri-query,date,time,cs-method, cs-uri-query ,time-taken,sc-substatus



Query#2:/*  Count and sort all HTTP status codes */
Remember http status code below have apended http SUB STATUS CODE

SELECT TOP 25  
    STRCAT(TO_STRING(sc-status),  
    STRCAT('.', TO_STRING(sc-substatus))) As Status,  
    COUNT(*) AS Hits  
    FROM '[LOGFILEPATH]'  
GROUP BY Status  
ORDER BY Hits DESC 

Query#3 To find DDOS Attack

A distributed denial-of-service (DDoS)attack occurs when multiple systems flood the bandwidth or resources of a targeted system, usually one or more web servers. Such an attack is often the result of multiple compromised systems (for example, a botnet) flooding the targeted system with traffic.

/* Hits on a particular page by IP address */

select c-ip, count(c-ip) as requestcount 
from '[LOGFILEPATH]' 
where cs-uri-stem like '%/%' 
group by c-ip order by count(c-ip) desc



Monday, July 10, 2017

Sitecore Pipeline HttpBeginRequest and Processor HttpRequestProcessor to Intercept requests before page get processed completely.

Problem Statement:
To intercept each request and check site configuration and take required steps before it is served and processed complete. This can be enabling intermediate maintenance page or site down page in case unfortunate events occurred such as third party service is down . This in particular is the case your content site is more dependent on upstream or downstream application to serve user specific data. Even though you aimed for zero downtime as per your architecture.

Solution:
Approach 1: To check this flag at every action call using action filter in mvc sitecore controller.
Approach 2: To intercept the call before it call action filter.

Reference: Pipeline and its Processor

Implementation:


Add processor just after ItemResolver to intercept the request to check for sitecore stored flag and take action based on values that something suits your requirement

Pipeline: httpBeginRequest: Sitecore.Pipelines.HttpRequest





Key Notes:
  • Ensure you have proper patch insert for CD and delete for CM. As per the scenario.
  • Ensure you have AbortPipeline in place to prevent -Cascading response header issue- Such as append header and results in Too many redirects.
  • Use custom processor wisely and regression test to cover different use case across the page navigation involves logout /login [For transactional Site or Personalised site]

Thursday, July 6, 2017

Maintenance Page Take App Offline! Magic with App_Offline.htm


Overview


The App_offline thing is around for quiet long time and I haven't seen enterprise level system use it. Either they do it using at load balancer end or redirect to some third party hamster page until the site is provision for up and running. Leaving the real time usage and know-how.

Headstart




Here are quick help tip if you want to enable it.


Key Note
Remember just putting App_offline.htm in the root folder of the website will just stop the further processing of request and always return =

Http Status 503:

The service is unavailable.


If you really want to show up App_Offline.htm custom page you must add this in your web.config file


Refer this for more information
https://stackoverflow.com/questions/17135109/app-offline-site-returning-the-service-is-unavailable


One can even try to automate this using FTP command and powershell or either use out of the box option in VSO Build and Release pipeline.


Take App Offline option under Deployment


Tuesday, July 4, 2017

Gotcha ! Special Character & in web.config


What is special about &?


Whenever you're dealing with ampersand or querystring url in rewrite rules beware of special character "&". There are chances you may play around with different ways to make it working. Inline rewritemap maps things bit difficult. Yes it might happen you have few rewrite and you end up with inline rewrite in web.config. Careful watch rewritemap urls as these may content special character as part of URI and redirection symantics. Sometimes # results in error and exception.


Always try this!



  • Replace & with &Make use of html encode and decode instead of URL Encode value such as "%26"
  • Good practice to keep rewritemap outside web.config . In many scenario the URL encode for ampersand as well # in querystring works.


References:







Monday, July 3, 2017

Sitecore CMS Logout not working due to conflicting Authentication Controller



Introduction

Sitecore CMS Logout will throw Javascript error due to multiple controller named 'Authentication'


Sitecore Logs
10344 02:57:52 ERROR Application error.
Exception: System.InvalidOperationException
Message: Multiple types were found that match the controller named 'Authentication'. This can happen if the route that services this request ('sitecore/shell/api/sitecore/{controller}/{action}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

The request for 'Authentication' has found the following matching controllers:
Sitecore.Controllers.AuthenticationController
MyWebsite.MyArea.Controllers.Api.AuthenticationController
Source: System.Web.Mvc
   at System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces)
   at System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext)
   at Sitecore.Mvc.Routing.RouteHandlerWrapper.GetHttpHandler(RequestContext requestContext)
   at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


Resolution


  1. Either rename your custom controller from Authentication to something Account to avoid sitecore conflict.
  2. Else apply below Maproute.

public override void RegisterArea(AreaRegistrationContext context) 
       {           
           context.MapRoute(
            "SCAuth",
              "sitecore/shell/api/sitecore/{controller}/{action}",
              new { controller = "Authentication", action = "Index" },
              new[] { "Sitecore.Controllers" });
 
 
       }

Reference:
https://sitecore.stackexchange.com/questions/201/how-to-override-replace-the-default-sitecore-authentication-controller

Sitecore .Net File Change Notification Shut down issues

 

Problem Statement

Not sure what is causing file change in webapps whether it is appinsight or for that matter logging handler that keep adding debug, info and error traces, cache or something else. For some reason there is something going under the hood which causes this file change notification. This take me back to the basics of file change notification causes app pool recycle when there is change in web.config or global.asax. Now as best practice it is always mentioned the logging has to be done outside your webroot and for some reason this is not the case with webapp. I'm naïve in webapp world and file and drive structure in azure webapp paas environment. Those days are gone when you use to have full control of VMs and you can deep dive into solving and identifying issues.


KB: Sitecore stability issues when using Azure Web Apps

It talks about dynamic cache- WEBSITE_DYNAMIC_CACHE

FCN Cause and Effect
Now this file change notification itself is a problem which as ripple effect on few things. This is how it works.
Chain and sequences of events due to FCN- Filewatcher/File change notification
  1. File change notification, filewatcher notification triggers
  2. Sitecore shut down
  3. Solr or lucene Indexing lookup failed. Empty Index found.
  4. Session State, if sql , Redis or Mongo used: Failure of session state, results in session leaks and session_end events, and all other subsequent calls.
  5. XDb: Analytics current tracking failed or current tracking is null
  6. Eventually spike in CPU utilization and memory leaks.

How it goes?

FCN Cause -> Affected--> Sitecore shut down-> Session --> Indexing--> Analytics-> CPU utilization--> Memory Leaks

It is very important to understand how we approach to the problem and how we look up error logs. It is not that straight forward instead need problem occurrence chart[Fish bone technique to lay down the cause and effect] to note down each events. In fact I see this as solving mystery or identify suspects. Like above chain of sequence. As rule of thumb memory leaks and CPU utilization always leads you to bad code or DI leaks etc. I insist more lateral thinking than primitive way of identifying problem.

.Net Way Short term Workaround: Brute force Fixes



As a work-around I have added fcnMode = "Disabled" to the httpRuntime element in the web.config. The root cause remains unknown.


httpruntime fcnmode="Disabled"/

Wednesday, June 21, 2017

KeepAlive Url agent SSL Forced authentication issues and quick fix!

Table of Contents

  1. Introduction
  2. Problem Statement: Failed SSL forced Authenticatio
  3. Bit of a background
  4. Quick Fix: Sitecore SSL Keepalive UrlAgent Issue
  5. Miscellaneous Custom UrlAgent for KeepAlive

Introduction


The purpose of this article is bring forward the key issues that one can come across when dealing with keepalive url. I'll not delve deep into what is Keepalive rather I'll focus on problem statement and list of references that can handy. Also I have given my way of approaching to the solution in different scenario. Maybe the solution I have provided may not stand the best recommended practice however it atleast give some foresight to deal with issues like this. The content more or less is about using https :// keepalive url when working with .net 4.5 azure webapp or environment required forced ssl.

Problem Statement: Failed SSL forced Authentication



Bit of a background


The SSL forced authentication will only arise if you have forced https for your website and http is restricted through firewall. Now if you are using .net 6.0 or higher this will work without any issue whereas .net 4.5 and lower version will not enforce TLS protocol by default.You may have to set them explicitly to map to your ssl certificate.
  • .NET 4.6 and above. You don’t need to do any additional work to support TLS 1.2, it’s supported by default.
  • .NET 4.5. TLS 1.2 is supported, but it’s not a default protocol. You need to opt-in to use it.
Refer this http://blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support/

***Poodle Attack


As per my understanding reason to do this to prevent poodle attack. Refer this for more details Security bulletin TechNet Poodle Attack

***SSL Scan


You can scan your site for poodle attack. Scan your site for poodle attack SSL Scan Test

Quick Fix: Sitecore SSL Keepalive UrlAgent Issue


Add this  Global.asax startup Or application Start method for .net 4.5 web app. This explains lot https://stackoverflow.com/questions/28286086/default-securityprotocol-in-net-4-5
 System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 
Add this to your web config Ip restriction to allow access to O.0.0.0 azure webapps




http://www.secqa.com/index.php?qa=2247&qa_1=sitecore-azure-website-forbidden-its-access-permissions-127
https://stackoverflow.com/questions/34389510/sitecore-8-1-azure-website-forbidden-by-its-access-permissions-127-0-0-1/34869927
https://stackoverflow.com/questions/24884098/azure-website-ip-restriction

The above solution will solve your forced ssl authentication issue.

Sitecore support KB must eloborate and refine this one to reduce number of support request. https://kb.sitecore.net/articles/376036 [Check out 4th Scenario Covered]

Someone even face this for mongo integration. http://techqa.info/programming/question/39699800/Intermittent--Authentication-failed-because-the-remote-party-has-closed-the-transport-stream-----Mongo-C-

Miscellaneous Custom UrlAgent for KeepAlive


If you are facing some other issues you will always have an options to create custom URLagent like this one below. I tried to create one with adding above solution. You can even create generic version to get azure host using custom solution making use of sitecore webutil. For e.g calling out of box webtil methods. for e.g GetHostIPAddress
Making use of above method we can create custom urlagent and add it to our solution.For testing purpose we reduce the interval to 2 minutes. Sitecore.config

using Sitecore.Diagnostics;
using Sitecore.Web;
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MyProject
{
    public class SslUrlAgent
    {

        private bool _logActivity = true;
        private readonly string _url;

        public bool LogActivity
        {
            get
            {
                return this._logActivity;
            }
            set
            {
                this._logActivity = value;
            }
        }


        public SslUrlAgent(string url)
        {
            Assert.ArgumentNotNull((object)url, "url");
            this._url = url;
        }

    
        public void Run()
        {
            try
            {
                string fullUrl = WebUtil.GetFullUrl(this._url);
                this.LogInfo("Scheduling.UrlAgent started. Url: " + fullUrl);
                this.LogInfo("Scheduling.UrlAgent done (received: " + (object)ExecuteSSLWithCertificatePolicyWebPage(fullUrl).Length + " bytes)");
            }
            catch (Exception ex)
            {
                Log.Error("Exception in UrlAgent (url: " + this._url + ")", ex, (object)this);
            }
        }
     
        private bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
            // If the certificate is a valid, signed certificate, return true.
            if (error == System.Net.Security.SslPolicyErrors.None)
            {
                return true;
            }

            LogInfo("ICertificatePolicy: " + error.ToString());

            return false;
        }
        private string ExecuteSSLWithCertificatePolicyWebPage(string url)
        {
            System.Net.ServicePointManager.ServerCertificateValidationCallback += (send, certificate, chain, sslPolicyErrors) => { return true; };
            using (WebClient webClient = new WebClient())
            {
                // System.Net.ServicePointManager.ServerCertificateValidationCallback += (send, certificate, chain, sslPolicyErrors) => { return true; };
                // ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;                          
                return Encoding.UTF8.GetString(webClient.DownloadData(url));
            }         
        }
      
        private void LogInfo(string message)
        {
            if (!this.LogActivity)
                return;
            Log.Info(message, (object)this);
        }
    }
}

 
Some useful webutil method for reference. I used dotPeek to get the implementation of these method.
    public static string GetFullUrl(string url)
    {
      Assert.ArgumentNotNull((object) url, "url");
      return WebUtil.GetFullUrl(url, WebUtil.GetServerUrl());
    }


 
    public static string GetFullUrl(string url, string serverUrl)
    {
      Assert.ArgumentNotNull((object) url, "url");
      Assert.ArgumentNotNull((object) serverUrl, "serverUrl");
      if (url.IndexOf("://", StringComparison.InvariantCulture) < 0)
        return FileUtil.MakePath(serverUrl, url, '/');
      return url;
    }


 
    public static string GetHostIPAddress()
    {
      HttpContext current = HttpContext.Current;
      try
      {
        if (current != null)
        {
          if (current.Request != null)
          {
            Uri url = current.Request.Url;
            if (url.HostNameType == UriHostNameType.Dns)
            {
              IPHostEntry hostEntry = Dns.GetHostEntry(url.Host);
              if (hostEntry.AddressList.Length >= 0)
                return hostEntry.AddressList[0].ToString();
            }
          }
        }
      }
      catch (SocketException ex)
      {
        Log.SingleWarn(string.Format("Cannot resolve the IP address of the web server with the specified hostname: {0}.", (object) current.Request.Url.Host), (object) typeof (WebUtil));
      }
      return string.Empty;
    }

 
 
    public static string GetHostName()
    {
      HttpContext current = HttpContext.Current;
      if (current != null && current.Request != null)
        return current.Request.Url.Host;
      return string.Empty;
    }

 
 
    public static string GetIISName()
    {
      HttpServerUtility server = WebUtil.GetServer();
      if (server != null)
        return SecurityUtil.ComputeHash(server.MapPath("/"));
      return string.Empty;
    }




With above implementation if you have any webproxy issue or anything you can try to resolve using custom urlagent approach as given above. Hope this article help you to some extend. Thanks.