3

Razor2 ビューで非常に奇妙な問題が発生しています。以下のコードは、intellisense が赤い波線を投げている実際のコードで、名前だけが変更されています。

@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 ポップアップが表示され、タイトルにカーソルを合わせると、通常の「実行時に評価される」という説明が表示されます。

誰かがこの問題に遭遇しましたか? 私は他の質問に目を通しましたが、それらにはすべてコードのタイプミスまたは本物の間違いがありました。アセンブリ参照の問題ではないことはわかっています。それ以外の場合、Intellisense は Viewbag が何であるかを認識できません。

アップデート

Intellisense で特に動的割り当てに問題があるようです。通常のサーバー コードでは上記の問題は発生しませんが、Viewbag の割り当てや @{//code here} 内でのレイアウトの指定などは壊れているように見えます。また、これは .cshtml ファイルの 1 つでのみ発生し、他のファイルは影響を受けないことに注意してください。

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");            
4

2 に答える 2

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()"...
    ...
}
于 2013-05-09T15:12:16.010 に答える
-1

通常の C# コードを Razor ビューに記述できないとは思いもしませんでした。

于 2013-05-09T17:27:00.293 に答える