2013-05-07 46 views
2

我遇到了Razor2視圖的一個非常奇怪的問題。下面的代碼是實際代碼,其中智能感知正在拋棄紅色曲線,只是名稱已更改。剃刀看不到我的右大括號

@model Space.ViewModels.PropertyAdminViewModel 

@{ 
    ViewBag.Title = "Create"; 
    ViewBag.UmbracoTitle = "Create Property"; 
    Layout = "../Shared/_Layout.cshtml"; 

    InitView(); 
    AnalysePreviousState(); 
    SortErrorsPerStep(); 
    GetStepToDisplay(); 
} 

<script src="../../Scripts/jquery-1.8.2.min.js"></script> 
<script src="../../Scripts/jquery.validate.min.js"></script> 
<script src="../../Scripts/jquery.validate.unobtrusive.min.js"></script> 
<script src="../../Scripts/AdminScripts.js"></script> 

@Html.ValidationSummary(ErrorMessage) 

@using (Html.BeginForm()) 
{ 
    @Html.Hidden("CurrentStep", StepToDisplay.ToString(), new { id="CurrentStep"}) 
    <input id="AddressButton" type="submit" name="@Button.AddressButton.ToString()" value="Address Details" /> 
    <input id="DetailsButton" type="submit" name="@Button.DetailsButton.ToString()" value="Details &amp; Description" /> 
    <input id="MediaButton" type="submit" name="@Button.MediaButton.ToString()" value="Images &amp; Documents" /> 


    switch (StepToDisplay) 
    { 
     case Step.Address: 
      Html.RenderPartial("_AddressDetailsForm", ViewData.Model.Address); 
      break; 
     case Step.Details: 
      Html.RenderPartial("_PropertyDetailsForm", ViewData.Model); 
      break; 
     case Step.Media: 
      Html.RenderPartial("_MediaUploadEditForm", ViewData.Model.MediaItems); 
      break; 
    } 


    <input id="BackButton" type="submit" name="@Button.BackButton.ToString()" value="Back" /> 
    <input id="NextButton" type="submit" name="@Button.NextButton.ToString()" value="Next" /> 
    <input id="FinishButton" type="submit" name="@Button.FinishButton.ToString()" value="Finish" /> 

} <-- `SQUIGGLY` 


