1. Function Review: Satisfy requirement
2. Security Review: SQL injection prevention and valid user input
3. Test Review: Accept Test and Unit Test coverage
4. Code quality Review:
a. Readable:  Name Convention, length of function
b. Solid principle
1) Single Responsibility, DRY (don't repeat yourself), make code reusable
2) Dependence,  check New instance code, check if interface defined. (testable)
3) Open Close, check "switch case", "if else" "Enum" code

c. other code refactor check
1) "out" "ref"
2) null check
d. Good performance check
e. Exception handle
f. Logging
g. Try best to remove the project build warning.


some useful ref:
http://www.codeproject.com/Articles/593751/Code-Review-Checklist-and-Guidelines-for-Csharp-De
http://www.amazedsaint.com/2010/11/top-6-coding-standards-guideline.html
http://www.codeproject.com/Articles/524235/Codeplusreviewplusguidelines


 
Categories: Agile | C# | Interview Question

this is a unsign saml response xml, the value need be change every submit was replaced by {time1} or {guid1}.
before sign the xml, those value will be update.  otherwise it will not pass the Saml validation.
If you got "Assertion was replayed" error. that because the time is not correct or AssertionId already be used.



After the Saml Xml build and signed, there is one more thing need change,
the RSA Saml Relay part only take the signature before the issuer, but the DotNet sign the xml and insert as the last Child, so we need additional code to make it work:

            SignXmlHelper.SignXml(xmlDoc, cert, "ID", guid1);
            //var item=  xmlDoc.GetElementsByTagName("Signature").Item(0);
            XmlElement xmlElement = xmlDoc.DocumentElement;
            var signatureNode = xmlElement.LastChild;
            xmlElement.InsertAfter(signatureNode, xmlElement.FirstChild);

            var outstr = xmlDoc.OuterXml;
Last notice:
 when you post the saml, in saml1, the target url is TargetUrl, but for saml2, it changed to relaystate

 
Categories: Asp.net | C# | Security

http://referencesource.microsoft.com/netframework.aspx

the download page only work under IE ;)

Available Source Code Components

 

Product NameVersionViewDownload
.NET8.0View EULADownload
dotnetfx1434_VistaWin2k8sp150727.1434View EULADownload
FXUpdate307450727.3074View EULADownload
ASP.NET_MVC1.0View EULADownload
WCF3.5SP1View EULADownload
WF3.5SP1View EULADownload
Dotnetfx_Vista_SP250727.4016View EULADownload
Dotnetfx_Win7_3.5.13.5.1View EULADownload
ASP.NET_MVC2.0View EULADownload
.Net4View EULADownload
.NET_3.5_sp1_redist50727.3053View EULADownload
ASP.NET_MVC3View EULADownload
Netfx_3.5.1_Win7SP13.5.1View EULADownload
NET4.5View EULADownload
Net4.5Update1View EULADownload


 
Categories: Asp.net | C# | MVC | Visual studio 10/up | WCF

Saml Response is Assertion xml with digital signature,
so , when get xml of Saml XML, and your x509 certificate,
you can use follow code to sign it.

Here is examples.
http://msdn.microsoft.com/en-us/library/ms229745%28v=vs.110%29.aspx

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;

public class SignXML
{

    public static void Main(String[] args)
    {
        try
        {
            // Create a new CspParameters object to specify 
            // a key container.
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";

            // Create a new RSA signing key and save it in the container. 
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

            // Create a new XML document.
            XmlDocument xmlDoc = new XmlDocument();

            // Load an XML file into the XmlDocument object.
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load("test.xml");

            // Sign the XML document. 
            SignXml(xmlDoc, rsaKey);

            Console.WriteLine("XML file signed.");

            // Save the document.
            xmlDoc.Save("test.xml");



        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }


    // Sign an XML file.  
    // This document cannot be verified unless the verifying  
    // code has the key with which it was signed. 
    public static void SignXml(XmlDocument xmlDoc, RSA Key)
    {
        // Check arguments. 
        if (xmlDoc == null)
            throw new ArgumentException("xmlDoc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = rsaKey;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);

        // Compute the signature.
        signedXml.ComputeSignature();

        // Get the XML representation of the signature and save 
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));

    }
}


