Logging for ASP.NET MVC 4: log4net

Logging is always an important part of a software project, tracing errors, passing audits, and allow monitoring etc.

I know how to use log4j in Spring framework, but today I have worked a little on C# MVC 4.

How to easily add logging into ASP.NET MVC 4 code base ?

I use log4net, and you can simply download it from VS NuGet store.

Steps for setting up after installation of log4net package:

1. Open  Global.asax.cs

protected void Application_Start() {
log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));

2. Open Startup.cs

[assembly: log4net.Config.XmlConfigurator(ConfigFile="Web.config", Watch = true)]

3. Open Web.config

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="app-log.txt" />
<appendToFile value="true"/>
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %logger (line:%line) - %message%newline" />
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender" />

4. Any namespace, say in Controller:

using log4net;
public class AccountController : Controller
readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public AccountController()
private bool try(){ log.Error("Error message"); }

The only thing missing here is that I have not tried to log Database SQL error. May update this later.

Bypass IdentityManager Popup in ESRI ArcGIS JavaScript API

When using ArcGIS secure layers in JavaScript API 2.5+, the default IdentityManager will come out as a login process for web app users.Please see example at http://developers.arcgis.com/javascript/samples/widget_identitymanager/ What if I already have a login for a web app, and do I need to login again for the map layers? What can be done to avoid the IdentityManager Popup ? Login use ArcGIS REST API: see http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r3000000m5000000 And then bypass the IdentityManager Popup.

//just use AJAX, you can put this login in any page
var timeout = 1440, referer = hostname + '/arcgis/rest';
var postData = {
    'username': username,
    'password': password,
    //'client': 'requestip', //can't work if using this type of request
    'referer': referer,//should be the web app host name
    'expiration': timeout,
    'f': 'json'//,
    //'encrypted': 'true' //if need to enable, please add the necessary js files, see generateToken page source code from ArcGIS
//processing data encryption
//postData = encryptFormData(postData, modulus);
   url: url,//hostname/arcgis/tokens/generateToken
   cache: false,
   type: 'POST',
   dataType: 'jsonp',
   data: postData,
   crossDomain: true,
   success: function (response) {
    if (response) {
        if (response.error) { // access error
         return false;
        } else {
         //store username and token in cookies
         setCookieName("arcgisusername", username, 12);
         setCookieName("arcgistoken", response.token, 12);
     } else {
        return false;
   error: function (error) { // system error
    return false; 

//bypass the popup
//require IdentityManager
//now build a identitymanager json object to init the object
var now = +(new Date());
var expires = now + (timeout*60000);
var imObject = {
"serverInfos": [
"server": hostname,
"tokenServiceUrl": hostname + "/arcgis/tokens/",
"adminTokenServiceUrl": hostname + "/arcgis/admin/generateToken",
"shortLivedTokenValidity": timeout,
"currentVersion": 10.22,//update necessary
"hasServer": true
"oAuthInfos": [],
"credentials": [
"userId": getCookieName('arcgisusername'),
"server": hostname,
"token": getCookieName('arcgistoken'),
"expires": expires,
"validity": timeout,
"ssl": false,
"creationTime": now,
"scope": "server",
"resources": [
hostname + '/arcgis/rest/services'

//Please remember that if you need to query some layer data using ajax or using some layer URL,
// you need to manually append the '&token=sometokenfromserver' for the URL

I found another hack to bypass the ArcGIS IdentityManager popup or a new method to access secure layers.

This requires coding in .NET/C#. I figure out that ArcGIS server use request cookie name agstoken as an authentication method for accessing secure layers.So if I can create a login form and post to the Login.aspx and send the response with cookie contains agstoken which I can freely request from ArcGIS services using the REST API.

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
namespace Login
    public partial class _Login : System.Web.UI.Page
        protected void Page_Load(object sender, EventArgs e)
            //code for normal user login, if failed, then redirect to login page
  	    string h = "hostname";
	    //h = Request.UserHostAddress;//may not work as direct ip address
            Response.AddHeader("Access-Control-Allow-Origin","*"); //may tighten the access
            Response.AddHeader("Access-Control-Allow-Methods", "POST");
            Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
	    HttpCookie c2 = Request.Cookies.Get("agstoken");
	    HttpCookie c3 = Request.Cookies.Get("agsapperror");	
	    string timeout = "1440";//mins
	    string u = Request["u"].ToString();
	    string p = Request["p"].ToString();
	    string referer = h;
	    string tokenURL = h + "/arcgis/tokens/generateToken";
            string type = "application/x-www-form-urlencoded";
            string token = "";
            WebClient wc1 = new WebClient();	
	          string loginData = "username="+u+ "&password="+p+     
                  wc1.Headers[HttpRequestHeader.ContentType] = type;
	          string loginContent = wc1.UploadString(tokenURL, loginData );
	          //check result      
			if(c3 == null){
			     c3 = new HttpCookie("agsapperror");
			     c3.Value  = "userpasswordwrong";
			     c3.Expires = DateTime.Now.AddMinutes(10d);
		          //push user token for accessing secure layers
			  token = getUserToken(loginContent);
                          if(c2 == null){
				c2 = new HttpCookie("agstoken");
				c2.Value  = token;
				c2.Expires = DateTime.Now.AddMinutes(1440d);
	       } catch (WebException e1) {
                   //Response.Write("{\"error\":\"network connection error\"}");
	public string getUserToken(string tokens){
	    string token = ""; 
               string [] r = tokens.Split(new string[]{"\",\""},StringSplitOptions.None);
	       if(r.Length > 0){
                   string part1 = r[0];
                   string [] r2 = part1.Split(new string[]{"\":\""},StringSplitOptions.None);
                   token = r2[1];   
	  return token;