2017-03-09 110 views
0

確定它在哪裏,發佈我的第一個SO問題後數小時的谷歌搜索。要溫柔請:)運行時訪問web.config system.webServer/webSocket部分

問:任何想法如何讓過去的錯誤:「[System.Configuration.ConfigurationProperty]」不可訪問由於其保護級別」,試圖修改的web.config system.webServer時/ webSocket部分在C#中?

背景&我已經試過: 我用C#編寫ASP.NET Web應用程序,它利用微軟SignalR服務器< - >客戶端函數調用。 SignalR儘可能使用Websocket協議,並在不可用時回退到其他傳輸方法。

我在我的web.config此項,system.webServer部分中:

<webSocket enabled="true" pingInterval="00:00:10" /> 

這使我的應用程序使用的WebSocket所以我需要這條線。另外,因爲我的用戶經常在困難的網絡環境中工作,所以我添加了一個相當短的pingInterval。這很好,沒問題。

衆所周知,Windows 2008 R2/IIS 7.5(及更低版本)不支持WebSocket。但是有時我需要在較舊的Windows Server版本上運行我的應用程序。在這種情況下,我需要手動刪除上面顯示的行,以避免關於錯誤的Web.config配置的令人討厭的IIS錯誤。這也工作得很好,但我不喜歡根據我運行的服務器來刪除這一行的額外工作。

因此,我在我的Global.asax中添加了代碼來檢測OS和IIS版本,以瞭解WebSocket是否受支持。 Next 我想在運行時動態添加或刪除WebSocket配置行(我確定我的appdomain在更改時重新啓動)。 我需要在我的應用程序中完全以編程方式完成此操作,並且無需在IIS或操作系統級別上更改任何內容。

我已經看了諸如this onethis from MS文章,也有不少,這樣非常接近我的問題,像this herethis regarding the actual error I get職位。這是最接近我可以在瞬間得到,我不知道如何讓過去的錯誤:

System.Configuration.Configuration webConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/MICC"); 
//At this point I can see that webConfig.FilePath is pointing to correct Web.config file 
System.Configuration.ConfigurationElement webSocketElement = webConfig.GetSection("system.webServer/webSocket"); 
if (webSocketElement == null) 
{ 
    //Not sure how to initialize a new ConfigurationElement, if GetSection() returned null 
} 
else 
{ 
    //Attempting to change values, but following two lines gives me: 
    //[System.Configuration.ConfigurationProperty]' is inaccessible due to its protection level 

    webSocketElement["enabled"] = true; 
    webSocketElement["pingInterval"] = TimeSpan.Parse("00:00:99"); //Test value 
} 
webConfig.Save(); //Never getting this far... 

,我還就如何解決這個任何其他建議非常開放。 同時我會繼續使用Google ...

編輯:忘記提到我在.NET 4.5

+0

嗯,我終於設法解決這個問題。我已經用「解決方案」部分更新了原文。 – tnurmi

+0

你應該發佈解決方案作爲答案:) –

+1

謝謝!我編輯了我原來的帖子,從中刪除了「已解決」的部分,並將其添加爲答案,並將其標記爲已接受的答案。看來我幾乎只是在這裏聊天自己...... :) – tnurmi

回答

2

解決了! 經過幾個小時的嘗試,我完全按照我的需要進行工作。這裏是相關的一段代碼,不是最漂亮的代碼,但它的工作原理:

public static bool enableWebSocket() 
{ 
    System.Configuration.Configuration webConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/my-apps-name-under-my-iis-site"); 
    System.Configuration.ConfigurationSection webServerSection = webConfig.GetSection("system.webServer"); 

    //This was the "magic" discovery. Just get the whole bunch as raw XML for manual editing:     
    XmlDocument webServerXml = new XmlDocument(); 
    webServerXml.LoadXml(webServerSection.SectionInformation.GetRawXml()); 
    //Check if the line is already there: 
    XmlNodeList nodes = webServerXml.GetElementsByTagName("webSocket"); 
    if (nodes.Count > 0) 
    { 
     return false; //Already there, do nothing... 
    } 
    else //Node not yet found, so let's add it: 
    { 
     //Create a new XmlNode with the needed attributes: 
     XmlNode webSocket = webServerXml.CreateNode(XmlNodeType.Element, "webSocket", null); 
     XmlAttribute attr = webServerXml.CreateAttribute("enabled"); 
     attr.Value = "true"; 
     webSocket.Attributes.Append(attr); 
     attr = webServerXml.CreateAttribute("pingInterval"); 
     attr.Value = "00:00:10"; 
     webSocket.Attributes.Append(attr); 

     //Append original <system.webServer> section with the new XmlNode: 
     webServerXml.DocumentElement.AppendChild(webSocket); 

     //And finally store the modified <system.webServer> section in Web.config:  
     webServerSection.SectionInformation.SetRawXml(webServerXml.OuterXml); 
     webConfig.Save(); 
     return true; //All done! 
    } 
}