http://www.codeproject.com/Articles/56640/Performing-a-SAML-Post-with-C
public static XmlElement SignDoc(XmlDocument doc, X509Certificate2 cert2, 
              string referenceId, string referenceValue) {
    SamlSignedXml sig = new SamlSignedXml(doc, referenceId);
    // Add the key to the SignedXml xmlDocument. 
    sig.SigningKey = cert2.PrivateKey;

    // Create a reference to be signed. 
    Reference reference = new Reference();

    reference.Uri = String.Empty;
    reference.Uri = "#" + referenceValue;

    // Add an enveloped transformation to the reference. 
    XmlDsigEnvelopedSignatureTransform env = new
        XmlDsigEnvelopedSignatureTransform();
    XmlDsigC14NTransform env2 = new XmlDsigC14NTransform();

    reference.AddTransform(env);
    reference.AddTransform(env2);

    // Add the reference to the SignedXml object. 
    sig.AddReference(reference);

    // Add an RSAKeyValue KeyInfo
    // (optional; helps recipient find key to validate). 
    KeyInfo keyInfo = new KeyInfo();
    KeyInfoX509Data keyData = new KeyInfoX509Data(cert2);

    keyInfo.AddClause(keyData);
    
    sig.KeyInfo = keyInfo;

    // Compute the signature. 
    sig.ComputeSignature();

    // Get the XML representation of the signature
    // and save it to an XmlElement object. 
    XmlElement xmlDigitalSignature = sig.GetXml();

    return xmlDigitalSignature;
}

Signed xml sample:
http://www.aleksey.com/xmlsec/api/xmlsec-examples-sign-x509.html



 
Categories: Asp.net | C# | Security

I am working on the SAML authentication for our Mobile app,
get some resource to build my test SAML Identity Service Party

http://www.componentpro.com/download/?name=UltimateSaml
http://www.componentpro.com/doc/saml/Introduction_to_Single_Sign-On_Applications.html

http://www.componentspace.com/Downloads.aspx

to create private key and public key,
we can use Visualstudio command line makecert.exe, but easiest way is using the gui tool from:
http://blog.pluralsight.com/selfcert-create-a-self-signed-certificate-interactively-gui-or-programmatically-in-net

first save the rsa key to pfx file by use selfcert tool.

then you can import it and export to to cer file.
you need use "mmc" command and add certificate snap to view the certificates.

or you can use openssl (need install it first),

C:\Users\wsun>openssl pkcs12 -nokeys -clcerts -in ix.pfx -out ix.cer
Enter Import Password:
MAC verified OK


 
Categories: C# | Security | Visual studio 10/up

I don't want to use jsonP because it only can use "GET" method and all the data can be viewed on url.
After many search and failed test code. Finally I got below solution:

1. Enable CORS on server,
  a. asp.net site said you can enable cors for webapi: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api . unfortunately, it require preview version of visual studio 2013.
  b. http://enable-cors.org/ site offer the methods to enable cors on IIS7, But it not works in my test.
  c. so I have to add the Access-Control-Allow-Origin=* to the response header by code myself.
    Simplest way is  adding this function in global.asax.cs
   protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            
        }

my test Action:
 public ContentResult Test(FormCollection formValues,string user="", string pwd="" )
        {
            dynamic flexible = new ExpandoObject();
            flexible.UserName = user;
        

            var dictionary = (IDictionary<string, object>)flexible;
            dictionary.Add("IsSuccess", true);

            var re= JsonConvert.SerializeObject(dictionary); 
          
            return  Content(re);
        }

2. It's not finish yet. you can see the correct response was return to the client in Fiddle or firebug, but the JQuery ajax call success not be fired. we have to do some more code on client side:
var loginUrl = 'http://localhost:6660/home/test';
        var data = "user=a&pwd=b";
        $.ajax({
            type: 'POST',
            url: loginUrl,         
            data: data,
            sucess:function(re) {
                //never reached here
            },
            error: function (jqXHR, error, errorThrown) {
                //handle err
            },
            complete: function (re, status) {
                if (status == 'success') {
                    var reObj = JSON.parse(re.responseText);
                    //todo
                }               
            }
        });