@{ 
    private enum Button 
    { 
     None, 
     AddressButton, 
     DetailsButton, 
     MediaButton, 
     NextButton, 
     BackButton, 
     FinishButton, 
     CancelButton 
    } 

    public enum Step 
    { 
     Address, 
     Details, 
     Media, 
     UpperBound 
    } 

    private const Step AddressStep = Step.Address; 
    private const Step DetailsStep = Step.Details; 
    private const Step MediaStep = Step.Media; 
    private const Step First_Step = AddressStep; 
    private const Step Last_Step = MediaStep; 
    private const string CurrentStep = "CurrentStep"; 
    private const string DisabledAttribute = "disabled='disabled'"; 

    private string BackButtonState = string.Empty; 
    private string NextButtonState = string.Empty; 
    private string ErrorMessage = "Please correct the errors and try again."; 
    private Button ButtonPressed = Button.None; 
    private Step PreviousStepDisplayed = AddressStep; 
    private Step StepToDisplay = AddressStep; 
    private ModelStateDictionary[] StepModelState = new ModelStateDictionary[(int)Step.UpperBound]; 

    private void InitView() 
    { 
     // Create a ModelState for each individual step 
     for (int key = (int)First_Step; key <= (int)Last_Step; key++) 
     { 
      StepModelState[key] = new ModelStateDictionary(); 
     } 
    } 

    /// <summary> 
    /// Check form variables from the last HTTP_POST to figure where the wizard needs to be 
    /// Grab the current step string along with which button was pressed 
    /// </summary> 
    private void AnalysePreviousState() 
    { 
     if (!string.IsNullOrEmpty(Request[CurrentStep])) 
     { 
      PreviousStepDisplayed = (Step)Enum.Parse(typeof(Step), Request[CurrentStep], true); 
     } 

     if (!string.IsNullOrEmpty(Request[Button.FinishButton.ToString()])) 
     { 
      ButtonPressed = Button.FinishButton; 
     } 

     if (!string.IsNullOrEmpty(Request[Button.CancelButton.ToString()])) 
     { 
      ButtonPressed = Button.CancelButton; 
     } 

     if (!string.IsNullOrEmpty(Request[Button.NextButton.ToString()])) 
     { 
      ButtonPressed = Button.NextButton; 
     } 

     if (!string.IsNullOrEmpty(Request[Button.BackButton.ToString()])) 
     { 
      ButtonPressed = Button.BackButton; 
     } 

     if (!string.IsNullOrEmpty(Request[Button.AddressButton.ToString()])) 
     { 
      ButtonPressed = Button.AddressButton; 
     } 

     if (!string.IsNullOrEmpty(Request[Button.DetailsButton.ToString()])) 
     { 
      ButtonPressed = Button.DetailsButton; 
     } 

     if (!string.IsNullOrEmpty(Request[Button.MediaButton.ToString()])) 
     { 
      ButtonPressed = Button.MediaButton; 
     } 
    } 

    /// <summary> 
    /// Sort all modelstate errors into the right step 
    /// </summary> 
    private void SortErrorsPerStep() 
    { 
     foreach (KeyValuePair<string, ModelState> entry in ViewData.ModelState) 
     { 
      foreach (int key in Enum.GetValues(typeof(Step))) 
      { 
       //Compare the start of each error's key with the name of a step 
       //if they match then that error belongs to that step 
       if (entry.Key.StartsWith(((Step)key).ToString())) 
       { 
        StepModelState[key].Add(entry); 
        break; 
       } 
      } 
     } 

     ViewData.ModelState.Clear(); 
    } 

    /// <summary> 
    /// Look at the previous step to get any errors and which button was clicked 
    /// and decide which step needs to be displayed now 
    /// </summary> 
    private void GetStepToDisplay() 
    { 
     //if the user tried to jump steps or finish, display the first step that has errors 
     //this ensures that the wizard is completed in the intended sequence 
     if (ButtonPressed != Button.NextButton && ButtonPressed != Button.BackButton) 
     { 
      ErrorMessage = "There are errors in the data provided. Please correct the errors and try again."; 

      for (Step key = First_Step; key <= Last_Step; key++) 
      { 
       if (!StepModelState[(int)key].IsValid) 
       { 
        DisplayStep(key, true); 
        return; 
       } 
      } 
     } 

     //if the last step has errors and the user has not hit the back button then stay on page and show the errors 
     //user can go back through steps but not forward until errors are resolved 
     if (!StepModelState[(int)PreviousStepDisplayed].IsValid && ButtonPressed != Button.BackButton) 
     { 
      DisplayStep(PreviousStepDisplayed, true); 
      return; 
     } 

     //Otherwise move as per user request 
     Step stepToDisplay = PreviousStepDisplayed; 

     switch (ButtonPressed) 
     { 
      case Button.BackButton: 
       stepToDisplay--; 
       break; 
      case Button.NextButton: 
       stepToDisplay++; 
       break; 
      case Button.AddressButton: 
       stepToDisplay = AddressStep; 
       break; 
      case Button.DetailsButton: 
       stepToDisplay = DetailsStep; 
       break; 
      case Button.MediaButton: 
       stepToDisplay = MediaStep; 
       break; 
     } 

     stepToDisplay = (Step)Math.Max((int)stepToDisplay, (int)First_Step); 
     stepToDisplay = (Step)Math.Min((int)stepToDisplay, (int)Last_Step); 

     DisplayStep(stepToDisplay, false); 
    } 

    private void DisplayStep(Step stepToDisplay, bool displayErrors) 
    { 
     StepToDisplay = stepToDisplay; 
     BackButtonState = stepToDisplay == First_Step ? DisabledAttribute : string.Empty; 
     NextButtonState = stepToDisplay >= Last_Step ? DisabledAttribute : string.Empty; 

     //page number 

     if (displayErrors) 
     { 
      foreach (KeyValuePair<string, ModelState> entry in StepModelState[(int)stepToDisplay]) 
      { 
       ViewData.ModelState.Add(entry.Key, entry.Value); 
      } 
     } 
    } 


} 

