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 & Description" />
<input id="MediaButton" type="submit" name="@Button.MediaButton.ToString()" value="Images & 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");