Yub!  date was get from cross domain server. this even working open html file directly.


 
Categories: Asp.net | C# | JQuery | MVC

Server side code in controller:
     public ContentResult TaskJsonP(string callback,int id)
        {
            var model = service.GetTaskDetails(new TaskDetailRequest() { Id = id });
            //return Json(model, JsonRequestBehavior.AllowGet);
            return Content(String.Format("{0}({1});",
          callback,
          new JavaScriptSerializer().Serialize(model)),          
          "application/javascript");

        }
Client side you can open any page and try below:
$.get("http://localhost:45897/home/taskJsonP/1",
                  
                   function(value)
                   {
                       alert (value)              },
                   "jsonp"
             );


 
Categories: Asp.net | C# | Html5 | JQuery | MVC

Reference:

http://www.codeproject.com/Articles/105497/Automated-UI-tests-with-Watin-in-ASP-NET-MVC

http://blog.willbeattie.net/2011/06/getting-started-with-specflow-watin.html 

My Spectflow feature file

My Step files:
#region Fill fields in form and Submit UserAccountInfo Request

    [Given(@"I on the UserAccountInfo metadata UI test page")]
    public void GivenIOnTheUserAccountInfoMetadataUITestPage()
    {
        CurrentBrowser.GoTo(@"http://localhost:45166/TestWidgetAction?widgetName=BusinessCenterAdminWidgetUser&actionName=UserAccountInfo&returnFormat=HTML");
        CurrentBrowser.WaitForComplete();
    }

    [Given(@"I have entered All fields for UserAccountInfo Metedat UI")]
    public void GivenIHaveEnteredAllFieldsForUserAccountInfoMetedatUI()
    {

        CurrentBrowser.TextField(Find.ById("SessionID")).TypeText(RequestData.SessionID);
        CurrentBrowser.TextField(Find.ById("AccountNumber")).TypeText(RequestData.AccountNumber);
        CurrentBrowser.TextField(Find.ById("AccountContextID")).TypeText(RequestData.AccountContextID);
        CurrentBrowser.TextField(Find.ById("UserID")).TypeText(RequestData.UserID);
        CurrentBrowser.TextField(Find.ById("ConsumerID")).TypeText(RequestData.ConsumerID);
        CurrentBrowser.TextField(Find.ById("TransactionID")).TypeText(RequestData.TransactionID.ToString());
        CurrentBrowser.TextField(Find.ById("OutputType")).TypeText(RequestData.OutputType);
    }

    [When(@"I click submit button for UserAccountInfo Metedat UI")]
    public void WhenIClickSubmitButtonForUserAccountInfoMetedatUI()
    {
        CurrentBrowser.InjectAjaxMonitor();
        CurrentBrowser.Button(Find.ById("btnSubmit")).ClickNoWait();
        
    }

    [Then(@"The Request Url woll displayed in Request section of UserAccountInfo Metedat UI")]
    public void ThenTheRequestUrlWollDisplayedInRequestSectionOfUserAccountInfoMetedatUI()
    {
        CurrentBrowser.WaitForComplete();
        CurrentBrowser.WaitForAjaxRequest();
      var divRequest= CurrentBrowser.Div(Find.ById("divRequest"));
      Assert.IsTrue(((WatiN.Core.Element)(divRequest)).OuterText.Contains("AccountNumber="+RequestData.AccountNumber));//
    }

    [Then(@"The AccountInfo will be loaded in Response Section of UserAccountInfo Metedat UI")]
    public void ThenTheAccountInfoWillBeLoadedInResponseSectionOfUserAccountInfoMetedatUI()
    {
        var divResponse = CurrentBrowser.Div(Find.ById("divOutput"));
        Assert.IsTrue(divResponse.OuterText.Contains(RequestData.AccountNumber));

    }

    #endregion

 