當我將鼠標懸停在Viewbag我得到的通常的智能感知彈出,並徘徊標題解釋了正常「在運行時進行評估」。

有沒有人遇到過這個問題?我查看了其他問題,但他們都有代碼拼寫錯誤或真正的錯誤。我知道這不是一個組裝參考問題,否則Intellisense不會知道Viewbag是什麼。

UPDATE

它看起來像智能感知是否有問題特別動態分配。普通服務器代碼不會遇到上述問題,而像Viewbag分配或指定@ {//此處代碼}中的佈局似乎已破壞。另請注意,這隻發生在我的一個.cshtml文件中,而其他文件不受影響。

UPDATE 2 這是測試視圖的結果。源文件是ASP.NET臨時文件中生成的代碼文件。

Compiler Error Message: CS1513: } expected 

Source Error: 

Line 259:   #line default 
Line 260:   #line hidden 
Line 261:WriteLiteral("\r\n"); 
Line 262: 

這是與上述錯誤在編譯的臨時文件中的代碼:

WriteLiteral(" value=\"Finish\""); 

WriteLiteral(" /> \r\n"); 


    #line 46 "F:....Create.cshtml" 

} <-- see the brace!? It's right there so why does the compiler freak out? 

    #line default 
    #line hidden 
WriteLiteral("\r\n");    
+1

代碼是否執行? – 2013-05-07 17:18:17

+2

您是否保存,關閉並重新打開文件?有時intellisense失去了它的名字的聰明部分。 – Tommy 2013-05-07 17:21:10

+0

嘗試僅刪除一次花括號,然後說@ ViewBag.Title =「Page」;看看它是否還能給出那種紅色的波浪曲線? – Nirman 2013-05-07 19:02:42

回答

0

我不知道,你可以不寫正常的C#代碼到剃刀意見。

+1

不確定你的意思。你不能聲明方法或類,因爲視圖基本上是一種方法。這就像試圖在另一種方法中聲明一種方法或類,這是不合法的。所以,這是「正常」的C#代碼,但你必須考慮它的運行環境。如果您需要方法,您必須更改視圖繼承的類,然後將其作爲單獨的文件執行。 – 2013-05-09 18:17:12

+0

在發表這篇文章之前,我對剃刀視圖語法的理解是,我可以編寫任何服務器代碼,只要它在{@}塊中聲明。並非如此。 – AutoGibbon 2013-05-09 18:55:11

0

你需要這樣的:

@switch (StepToDisplay) 

它看到閘刀開關括號截至收盤到你之前的那個。您甚至可能需要將開關放在一個剃鬚刀代碼塊中@{ switch(){} }

另外,如果您使用的是ReSharper,它會突出顯示它的實際代碼塊,並且您會看到Razor在想什麼該塊的結束將是。

編輯:

它應該是這樣的:

@using (Html.BeginForm()) 
{ 
    // remove the @ from before the Html on this line 
    Html.Hidden("CurrentStep", StepToDisplay.ToString(), new { id="CurrentStep"}) 
    // This html causes razor to switch back to "html mode" 
    <input id="AddressButton" type="submit" name="@Button.Step1Button.ToString()"... 

    ... 

    // Add an @ here, because razor is now in Html mode 
    @switch (StepToDisplay) 
    { 
     ... 
    } 

    // Back in html mode again, so we need @'s 
    <input id="BackButton" type="submit" name="@Button.BackButton.ToString()"... 
    ... 
} 
+0

在'switch'語句之前添加'@'會得到以下結果:'@「字符後出現'Unexpected'開關'關鍵字。一旦進入內部代碼,你就不需要在「@」前面加上「switch」這樣的結構。' – AutoGibbon 2013-05-09 15:18:37

+0

@AutoGibbon - 問題在於它由於之前的html而切換回HTML模式。在第一個大括號後面的第一行不應該有'@ Html'。 – 2013-05-09 15:22:33

+0

做你的建議仍然會導致'意外的「開關」...「編譯錯誤。它清楚地表明這不是必需的。在附註中 - 將生成的代碼從臨時asp.net文件放入VS2012編輯器中,可以看出生成的代碼具有OP所示的錯誤。 – AutoGibbon 2013-05-09 16:09:20