잊지 않겠습니다.

'c#'에 해당되는 글 13건

  1. 2009.02.09 ExceptionToHtml Class
  2. 2009.01.08 C# code를 이용한 Xml 문서 작성
  3. 2009.01.07 C# 3.0의 새로운 기능들
Exception을 mail로 보내야지 될 때가 많아서, Exception handler를 간단하게 제작
가장 Key Point는 HttpContext static Member를 이용해서, web에서 발생된 Error도 같이 표현하고 있다는 것이 가장 좋은 점 같다. 

    /// <summary>HtmlError Object.</summary>
    public class ExceptionToHtmlConverter
    {
        public enum ErrorInfoType
        {
            Exception,
            Context
        };
        private delegate string ErrorRendererDelegate(string headerString, NameValueCollection collection);
        static private Hashtable GetErrorInfo(Exception exception)
        {
            Hashtable errorTable = new Hashtable();
            if(exception == null)
            {
                throw new ArgumentNullException("exception");
            }

            // Populate Error Information Collection
            ArrayList errorInfoArray = new ArrayList();
            while(exception != null)
            {

                // Populate Error Information Collection
                NameValueCollection errorInfo = new NameValueCollection();
                errorInfo.Add("Exception Type", exception.GetType().ToString());
                errorInfo.Add("Message", exception.Message);
                errorInfo.Add("Source", exception.Source);
                errorInfo.Add("TargetSite", exception.TargetSite.ToString());
                errorInfo.Add("StackTrace", exception.StackTrace);

                errorInfoArray.Add(errorInfo);
                exception = exception.InnerException;
            }

            errorTable.Add(ErrorInfoType.Exception, errorInfoArray.ToArray());

            if(HttpContext.Current != null)
            {
                Hashtable info = new Hashtable();

                info.Add("QueryString", HttpContext.Current.Request.QueryString);
                info.Add("Form", HttpContext.Current.Request.Form);
                info.Add("Cookies", HttpContext.Current.Request.Cookies);
                info.Add("Session", HttpContext.Current.Session);
                info.Add("Server Variables", HttpContext.Current.Request.ServerVariables);

                errorTable.Add(ErrorInfoType.Context, info);
            }

            return errorTable;

        }
        /// <summary>Returns HTML an formatted error message.</summary>
        static public string GetHtmlError(Exception Ex)
        {
            if(Ex == null)
            {
                throw new ArgumentNullException("Ex");
            }

            // Error Message Header
            StringBuilder sb = new StringBuilder();
            Hashtable errorTable = GetErrorInfo(Ex);
            ErrorRendererDelegate renderer = CollectionToHtmlTable;

            if(HttpContext.Current != null)
            {
                sb.AppendFormat("<font face=\"Arial\" size=\"4\" color=\"red\">An error occurred at {0}<br><font size=\"3\">&nbsp;&nbsp;&nbsp;&nbsp;{1}</font></font><br><br>", HttpContext.Current.Request.Url.ToString(), Ex.Message);
            }

            // Populate Error Information Collection
            foreach(NameValueCollection errorInfo in errorTable[ErrorInfoType.Exception] as object[])
            {
                // Error Information
                sb.Append(renderer("Error Information", BuildCollection(errorInfo)));
            }

            if(errorTable[ErrorInfoType.Context] != null)
            {
                Hashtable info = errorTable[ErrorInfoType.Context] as Hashtable;

                foreach(DictionaryEntry entry in info)
                {
                    sb.AppendFormat("<BR><BR>\n{0}", renderer(entry.Key as string, BuildCollection(entry.Value as ICollection)));
                }
            }

            return sb.ToString();
        }

        /// <summary>Returns HTML an formatted error message.</summary>
        static public string GetTextError(Exception Ex)
        {
            if(Ex == null)
            {
                throw new ArgumentNullException("Ex");
            }

            // Error Message Header
            StringBuilder sb = new StringBuilder();
            Hashtable errorTable = GetErrorInfo(Ex);
            ErrorRendererDelegate renderer = CollectionToTextTable;

            // Populate Error Information Collection
            foreach(NameValueCollection errorInfo in errorTable[ErrorInfoType.Exception] as object[])
            {
                // Error Information
                sb.Append(renderer("Error Information", BuildCollection(errorInfo)));
            }

            if(errorTable[ErrorInfoType.Context] != null)
            {
                Hashtable info = errorTable[ErrorInfoType.Context] as Hashtable;

                foreach(DictionaryEntry entry in info)
                {
                    sb.AppendFormat("\r\n{0}", renderer(entry.Key as string, BuildCollection(entry.Value as ICollection)));
                }
            }

            return sb.ToString();
        }

        #region Private Methods
        static private string CollectionToHtmlTable(string headerString, NameValueCollection collection)
        {

            // Heading Template
            const string heading = @"
  <tr>
    <td bgcolor=""#666666"" colspan=""2"">
      <font face=""Arial"" color=""white""><b>&nbsp;{0}</b></font>
    </td>
  </tr>
";
            // <TD>...</TD> Template
            const string TD = "<td><font face=\"Arial\" size=\"2\"><!--VALUE--></font></td>";

            StringBuilder sb = new StringBuilder();
            // Table Header
            sb.Append("\n<table width=\"100%\" bgcolor=\"#d1d9e4\" cellspacing=\"1\" cellpadding=\"3\">\n");
            sb.AppendFormat(heading, headerString);

            sb.AppendFormat("  <tr bgcolor=\"#d0d0d0\">\n");
            sb.AppendFormat("    {0}\n", TD.Replace("<!--VALUE-->", "&nbsp;<b>Name</b>"));
            sb.AppendFormat("    {0}\n", TD.Replace("<!--VALUE-->", "&nbsp;<b>Value</b>"));
            sb.Append("  </tr>\n");

            // No Body? -> N/A
            if(collection.Count == 0)
            {
                collection = new NameValueCollection();
                collection.Add("N/A", "");
            }

            // Table Body
            for(int i = 0; i < collection.Count; i++)
            {
                sb.AppendFormat("  <tr valign=\"top\" bgcolor=\"{0}\">\n", (i % 2 == 0) ? "white" : "#f4f4f4");
                sb.AppendFormat("    {0}\n", TD.Replace("<!--VALUE-->", collection.Keys[i]));
                sb.AppendFormat("    {0}\n", TD.Replace("<!--VALUE-->", CleanHtml(collection[i])));
                sb.Append("  </tr>\n");
            }

            // Table Footer
            sb.Append("</table>");

            return sb.ToString();
        }
        static private string CollectionToTextTable(string headerString, NameValueCollection collection)
        {

            // Heading Template
            const string heading = "{0}\r\n\r\n";


            StringBuilder sb = new StringBuilder();
            sb.AppendFormat(heading, headerString);


            // No Body? -> N/A
            if(collection.Count == 0)
            {
                collection = new NameValueCollection();
                collection.Add("N/A", "");
            }

            // Table Body
            for(int i = 0; i < collection.Count; i++)
            {
                sb.AppendFormat(" {0} : {1}\r\n", collection.Keys[i], collection[i]);
            }

            return sb.ToString();
        }
        
        static private NameValueCollection BuildCollection(ICollection collection)
        {
            // Overload for HttpCookieCollection collection.
            // Converts HttpCookieCollection to NameValueCollection
            if(collection == null)
            {
                collection = new NameValueCollection();
            }
            NameValueCollection nvCollection = new NameValueCollection();
            IEnumerator en = collection.GetEnumerator();

            object entry;
            while(en.MoveNext())
            {
                entry = en.Current;

                if(collection is HttpCookieCollection)
                {
                    nvCollection.Add(entry.ToString(), (collection as HttpCookieCollection)[entry.ToString()].Value);
                }
                    // Min
                    // CANNOT_MAKE_TEST_CONDITION
                else if(collection is HttpSessionState)
                {
                    nvCollection.Add(entry.ToString(), (collection as HttpSessionState)[entry.ToString()].ToString());
                }
                    // END-CANNOT_MAKE_TEST_CONDITION
                else if(collection is NameValueCollection)
                {
                    if(entry != null)
                    {
                        nvCollection.Add(entry.ToString(), (collection as NameValueCollection)[entry.ToString()].ToString());
                    }
                }
                else
                {
                    throw new NotSupportedException(collection.GetType().ToString());
                }
            }
            return nvCollection;
        }


        static private string CleanHtml(string html)
        {
            // Cleans the string for HTML friendly display
            return (html.Length == 0) ? "" : html.Replace("<", "&lt;").Replace("\r\n", "<BR>").Replace("&", "&amp;").Replace(" ", "&nbsp;");
        }
        #endregion
    }