WebBrowserHelper.cs
 [Binding]
    public  class WebBrowserHelper
    {
        public static Browser CurrentBrowser
        {
            get
            {
                if (!ScenarioContext.Current.ContainsKey("browser"))
                {
                    ScenarioContext.Current["browser"] = new IE();
                }
                return (Browser)ScenarioContext.Current["browser"];
            }
        }
        
        [AfterScenario]
        public static void Close()
        {
            if (ScenarioContext.Current.ContainsKey("browser"))
            {
                CurrentBrowser.Close();
            }
        }
    }

My Codes:

 BrowserExtension.cs (1.72 KB) WebBrowserHelper.cs (.85 KB) UserAdminStepHelper.cs (.75 KB) 
UserStoryForMetadataUI_LoadUserAccount.step.cs (5.74 KB) UserStoryForMetadataUI_LoadUserAccount.feature (1.25 KB)
 
Categories: Agile | C# | UnitTest

If the symbol is defined, the call is included; otherwise, the call is omitted. Conditional methods provide a cleaner, more elegant alternative to enclosing the method call in #if conditionalSymbol...#endif preprocessor directives.(http://msdn.microsoft.com/en-us/library/4xssyw96%28v=vs.71%29.aspx)
Using the Conditional attribute, you can isolate functions that should be part of your classes only when a particular environment variable is defined or set to a certain value.
The Conditional attribute generates more efficient IL than #if /#endif  does. It also has the advantage of being applicable only at the function level, which forces you to better structure your conditional code. (Effective C#:50 Specific Ways to Improve Your C# by Bill Wagner (Mar 15, 2010))


 
Categories: C# | IoC | MVC | Visual studio 10/up

November 28, 2012
@ 10:59 PM
we are practice BDD by using specflow.

for a web application, when  the user story converted to specflow acceptance test,  it is all for broswer.

Acceptance test for controller is only for developer, not for non-tech business owner/analyst

So I want to use some tool to fill the gap.  After some Google search, I found Coded UI and WatiN could do this job.

Below two articles have a very good example how to do it.

specflow with CodedUI
https://github.com/techtalk/SpecFlow/wiki/Using-SpecFlow-with-CodedUI-API

Specflow with WatiN
blog.willbeattie.net/2011/06/getting-started-with-specflow-watin.html

Ok...which one is better?

 I need to try them and  compare them.

After try both of them,
I think Watin is much better for programmer and much easy to use.
my CodeUI code was broken soon after couple change, and it is very difficult to intigrate with the specflow.

see my other post for my code of specflow and watiN


 
Categories: Agile | C# | UnitTest

October 4, 2012
@ 01:15 AM

Notes of read book "clean code"  by Robert C. Martin

SRP: Single responsibility
DRY: Don't repeat yourself
OCP: open close principle

ex:
1. Switch break the SRP and OCP, should limit it in bottom and factory.
2. Try catch should keep it small ,and no code after try catch block
3. Use exception in stand of ErrorCode
4. Each function should has only one return...try avoid  break, continue, never use goto
5. one parameter is better than two parameters and better than three or more
6. Make sense Name and comments
7. First write the code as you think, then refactor to follow the principle
8. Don't return or pass null, empty list is much better
9. Put Error handle code out side the main logic

Something in the book I don't agree is for Name convention,
he don't like name interface with prefix 'I', and don't like put the type in classname such as AbstractProduct or Iproduct.

But I think that make our life easier when we code...if you need a interface,  With the help of Intelli come with VS or ReSharper ,you type 'I', it will jump out, if you need a Enum...type Enum..all Enum named start with Enum will list for you to choice.


 
Categories: Agile | C# | OODesign

September 26, 2012
@ 03:29 PM
I found this piece of code from stackflow, and I think it was very useful when you want to use a enum to a MVC dropdown.

    public static class EnumUtility
    {
        public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
        {
            var values = from TEnum e in Enum.GetValues(typeof(TEnum))
                         select new { Id = e, Name = e.ToString() };

            return new SelectList(values, "Id", "Name", enumObj);
        }
    }


 
Categories: C# | MVC

Custom Project Template with Wizard, create the new class with the name of custom value.
 
