Issue migrating MVC3 Application to MVC4: Compiler Error Message: CS1513: } expected - razor

This is a really weird error, I think it may be a razor bug. I'm using VS 2012, MVC4, Framework 4.5.
Following these instructions: http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253806
I created a new MVC4 project and then I copied all my code (controllers, views, viewmodels) to it from the MVC3 project.
Eveything worked just fine, until I tested one View which has a custom helper and inside it it has one foreach, one switch, three if statements and then I call some other custom helpers in there too.
It's exactly the same code in both projects, in MVC3 it works, but in MVC4 it shows this message:
Compiler Error Message: CS1513: } expected
So I tried adding one curly bracket but it shows the same error, so I keep adding brackets and it won't stop telling me the same thing.
I googled this issue but I just found this question with no answer:
http://www.1771.in/asp-net-mvc-4-issues-migrating-mvc3-view-in-vs-2012-rc.html
has anyone experienced this issue?

The Razor parser of MVC4 is different from MVC3.
Razor v3 is having advanced parser features and on the other hand strict parsing compare to MVC3.
You may run into syntax error in view while converting MVC3 to MVC4 if you have not used razor syntaxes in correct manner.
Solution of some common razor code mistakes that are not allowed in Razor v2 are :
--> Avoid using server blocks in views unless there is variable declaration section.
Don’t : #{if(check){body}}
Recommended : #if(check){body}
--> Avoid using # when you are already in server scope.
Don’t : #if(#variable)
Recommended : #if(variable)
Don't : #{int a = #Model.Property }
Recommended : #{int a = Model.Property }

I had exactly the same issue.
In Razor MVC3 i was accessing the vars like this: #vSuggestion but in MVC4 the # is not necessary.
My example, i had this code in MVC3 working:
#{
var vSuggestion = ((dynamic)ViewData["suggestion"]);
}
<!-- more code here -->
#{ int suggestion = #vSuggestion;
switch (suggestion)
{
case Suggestion.INCORRECT_PASSWORD:
case Suggestion.USER_ALREADY_IN_DATABASE:
<span>Trata de iniciar sesión de nuevo</span><br />
<span>Recupera tu contraseña #Html.ActionLink("aquí", "Recover", "Account")</span>
break;
case Suggestion.EMAIL_DONT_EXISTS:
<span>Comprueba que el correo electrónico está bien escrito</span><br />
<span>Registrate (abajo)</span>
break;
}
}
In MVC4, Razor wasn't catching the first curly bracket from the switch statement. So i removed the # from #vSuggestion and razor parsed the code properly.
Hope it helps.

I ran into this "Expected }" issue as well and the culprit turned out to be an apostrophe in an HTML comment This seems like a bug in Razor.
Here is an example on how to reproduce this issue in the default MVC 4 application with VS 2012. Just add the following a comment with an apostrophe to the #section featured {} in the default.cshtml. Remove the apostrophe from the comment and it works OK.
#section featured {
<!-- hello world it's not cool -->
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<p>...</p>
</div>
</section>
}

This may be more of a long shot but sometimes if you are using a keyword it will cause that error
List of Keywords VS 2012
http://msdn.microsoft.com/en-us/library/x53a06bb%28v=vs.110%29.aspx
I know two of the new keywords are await and async for 4.5
See the following for an example of what I am talking about
http://www.wduffy.co.uk/blog/css-class-property-asp-net-mvc-htmlattributes/

Try to add this line in web.config
<compilation debug="true" batch="false">
Now, when getting the error you should be able to open the temporary generated .cs file and take a look at generated code.
Maybe then you will more easily spot the problem.
For details look here Debugging ASP.NET generated code

Most helpful thing to do that will solve 6/10 of these for you is in VS2012
File-> Source Control -> Advanced -> Format this Document.
This will solve any un-closed div's, conditional statements even ul's and li's which cause big errors for .net.

I experienced this error but narrowed it down to a missing slash to close a tag. this worked in MVC3:
#helper metatags()
{
<meta charset="utf-8">
}
but not in MVC4. it requires this:
#helper metatags()
{
<meta charset="utf-8" />
}

Related

Blazor component is rendered but no lifecycle methods are called, no other methods can be invoked

