I am experiencing a very strange issue with Razor2 views. The code below is the actual code on which intellisense is throwing down the red squiggly, just names have been changed.
@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);
}
}
}
}
When I hover over Viewbag I get the usual intellisense popup, and hovering on Title explains the normal 'evaluated at runtime'.
Has anyone run into this issue? I have looked over other questions but they all had code typos or genuine mistakes. I know it's not an assembly reference issue otherwise Intellisense wouldn't know what the Viewbag is.
UPDATE
It looks like Intellisense is having a problem specifically dynamic assignments. Normal server code does not experience the above issue, whereas anything like Viewbag assignments or specifying the layout within @{//code here} seems broken. Also note that this only occurs on one of my .cshtml files and the others are unaffected.
UPDATE 2 This is the result of testing the view. Source file is the generated code file in ASP.NET temp files.
Compiler Error Message: CS1513: } expected
Source Error:
Line 259: #line default
Line 260: #line hidden
Line 261:WriteLiteral("\r\n");
Line 262:
And this is the code relating to the above error in the compiled temp file:
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");
I had no idea that you can't write normal c# code into Razor views.