Categories: Asp.net | C# | Visual studio 10/up | VS 2008

  public static class UnityIOC
    {
        public static IUnityContainer Container;
        private static bool _isInited ;
        
        //Make it not dependends the application_start, 
        //this make the Controller can be tested in UnitTest tools
        static UnityIOC()
        {
            Initialise();
        }

        //call by global.asax application start for MVC
        public static void Initialise()
        {
            if (!_isInited)
            {
                _isInited = true;
                Container = BuildUnityContainer();
                DependencyResolver.SetResolver(new UnityDependencyResolver(Container));
                //to use this container in mvc
                // DependencyResolver.Current.GetService(Type)  just resolve in ioc containner
            }
        }

        private static IUnityContainer BuildUnityContainer()
        {
            Container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers
            
            // e.g. container.RegisterType<ITestService, TestService>();            
          //  Container.RegisterType<Widgets.WsunTest.Common.ILoggingService, Widgets.WsunTest.Common.WsunLoggingService>();

            //load web.config ref:http://msdn.microsoft.com/en-us/library/ff660935%28v=pandp.20%29.aspx
             Container.LoadConfiguration();

            Container.RegisterType
                <WsunTest.ViewModel.IWidgetModelFactory<WsunTest.Models.IWsunRequest, WsunTest.Models.WsunResponse>,
                    WsunTest.ViewModel.WsunTestModelFactory>()
                .RegisterType<WsunTest.Models.IWsunRequest, WsunTest.Models.WsunRequest>();
            
            return Container;
        }
    }


the Config in Web.Config
<configuration>
  
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity>">
    <containers>
      <!-- <alias alias="ILoggingService" type="Widgets.WsunTest.Common.ILoggingService" />
     <namespace name="Widgets.WsunTest.Common" />
      <assembly name="Widgets.WsunTest" /> -->
      <container>        
          <register  type="Widgets.WsunTest.Common.ILoggingService,Widgets.WsunTest"
                mapTo="Widgets.WsunTest.Common.WsunLoggingService, Widgets.WsunTest" />   
       
      </container>
    </containers>
  </unity>
Reference:
http://msdn.microsoft.com/en-us/library/ff660935%28v=pandp.20%29.aspx


 
Categories: C# | IoC | MVC

September 18, 2012
@ 07:49 PM
Just Implement a Controller Error Handler call "LogError":
  public class LogError : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            
           ILoggingService logService = DependencyResolver.Current.GetService<ILoggingService>();
          
           logService.Logging(filterContext.Exception.Message,1);

            //redirect to customer error page
            filterContext.Result =
               new RedirectToRouteResult(
                   new RouteValueDictionary{{ "controller", "WsunTest" },
                                                 { "action", "Error" },
                                                 {"message",filterContext.Exception.Message},
                                                 { "returnUrl",    filterContext.HttpContext.Request.RawUrl }
                                                });
            filterContext.ExceptionHandled = true;

        }
    }

And below is the controller, I put the filter on the top of Controller:
 [LogError]
    public class WsunTestController : Controller
    {
       
       public ActionResult Index()
       {
                throw  new Exception("test exception message");

            return View();
          
       }   
      

        public ActionResult Error(string message="unknow")
        {
            ViewBag.message=message;
            return View();
        }

}

There is another way is override the parent controller:
 protected override void OnException(ExceptionContext filterContext)
        {

            // Don't interfere if the exception is already handled
            if (filterContext.ExceptionHandled)
                return;
            //do something to handele the exception
            filterContext.ExceptionHandled = true;
}
Easy to understand..buy I think Filter or actionFilter is more flexible easy to use.


 
Categories: C# | MVC

September 16, 2012
@ 02:47 AM
I have some thoughts for making better code. I call it 3 rulers plus 2 sub rulers.

1 Readable : small function, single responsibility, straightforward name convention.
2. Re-useable: clear and simple responsibility, DRY
3. Testable : can be tested by UnitTest tools. Also I like write code that I can easily put a break point there.

+

4. flexible :  Prepare for future change,  configurable, lower coupling. using IoC.
5. performance: improve code for better performance or user experience, Threading, Cache, Ajax, Parallel LinQ,


