我在使用 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 & 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 上时,我会看到通常的智能感知弹出窗口,而将鼠标悬停在 Title 上会解释正常的“在运行时评估”。
有没有人遇到过这个问题?我查看了其他问题,但它们都有代码拼写错误或真正的错误。我知道这不是程序集参考问题,否则 Intellisense 不会知道 Viewbag 是什么。
更新
看起来 Intellisense 遇到了特别是动态分配的问题。正常的服务器代码不会遇到上述问题,而像 Viewbag 分配或在 @{//code here} 中指定布局之类的东西似乎已损坏。另请注意,这只发生在我的 .cshtml 文件之一上,其他文件不受影响。
更新 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");