Using Function Name, Line Number, and Source File for C# Logging

Using Function Name, Line Number, and Source File for C# Logging

We want a custom logger for C# that automatically helps with function name, line number, and source file name. We can use the following attributes on our function arguments:

  • CallerMemberName
  • CallerFilePath
  • CallerLineNumber

Here’s a code sample on how to put it together:

public void LogMessage(string message,
						 [CallerMemberName] string callingFunction = "",
						 [CallerFilePath] string sourceFilePath = "",
						 [CallerLineNumber] int sourceLineNumber = 0)
{
	Debug.WriteLine("message: " + message);
	Debug.WriteLine("function name: " + callingFunction);
	Debug.WriteLine("source file path: " + sourceFilePath);
	Debug.WriteLine("source line number: " + sourceLineNumber);
}

Finally, we can make a call to our LogMessage function like this and the calling function, source file path, and source line number will automatically get populated with the correct values:

LogMessage("INFO: Log message details go here.");

 

Posting with Cookie Containers in C#

Posting with Cookie Containers in C#:

We want to use C# and make a web call Rest POST call to some web API, and we need to add cookie values to our request.

 

We’ll extend the basic WebClient C# class like this:

 

    public class MyWebClient : WebClient
    {
        public MyWebClient(CookieContainer container)
        {
            this.container = container;
        }
        public MyWebClient()
        {
        }

        public int Timeout { get; set; }

        public CookieContainer CookieContainer
        {
            get { return container; }
            set { container = value; }
        }

        private CookieContainer container = new CookieContainer();

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest r = base.GetWebRequest(address);
            r.Timeout = Timeout;
            var request = r as HttpWebRequest;
            request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
            if (request != null)
            {
                request.CookieContainer = container;
            }
            return r;
        }

        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
        {
            WebResponse response = base.GetWebResponse(request, result);
            ReadCookies(response);
            return response;
        }

        protected override WebResponse GetWebResponse(WebRequest request)
        {
            WebResponse response = base.GetWebResponse(request);
            ReadCookies(response);
            return response;
        }

        private void ReadCookies(WebResponse r)
        {
            var response = r as HttpWebResponse;
            if (response != null)
            {
                CookieCollection cookies = response.Cookies;
                container.Add(cookies);
            }
        }
    }

 

Then, we can use the new custom WebClient to assign our cookie name and value pairs and make our POST calls like this:

using (MyWebClient client = new MyWebClient())
{
	client.Timeout = 900000;
	client.Encoding = UTF8Encoding.UTF8;
	client.Headers.Add("Accept-Encoding", "gzip, deflate, br");
	client.Headers.Add("Accept-Language", "en-US,en;q=0.8");
	client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36");
	client.Headers.Add("Content-Type", "application/json");

	client.CookieContainer.Add(new Cookie(myAuthCookieName, myAuthCookieValue, "/", postDomain));

	string urlResult = client.UploadString(postApiUrl, postData);
	Console.WriteLine(urlResult);
}

It’s that easy! Now, you can make POST calls to web APIs with WebClient and include cookie name/value pairs along with your request.