4 and 5 have lower priority than 123.   You should know why ;)


 
Categories: C# | OODesign

Our company haven't Team Foundation Server, to do the integration web test, I plan to extend our existed AppMonitor application to run my .webtest file.  the AppMon just simply call powershell script to send request to the webpage, if it can pick up the webtest, it can do more complicate testing.

To approach that final goal, the first thing is get the classes for the .webtest file deserialization.

below are my steps:
1. rename webtest1.webtest to webtest1.xml
2. in VS command line window, run "xsd webtest1.xml", and you will get webtest1.xsd
3. "xsd webtest1.xsd /classes", you class will be generated.

xsd webtest1.xml
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 4.0.30319.1]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\Users\llj\Documents\Visual Studio 2010\Projects\TestProject1\Te
stProject1\webtest1.xsd'.

xsd webtest1.xsd /classes
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 4.0.30319.1]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\Users\llj\Documents\Visual Studio 2010\Projects\TestProject1\Te
stProject1\webtest1.cs'.



 
Categories: C# | UnitTest

1. Defined [DataContract] but forget [DataMember] in DTO .You will got return DTO with all member be null or 0;
if all  proprieties are datamember ,just need [Serializable],
but the fields name may be end with  'k__backingfield' if you generate class from service xml in client. 
to fix this, either add [DataMember] to classes, or use the classes in client side also.


2. DataMember use Enum type which first item value not 0,  and didn't initial  the value. it will cause serialize/deserialize issue.
for example,
public enum SessionLOB //Line Of Business
    {
        UnDefined = 1, Auto = 4, InstantRenter = 5, StandardRenter = 32, HomeOwner = 37
    } ;
and with MyDTO has properties lob
public  SessionLOB lob { get; set; }

if the lob was not initialed and not be set a value, you will get null DTO, because it failed to deserialize 0 to SessionLOB 


 
Categories: C# | WCF

http://weblogs.asp.net/adilakhter/archive/2008/05/04/more-on-unit-testing-testcontext.aspx

What is TestContext?

TestContext is a abstract class of Microsoft.VisualStudio.TestTools.UnitTesting namespace that provides various information about the current test run. Purposes that has been served by TestContext Class -

1.  To store information and provide information to the unit tests during Unit Test Run.

2.  Provide a mechanism to measure performance of your code being tested by the Unit Test.

3.  In Testing the web service it stores the additional information, like server's URL.

4.  In Asp.Net unit tests, it get holds of the Page object.

5.  For Data Driven Unit Tests , it provides access to the data rows.



 
Categories: Agile | C# | UnitTest | VS 2008

To retrieve the version number from the assembly in your code, you use can do this:

String strVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); 

To retrieve the version number from the assembly that is calling your assembly, you can use this:

String strVersion = System.Reflection.Assembly.GetCallingAssembly().GetName().Version.ToString()


 
Categories: C#

April 19, 2010
@ 09:45 AM
Last week someone asked me about "yield" that he saw in my blog. It is very embarrassed me, I totally forget what it is.
I can't keep the "yield" in my mind because it is not something like "what you see is what it is". it even didn't has "return" in the code scope, that make code not easy to read.  that new feature of c#3.0 need me more time to familiar with.


But the new feature "Default Parameter" in c# 4.0 give me some different feeling ,
This is something very nature and  very easy to use.

private void TestFunction(string username,bool isAdmin=false)
{
    //do something..
}

/// since have Default Parameter, this overLoad function is no more need
//private void TestFunction(string username)
//{
//    TestFunction(username,false);
//}
public void Test()
{
     TestFunction("user");
     TestFunction("user1",true)

 
}


This will make you code cleaner and easier to read in many cases.


 
Categories: C#

I don't like to using Struct just for Performance reason. Because it made it easier to has bug in your application.
And it is worse in Team environment.  If an application has a stuct employeeDTO, because this DTO only hold Employee values and qualify to be a value type .
In one place the code got an EmployeeDTO and stored it to a collection(for example, session or ArrayList).

