2016-07-12 3 views
0

내 페이지에서 이벤트를 트리거하고 txt 파일에 기록하는이 단추가 있습니다.C# ASP.NET ViewState의 도움으로 파일로 로깅

void ButtonClick(object sender, EventArgs e) 
    { 
     // Stop/start service 
     var button = (Button)sender; 
     string machine = button.CommandArgument; 
     string service; 

     /*Do stuff */ 

     if (buttonClicked) 
     { 
      writeToLogFile("User " + HttpContext.Current.User.Identity.Name + " pressed the " + button.CommandName + " button on server " + machine + " with the services " + checkedBoxes(machine) + " checked."); 
      ViewState["buttonClicked"] = buttonClicked; 
     } 
    } 

단추가 내 페이지의 상태를 변경합니다. 이 상태는 다른 소스에서도 변경 될 수 있으므로 로그인 할 수도 있습니다.

protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      prevStatus = new Dictionary<string, ServiceControllerStatus>(); 
      currStatus = new Dictionary<string, ServiceControllerStatus>(); 
      buttonClicked = false; 
      ViewState["buttonClicked"] = false; 
     } 
     else 
     { 
      prevStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["prevStatus"]; 
      currStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["currStatus"]; 
      buttonClicked = (bool)ViewState["buttonClicked"]; 
      if (!buttonClicked) 
      { 
       foreach (var item in currStatus) 
       { 
        ServiceControllerStatus oldStatus; 
        if (prevStatus.TryGetValue(item.Key, out oldStatus) && !(oldStatus == item.Value)) 
        { 
         string[] split = item.Key.Split('_'); 
         writeToLogFile("The service " + split[0] + " on server " + split[1] + " was changed to " + item.Value + " from another source."); 
        } 
       } 
      } 
      else 
      { 
       ViewState["buttonClicked"] = false; 
      } 

그러나이 로그는 내가 원하지 않는 버튼을 클릭 할 때도 기록됩니다. 따라서 포스트 백간에 상태 변수 buttonClicked을 유지해야합니다.

여기서 문제는 내가 ViewState 변수를 재설정 한 마지막 사례입니다. 다른 모든 것은 잘 작동합니다. 그러나이 재설정이 없으면 버튼을 클릭 한 후 buttonClicked이 true로 유지되기 때문에 다른 로거가 로깅을 중지합니다. 그러나 재설정을 구현 한 경우 ViewState는 Page_Load가 시작될 때 false로 설정되므로 버튼과 다른 로거에 대해 각각 두 번씩 기록되므로 모든 의미가 손실됩니다. 나는 왜이 else case가 if 문 앞에 일어나는 것일까를 알아 내려고 노력하고있다.

Page_Load를 누르 자마자 버튼 클릭 이벤트에서 디버깅하고 단계를 밟으면 ViewState가 false로 설정됩니다. else case 내에서 줄을 주석 처리하면 디버깅을 단계별로 수행하는 동안 false로 설정되지 않습니다. 무슨 일 이니?

+0

그냥 명확히 .. 당신은'Page_Load' 자체 로깅이 있다면? 당신은 사용할 수있는 viewstates가 있습니다 ... –

+0

@SujeetSinha 나는 당신이 의미하는 것을 실제로 따르지 않고 있습니다. 'Page_Load'에서'writeToLogFile'을 호출하고 클릭을 위해 버튼 이벤트에서 호출합니다. 내가'Page_Load'에서 로그 만하면된다는 의미인가요? – Skillzore

+0

버튼을 클릭하면 Page_Load가 먼저 발생하고 그 후에 만 ​​버튼 이벤트가 발생합니다. 따라서 단추 이벤트에서 설정하는 ViewState가 너무 늦습니다. 이것은 작동하지 않습니다. 어쩌면 로깅을 포스트 백에서 수행하지 않고 필요할 때 호출하는 일부 로그 메소드에 대한 별도의 호출로 로직을 변경하십시오. – Esko

답변

0

단추를 클릭하거나 다른 포스트 백이 발생하면 실제 이벤트가 단추와 바인딩되기 전에 Page_Load 이벤트가 실행됩니다. here에서 페이지 수명주기에 대해 자세히 알아보십시오.

그래서 문제는 설정하려는 ViewState 값이 너무 늦게 발생하여 Page_Load에서 평가할 수 없다는 것입니다.

하나의 해결 방법은 단순히 로깅 로직을 별도의 메서드에 넣고 필요할 때 호출하는 것입니다.

예 :

public partial class _Default : Page 
    {  

     protected void Page_Load(object sender, EventArgs e) 
     { 
     } 

     private void Log() 
     {    
      if (ViewState["prevStatus"] != null && ViewState["currStatus"] != null) 
      { 
       prevStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["prevStatus"]; 
       currStatus = (Dictionary<string, ServiceControllerStatus>)ViewState["currStatus"];     

       foreach (var item in currStatus) 
       { 
        ServiceControllerStatus oldStatus; 
        if (prevStatus.TryGetValue(item.Key, out oldStatus) && !(oldStatus == item.Value)) 
        { 
         string[] split = item.Key.Split('_'); 
         writeToLogFile("The service " + split[0] + " on server " + split[1] + " was changed to " + item.Value + " from another source."); 
        } 
       }     
      }   
     } 

     protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      // Do stuff 

      this.Log(); 
     } 

     protected void Button1_Click(object sender, EventArgs e) 
     { 
      // Stop/start service 
      var button = (Button)sender; 
      string machine = button.CommandArgument; 
      string service; 

      /*Do stuff */ 
      writeToLogFile("User " + HttpContext.Current.User.Identity.Name + " pressed the " + button.CommandName + " button on server " + machine + " with the services " + checkedBoxes(machine) + " checked."); 
     } 

    } 
+0

정말 고마워! – Skillzore