Posted by Y2K
,
XElement를 이용하면 XmlDocument를 이용한 XmlDocument의 생성보다 편하고 직관적인 방법을 제공할 수 있다.

XElement - Element 생성
XComment - Comments 생성
XDeclaration - Declaration 생성

    public class XmlLinq2
    {
        public void CreateXmlDocument()
        {
            XNamespace nameSpace = "http://www.hostway.co.kr";
            XElement xBookParticipant = new XElement(nameSpace + "BookParticipant");
            XAttribute bookAttribute = new XAttribute("type", "Author");
            XElement xFirstname = new XElement(nameSpace + "FirstName", "Joe");
            XElement xLastName = new XElement(nameSpace + "LastName", "Rattz");
            XComment xComment = new XComment("This is XComment");

            xBookParticipant.Add(bookAttribute);
            xBookParticipant.Add(xComment);
            xBookParticipant.Add(xFirstname);
            xBookParticipant.Add(xLastName);

            Console.WriteLine(xBookParticipant);
        }

        public void FindDatas()
        {
            XNamespace nameSpace = "http://www.hostway.co.kr";
            XElement xBookParticipant = new XElement(nameSpace + "BookParticipant", 
                                                     new XElement(nameSpace + "FirstName", "Joe"),
                                                     new XElement(nameSpace + "LastName", "Rattz"));
            Console.WriteLine(xBookParticipant.ToString());
            Console.WriteLine(xBookParticipant);
        }
    }