See code like this
ArrayList EmpList=new ArrayList();
EmpList.add(aEmpDto);

....

EmployeeDTO empDto=(EmpleoyeeDTO)EmpList[0];
empDto.email="newemail@test.com"

or
EmployeeDTO empDto=(EmpleoyeeDTO)Session["MyEmpDTO"];
empDto.email="newemail@test.com"

UnBox happen here. Many people will forget that the employeeDTO is value type and treat it as reference type. They change the value and didn't save it back to session.


if in another page, he want to display this updated email address.
Response.write(((EmpleoyeeDTO)session["myEmployeeDto"]).email)
It will still print the old email address.

you may say a good programmer with good programming habit will not cause that bug. But you can't relay on all the members in your team will never make mistake like this.
So I always avoid to create new value type in my code. I may lost some performance, but prevent some potential bugs.


 
Categories: C#

Here is a example of using yield:

public static IEnumerable<int> Unique(IEnumerable<int> nums)
{
Dictionary<int, int> uniqueVals = new
Dictionary<int, int>();
foreach (int num in nums)
{
if (!uniqueVals.ContainsKey(num))
{
uniqueVals.Add(num, num);
yield return num;
}
}
}


Dompare the typical way and the "yield" to get IEnumerable

# IList<string> FindBobs(IEnumerable<string> names)  
# {
# var bobs = new List<string>();
#
# foreach(var currName in names)
# {
# if(currName == "Bob")
# bobs.Add(currName);
# }
#
# return bobs;
# }
# IEnumerable<string> FindBobs(IEnumerable<string> names)  
# {
# foreach(var currName in names)
# {
# if(currName == "Bob")
# yield return currName;
# }
# }



 
Categories: C# | LINQ and C# 3.0

When I try to export a complex page which has RadGrid Control to PDF file, it always returns an error message like
Script control '' is not a registered script control. 
Script controls must be registered using RegisterScriptControl() before calling RegisterScriptDescriptors().
Parameter name: scriptControl

After trying many different ways, I finally found the right solution to exporting the page without exception: Override the "Render" method in the page or the UserControl.
The code is below:

protected override void Render(HtmlTextWriter writer)
    {

        if (_isExport)
        {
            StringWriter stringWriter = new StringWriter(); //System.IO namespace should be used

            HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
            base.Render(htmlTextWriter);

            Response.Clear(); //this clears the Response of any headers or previous output
            Response.Buffer = true; //make sure that the entire output is rendered simultaneously

            ///
            ///Set content type to MS Excel sheet
            ///Use "application/msword" for MS Word doc files
            ///"application/pdf" for PDF files
            ///"application/vnd.ms-excel";
            Response.AddHeader("content-disposition", "attachment;filename=ShippingSheet.doc");

            Response.Charset = "";
            Response.ContentType = "application/msword";

            ///
            ///Render the entire Page control in the HtmlTextWriter object
            ///We can render individual controls also, like a DataGrid to be
            ///exported in custom format (excel, word etc)
            ///
            // PrintableShippingSheet1.RenderControl(htmlTextWriter);
            Response.Write(stringWriter.ToString());
            Response.End();

        }
        else
            base.Render(writer);
    }


 
Categories: Asp.net | C# | Telerik Controls


I found those piece of code in my old project. I forget where to get it. Just post here in case I lost it.


using
System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Security.Cryptography; using System.Text; /// <summary> /// Summary description for Cryptography /// </summary> public static class Cryptography { /// <summary> /// Encrypt a string using dual encryption method. Return a encrypted cipher Text /// </summary> /// <param name="toEncrypt">string to be encrypted</param> /// <param name="useHashing">use hashing? send to for extra secirity</param> /// <returns></returns> public static string Encrypt(string toEncrypt, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); // Get the key from config file string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); //System.Windows.Forms.MessageBox.Show(key); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } /// <summary> /// DeCrypt a string using dual encryption method. Return a DeCrypted clear string /// </summary> /// <param name="cipherString">encrypted string</param> /// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param> /// <returns></returns> public static string Decrypt(string cipherString, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(cipherString); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); //Get your key from config file to open the lock! string key; try { key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); }catch { key = "broadview networks"; } if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray); } }


 
Categories: C#