I have a pretty standard Razor pages project, and I've recently introduced Blazor components into the project. I've added the _Host.cshtml, App.razor, and the other requirements to get Blazor working. The Blazor components work fine when I'm at an endpoint that is exclusively Blazor components. However, I want to embed Blazor components within my current .cshtml pages using something like
#(await Html.RenderComponentAsync<EditorComponent>(RenderMode.Server, new { Id = Model.Id}))
withing my cshtml page. This syntax renders the component fine, but it doesn't run any of the Blazor lifecycle methods(OnAfterRenderAsync) or even something like a button calling back to a Task, in my EditorComponent component.
I've included the
<script src="~/_framework/blazor.server.js"></script>
at the end of element on my layout page. Am I missing something to get this working?
I think you might need to use the component tag helper instead.
Docs
<component type="typeof(EditorComponent)" render-mode="Server" param-Id=#Model.Id/>
As you've not provided a lot of code, I've built this code to try and reproduce your problem.
I can't: it works as I would expect it to. So unless either answer above solves your problem, you'll need to provide more code.
Start point Blazor Server template.
New razor page - _Test.cshtml
#page "/Test"
#namespace BlazorApp8.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
Layout = "_Layout";
}
<h1>Counter in a Page</h1>
<div class="m-2 p-2">
#(await Html.RenderComponentAsync<Counter>(RenderMode.Server, new { Starter = 6}))
</div>
Update Counter.razor to take a parameter.
[Parameter] public int Starter { get; set; } = 0;
protected override Task OnInitializedAsync()
{
currentCount = this.Starter;
return base.OnInitializedAsync();
}
Run and navigate to /Test.
I get the Counter page, OnInitialized sets the initial count to 6 and clicking on the button increments the counter.
Replace the blazor section in your _Layout.cshtml with =>
<head>
...
<base href="~/"/>
</head>
...
<script src="_framework/blazor.server.js" autostart="false" ></script>
<script>
Blazor.start({
configureSignalR: function(builder) {
builder.withUrl("_blazor");
}
});
</script>
...
Make sure to check your web console output. Blazor is likely throwing an error. This is pulled from every layout of every area in every app that I make. I've enjoyed a templated micro ui experience. Dotnet really makes it a breeze to proliferate your own designs via templates.

VS code parse error ignored in some components

Currently working on an html template using angular, and I have this code:
<a mat-list-item class="side-link" [routerLinkActive]="['is-active']" [routerLink]="[{outlets: { agent-sidebar: ['agent-manage-clients'] } }]"><i class="fas fa-user mr-3"></i>Clients</a>
As you can see, there's nothing wrong with the code. However, doing an ng build produces an error whereas the compiler is looking for a missing : token where I think is unnecessary.
Why does my compiler keep looking for a 'missing' token even though I have closed the braces correctly?
This is funny to me because this is a copy pasted working code in a different component and only produced an error when I pasted it in this new component. So why isn't it producing the same error in the other component?
So apparently, I've fixed this bug of mine by changing the name of my router-outlet. It turns out that naming my outlet agent-sidebar with the token - messes up the compiler somehow. So after almost half a day of work, I've changed this:
[routerLink]="[{outlets: { agent-sidebar: ['agent-manage-clients'] } }]"
to this:
[routerLink]="[{outlets: { agentSidebar: ['agent-manage-clients'] } }]"
and compiler is now working properly.

<b-form-select-option> not working in Bootstrap Vue

can anyone tell me why my "b-form-select-option" is not working?
Thats my code:
I am using Vue with Bootstrap, everything else works, except for this single command. I am getting the standard "unknown html tag" error.
What is wrong here? I just copied the code from https://bootstrap-vue.js.org/docs/components/form-select/ and adapted it to my project.
Make sure you are using BootstrapVue v2.2.x.
The <b-form-select-*> sub components were introduced in v2.2.0.
the "unknown html tag" error means your editor doesn't recogonize thie element, your web app can still work, you can add this tag as an custom tag in your editor preference
There you have a simple example of usage.
You have to declare options inside <script>...</script>, like this:
options: [
{
value: null,
text: 'Please select an option'
},
]

Creating 2sxc Content Template

