Situation

需要判斷使用者的IP 為內網或外網。

Action

使用者 IP 可以透過 Request.UserHostAddress 取得
“判斷內外網邏輯” 首先從重用性考慮,該邏輯之後可以在其他專案或模組重複使用,看起來應該提取到新類別中,如下

public class NetworkManager
{
    public enum NetType
    {
        INTERNET, INTRANET
    }
    public static NetType CheckIntranetOrInternet(string targetIP)
    {
        string[] targetIPSections = targetIP.Split('.');
        /// IP地址中,有三段地址專門用於私網的規劃,不能被用於網際網路上的連線如下
        /// Class A:10.0.0.0-10.255.255.255
        if (targetIPSections[0] == "10") {
            return NetType.INTRANET;
        }
        /// Class B:172.16.0.0-172.31.255.255
        if (targetIPSections[0] == "172")
        {
            int targetIPSecondSection = Convert.ToInt16(targetIPSections[1]);
            if (targetIPSecondSection >= 16 && targetIPSecondSection <= 31)
            {
                return NetType.INTRANET;
            }
        }
        /// Class C:192.168.0.0-192.168.255.255
        if (targetIPSections[0] == "192" && targetIPSections[1] == "168")
        {
            return NetType.INTRANET;
        }
        return NetType.INTERNET;
    }
}

CheckIntranetOrInternet 方法的參數型態其實有兩個選項為 Request 或 string,因為我習慣寫單元測試來覆蓋邏輯,string 會是比較好的選擇。
另一個為列舉,因為CheckIntranetOrInternet 方法的回傳值為內網或外網。
很多人會使用常數但我通常使用列舉來取代常數,特別是列舉可以清楚的規範且說明本身的意義

Result

這邊使用單元測試來測試邏輯,注意這邊並沒有覆蓋到所有邏輯。

[TestMethod]
public void CheckIntranetOrInternet_CheckInternet()
{
    Assert.AreEqual(NetworkManager.NetType.INTERNET, NetworkManager.CheckIntranetOrInternet("9.0.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTERNET, NetworkManager.CheckIntranetOrInternet("11.0.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTERNET, NetworkManager.CheckIntranetOrInternet("172.15.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTERNET, NetworkManager.CheckIntranetOrInternet("172.32.255.255"));
    Assert.AreEqual(NetworkManager.NetType.INTERNET, NetworkManager.CheckIntranetOrInternet("192.167.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTERNET, NetworkManager.CheckIntranetOrInternet("192.169.255.255"));
}
[TestMethod]
public void CheckIntranetOrInternet_CheckIntranet()
{
    Assert.AreEqual(NetworkManager.NetType.INTRANET, NetworkManager.CheckIntranetOrInternet("10.0.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTRANET, NetworkManager.CheckIntranetOrInternet("10.255.255.255"));
    Assert.AreEqual(NetworkManager.NetType.INTRANET, NetworkManager.CheckIntranetOrInternet("172.16.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTRANET, NetworkManager.CheckIntranetOrInternet("172.31.255.255"));
    Assert.AreEqual(NetworkManager.NetType.INTRANET, NetworkManager.CheckIntranetOrInternet("192.168.0.0"));
    Assert.AreEqual(NetworkManager.NetType.INTRANET, NetworkManager.CheckIntranetOrInternet("192.168.255.255"));
}