Sometime I need resort the ArrayList or List<T> in my code. I am too lazy to write a piece of code to implement IComparer. When I search through google, I found there is a very elegant way to do the sorting:
[code]
peopleList.Sort(
delegate(Person p1, Person p2)
{
return p1.name.CompareTo(p2.name);
}
);

peopleList.ForEach(delegate(Person p) { Console.WriteLine(String.Format("{0} {1}", p.age, p.name)); });

[/code]
I have used code like this many times, but actually I didn't really understand why code can be wrote like this.
Those are some different way to sorting in different version of .net frameworks,
and those articles helping me to understand the sorting code better.

Thanks to happy九拍
如果不用匿名方法,我们1.1里就的这么写

代码:
static int Compare(Person p1, Person p2)
{
return p1.name.CompareTo(p2.name);
}
然后
代码:
people.Sort(new Comparison<Preson>(Compare));
你的问题解决了,在C#3.0里,我们不再需要匿名方法了,直接lambda咯
代码:
people.Sort((p1, p2) => p1.name.CompareTo(p2.name));

Thanks to Shadal:
2.0可以这样写
static int Compare(Person p1, Person p2)
{
return p1.name.CompareTo(p2.name);
}

people.Sort(Compare);





An userful article:

Variable Scoping in Anonymous Delegates in C#


public void AddScript(ScriptItem script)
{
    ScriptItem match = null;
 
    // *** Grab just the path
    if (!string.IsNullOrEmpty(script.Src))
    {
        script.FileId = Path.GetFileName(script.Src).ToLower();
 
        match = this.InternalScripts.Find(
            delegate(ScriptItem item)
            {
               ScriptRenderModes mode = this.RenderMode;  // demonstrate this pointer
               return (item.FileId == script.FileId);
            });
    }
 
    if (match == null)                
        this.InternalScripts.Add(script);
    else
        match = script;
} 


 
Categories: C# | LINQ and C# 3.0

step 1, Preparing Object Datasource:

UserDs.cs

public class UserDS
{
public ArrayList GetUsers(object login_user)
{
if user is admin return all users, otherwise return login_user in Arralist
return DBControl.GetDashboardUsers((User)login_user);
}
public void SaveUser(string username, string password, string group)
{
DBControl.UpdateUser(username, password, group);
}
public void InsertUser(string username, string password, string group)
{
//if username exsit, then throw excepton..
DBControl.InsertUser(username, password, group);
}

public void Deleteuser(string username)
{
DBControl.DeleteUser(username);
}
}

step 2, Create Object Datasource In Asp page:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="Deleteuser"
SelectMethod="GetUsers" TypeName="UserDS" UpdateMethod="SaveUser">
<DeleteParameters>
<asp:Parameter Name="UserName" Type="String" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="UserName" Type="String" />
<asp:Parameter Name="Password" Type="String" />
<asp:Parameter Name="Group" Type="String" />
</UpdateParameters>
<SelectParameters>
<asp:SessionParameter Name="login_user" SessionField="Login_User" Type="Object" />
</SelectParameters>

</asp:ObjectDataSource>

step 3, GridView:

<asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#E7E7FF"
BorderStyle="None" BorderWidth="1px" CellPadding="3" DataSourceID="ObjectDataSource1"
GridLines="Horizontal" AutoGenerateColumns=False DataKeyNames="UserName">
<FooterStyle BackColor="#B5C7DE" ForeColor="#4A3C8C" />
<Columns>
<asp:BoundField DataField="UserName" HeaderText="UserName" ReadOnly=true />
<asp:BoundField DataField="Password" AccessibleHeaderText="Password" HeaderText="Password" />
<asp:BoundField DataField="Group" HeaderText="Group" />
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
</Columns>
<RowStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" />
<SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="#F7F7F7" />
<PagerStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" HorizontalAlign="Right" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
<AlternatingRowStyle BackColor="#F7F7F7" />
</asp:GridView>


 
Categories: Asp.net | C#