I followed the steps as per the following guide tutorial:
http://2sxc.org/en/Learn/Getting-started-with-creating-stuff/First-Content-Template
But I am having trouble with one or two issues.
When I get to Step 2.2 Add the Demo Template by pasting in the Template.txt file into my newly created Template .cshtml file, I am not seeing as expected with my Heading (Content.Title) and my Call to Action button/link (Content.LinkText) are not appearing on screen. This is preventing me from creating even the most simple of templates
After pasting in the Template.txt code:
<div class="sc-element"> #Edit.Toolbar(Content) <!--- Edit toolbar -->
<div class="co-person-image col-sm-4">
#if (!String.IsNullOrEmpty(Content.Photo))
{
<img src="#Content.Photo?w=350" alt="#Content.Name" class="img-responsive" />
}
else
{
<div class="co-person-placeholder"></div>
}
</div>
<div class="co-person-text col-sm-8">
<p>
<strong>#Content.Name</strong><br />
#if (!String.IsNullOrEmpty(Content.Position))
{
#Content.Position<br />
}
</p>
<p>
#if (!String.IsNullOrEmpty(#Content.EMail))
{
#Content.EMail<br />
}
#if (!String.IsNullOrEmpty(Content.Phone))
{
<text>#Content.Phone<br /></text>
}
</p>
#Html.Raw(Content.Description)
</div>
</div>
I am not seeing any placeholder and when I upload an image using ADAM it too wont appear to screen?
Not sure what I am doing wrong but would really appreciate some help on this as I also tried simply pasting in code from another one of your bootstrap templates into my new template but am getting the following error:
Error: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best
overloaded method match for 'string.IsNullOrEmpty(string)' has some
invalid arguments at CallSite.Target(Closure , CallSite , Type ,
Object ) at
System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite
site, T0 arg0, T1 arg1) at
ASP._Page_Portals_0_2sxc_Content__text_block_image_block_12_cshtml.Execute()
in d:\Inventise\trunk\Customers\St Josephs
Foundation\Projects\Website\Sources\DNN-Root\Portals\0\2sxc\Content_text
block_image block_12.cshtml:line 26 at
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() at
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext
pageContext, TextWriter writer, WebPageRenderingBase startPage) at
ToSic.SexyContent.Engines.RazorEngine.RenderTemplate() in
C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\2Sexy
Content Razor\RazorEngine.cs:line 76 at
ToSic.SexyContent.Engines.EngineBase.Render() in
C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\SexyContent\Engines\EngineBase.cs:line
89 at ToSic.SexyContent.SxcInstance.Render() in
C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\SexyContent\SxcInstance.cs:line
200
The path mentioned in the above error message appears wrong but I don't know where this can be amended?
I would appreciate help on this issue.
Regards
I'll try to guide you through it, but I'm guessing you forgot to set a demo-item.
The demo-item is used to show data on a template, till a user adds his own. So it's really important to create an item in the admin UI (Step 1.5) and assign it to the template (Step 1.5.1). This allows the template to render, before you add any data to a page :).
If you don't have a demo-item, the template assumes it can't render, and will show a message that it doesn't have data yet - or it will try to render, and fail with errors like the one above.
Did that help?

Simplifying ASP.Net MVC Razor Code

I'm looking for suggestions on how to simplify/optimize a piece of code in one of my view files in my ASP.Net MVC project. The code works, but I'm not sure if I've written it the best way.
Basically, the code is used to display a list of links to documents, with little thumbnails to the left of each link. The main problem, is that there are two different types of documents, and each type has to have it's thumbnail image stored in a different location, this is a project requirement and can't be changed.
I'm currently accomplishing this with the view code shown below.
// Display a link to every document.
foreach (var document in documentList)
{
<a href="#Url.Content("~/Document/DownloadDocument/" +
document.documentid)" target="_blank">
#{
// This will be the root of all the paths.
var path = "~/Document/DisplayImage/";
// If it's a Type 1 document, we need to use a different path.
if (document.documentType == "Type 1") {
path += "Path/To/Image/Folder";
<img id="imageHolder" src="#Url.Content(path)"
onerror="imgError(this);" />
#document.documentname
}
else {
path += "Path/To/Different/Image/Folder";
<img src="#Url.Content(path)" />
#document.documentname
}
}
</a>
<br />
}
Like I said, the code works, but I'm not too happy with how it's written. Does anyone have any suggestions?
When working with MVC, it's best to keep your Views dumb (no logic, simply rendering).
You can accomplish this by using a strongly-typed View and performing all of the logic in the Controller. It looks like you may already be doing this since you have a documentList.
In this case, documentList should be a list of View Model objects that already have the appropriate image path already set on them from the controller.
I would suggest moving the path to your document image into your model. That way you can just display the image from the path in the model and you wouldn't have to put any logic in your view.