: 기초책을 볼때마다 느끼는 거지만.. 언제나 기본인 내용을 모르고 있는 내 모습이 많이 부끄러워질때가 많은 것 같다. 


Posted by Y2K
,

Visual Studio 2008에서는 Targeting을 정해줄 수 있다 : .NET Framework의 종류를 지정해서 compile을 시킬 수 있다.

1. Auto-implemented property

  • Property에서 간단히 값을 저장하는 형식이라면 private 변수들을 선언하거나 property의 구현을 하지 않더라도, 구현이 가능하다.
  • Code가 매우 간단해지고, 간단한 수행에서의 가독성을 높여준다.
  • 기존의 get/set에서의 특별한 행동을 해주는 경우에는 전과 같이 안의 코드를 만들어줘야지 된다.        
    class AutoImplementedClass
    {
        public string Name
        {
            get; set;
        }
        public string Customer
        {
            get;
            private set;
        }
    }

  

2. Object / Collection Initializer

  • Class의 선언과 동시에 private 변수를 초기화 시키는 것이 가능하다.
  • Object / Collection Initialize에서는 {}를 사용하는 것을 유념할것.
  • Public 변수들만 된다.    
    List<int> powers = new List<int>{ 1, 2, 3, 4, 5, 6, 7 };    
    class Point
    {
        public int x, y;        
    }
    Point point = new Point{x = 0, y = 1};

  

3. Local Variable Type Inference

  • Type 명을 적지 않더라도, compiler에서 선언 대치해줄수 있다.
  • 'var' keyword를 이용해서 사용가능하다.
  • 주의할 점은 var에서 type을 변화시킬 수 없는 경우에서는 에러가 나타난다.
  • Type이 동적으로 되는 것이 아니라, 초기화 될때 Type은 결정되어 고정된다.

  

4. Anonymous Type

  • 익명 Type Class
  • 프로그램에서 참조할 수 없다.
  • 복잡한 임시 테이블에 사용하는 것이 좋다. 
    static void Main(string[] args)
    {
        var x = new {a =3 , b = 5, c ="some text"}
        assert.AreEqual(3, x.a)
        assert.AreEqual(5, x.b)
        assert.AreEqual("some text", x.c)        
    }

  

5. Lamda Expression

  • Delegate와 매우 연관이 높다.
  • Lamda expression에서 input/output에서 type을 명확히 넣어주고 싶은 경우에는 type을 결정해서 넣어주면 된다.
  • Func<T> : return 값이 존재하는 경우에 기본적으로 사용되는 delegate type (new delegate로 만들어줘도 상관이 없지만, 기왕에 있는 녀석이면 사용하자.)
  • Action<T> : return 값이 존재하지 않는 경우에 사용되는 delegate type (new delegate로 만들어줘도 상관이 없지만, 기왕에 있는 녀석이면 사용하자.)
    SomeDelegate d3 = s => s.ToUpper();
    SomeDelegate d4 = (string s) => {return s.ToUpper()}
    string a = d3("abcde")

  

6. Extension Methods

  • 기존 Class에 새로운 기능을 추가한다.
  • 상속을 받지 않고도 가능하다.
  • 실행 우선 순위가 Instance method보다 낮다.
  • "this string s" 라는 구문으로 string class에 대한 확장 class를 구현 가능하다.
  • 특정한 API를 만드는 것은 좋지만, 가독성에 심각한 문제를 초래할 수도 있다. 
    public static class Extensions
    {
        public static int ToInt32(this string s)    
        {
            return 0;
        }
    }

  

7. Partial Methods

  • Prital Method는 Partial Class안에 선언되어야지 된다.
  • 반드시 Return type은 void가 되어야지 된다.
  • 반드시 private 한정자에서만 가능하다.
  • C++에서의 함수 선언을 header에서 하는 것과 비슷하게 생각하면 쉽다.
  • 구현부가 없는 경우에는 compiler가 연관된 모든 code를 삭제할 수 있다.

  

8. Query Expressions [LINQ]

  • var = contacts = from c in customers where c.City == "London" SELECT new {c.Customer.ID, c.City}
  • Where 문을 Extension Method를 이용해서 만들어주고, Lamda Expression을 이용해서 내부적으로 code를 작성시켜주게 된다.
    class Customer
    {
        public string CustomerID { get; set; }
        public string ContactName { get; set; }
        public string City { get; set; }
    }
    public class Program
    {
        static void Main(string[] args)
        {
            List<Customers> customers = LoadCustomers();
            var query = from c in customers
                                where c.City == "London"
                                select (new {c.CustomerID, c.ContactName} );
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }                
        }
    }

../C# 3.0/LINQ.png

Posted by Y2K
,