Broken RenderPartial with MVC3 - c#

I've come to an MVC3 project I wrote just a week ago which has stopped working and is throwing the following error:
Error 10
The call is ambiguous between the following methods or properties: 'System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(System.Web.Mvc.HtmlHelper, string)' and 'System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(System.Web.Mvc.HtmlHelper, string)'
What is the reason for this? I haven't changed anything in project recently for it to bork. The code I call it in looks like this:
<div class="page-body">
#if(!String.IsNullOrWhiteSpace(ViewBag.ErrorMessage)) {
// Output error message
Html.Raw(ViewBag.ErrorMessage);
} else {
// Render upload form
Html.RenderPartial("_UploadForm");
}
</div>

You are missing # symbols front of your Html.Raw because teh method reutrns a string back hence requires the #symbol
For your knowledge taken from MSDN : The Razor syntax # operator
HTML-encodes text before rendering it to the HTTP response. This
causes the text to be displayed as regular text in the web page
instead of being interpreted as HTML markup.
Please use it this way
<div class="page-body">
#if(!String.IsNullOrWhiteSpace(ViewBag.ErrorMessage)) {
#Html.Raw(ViewBag.ErrorMessage);
} else {
// Render upload form
Html.RenderPartial("_UploadForm");
}
</div>

Related

Razor Pages override route getting RoutePatternException despite seemingly correct

I am using Razor Pages, and everything has been going smoothly so far.
Now I wish to create a page with an override route. Like the override routes that are shown possible here.
I am, however encountering the following exception, despite I don't seem to have the issue in my code that it describes:
RoutePatternException: There is an incomplete parameter in the route template. Check that each '{' character has a matching '}' character.
I must be somehow misunderstanding how this routing works, but I haven't been able to find someone encountering the same issue in my preliminary searches.
This is my entire code on this page so far:
#page "/layouts/{layoutId:int}/save/{revisionId:int}"
#model Project.Web.Pages.TenantBased.Layouts.SavePageModel
#{
Layout = "_TenantLayout";
ViewData["Title"] = "Title";
}
And this is the code-behind:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Legalit.Web.Pages.TenantBased.Layouts
{
public class SavePageModel : PageModel
{
public void OnGet(int layoutId, int revisionId)
{
}
}
}
This gives the following exception when running the project:
RoutePatternException: There is an incomplete parameter in the route template. Check that each '{' character has a matching '}' character.
If I remove the first / from the route as so:
#page "layouts/{layoutId:int}/save/{revisionId:int}"
Then it stops generating the exception, but I of course get the wrong routing from it. Now my page is reachable by the directory path with this route added to the end of it.
I am using .NET 6.0.
The project type is Microsoft.NET.Sdk.Web
The project had a custom Convention in the Program.cs that was specified under the AddRazorPagesOptions configuration method.
After removing this, it worked fine.

Why local function in Razor View doesn't compile?

I did some reading and found out that you can now have local functions in razor views: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-3.0#razor-code-blocks
#{
void RenderName(string name)
{
<p>Name: <strong>#name</strong></p>
}
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
And that looks great. But, for some reason this doesn't compile on my machine. Why is that? My target framework is .NetCore 3.1 and Visual Studio 2019 16.6.0. There are some error messages:
"Type or namespace definition, or end-of-file expected" - on the very first line (#using statement) and then:
"Invalid expression term '<'" on the line with HTML.
What is wrong with that?
Functions must be declared inside a #functions block in Razor pages.
Here is a related post.
Is this working?
#functions{
void RenderName(string name)
{
<p>Name: <strong>#name</strong></p>
}
}
#{
RenderName("Mahatma Gandhi");
RenderName("Martin Luther King, Jr.");
}
OK, the solution was really simple. I had a warning that was saying: "Detected Razor downgrade". I just had to remove reference to Microsoft.AspNetCore.Mvc (2.2) which had been added automatically while creating the project in one of previous versions of VisualStudio.

Why does Umbraco treat IPublishedContent differently when called via AJAX

The short story is I have a list of blog articles which I'm casting to a model which contains .wordCount. This is calculated by striping the HTML from the output of the RTE and then calculating the lengh. The output of the RTE can contain Macros.
On first load, i.e from a view, the output of the RTE renders my Macros as HTML. However, when I refresh my list articles using a clientside AJAX the output of the RTE is rendered differently. My Macros now look like this: <?UMBRACO_MACRO macroAlias="ArticleAudio" audioPicker="6068" audioPosition="left" audioTitle="Interview Audio" />
I also get the error System.InvalidOperationException: 'Cannot render a macro when there is no current PublishedContentRequest.
public static Article ToArticle(this IPublishedContent item)
{
string rawText = HelperFunctions.StripHTML(item.GetPropertyValue<string>("richText"));
...
}
public static string StripHTML(string htmlString)
{
string pattern = #"<(.|\n)*?>";
return Regex.Replace(htmlString, pattern, string.Empty);
}
Expected
<div class="audio-player">
<audio style="display: none;">
<source src="https://www.address.com/media/77390/interview.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
My Output
<?UMBRACO_MACRO macroAlias="ArticleAudio" audioPicker="6068" audioPosition="left" audioTitle="Interview Audio" />
Thank you in advance for your help
When you get the property value, it will have the placeholder string for the macro in it. There is some code that runs as part of rendering the page that turns those into the actual Macros. I can't remember off the top of my head where that lives though.
Can you post the full code of the controller you are calling to update via AJAX? Is it a surface controller, an API controller, or something different?

How to let user download data to a file

I want to let user download data I am displaying elsewhere in the website as reports.
I am using Asp.net core 2.1 rc1 MVC app.
My cunning plan was to create a special view which would render data as a tab delimited text and use response headers to make browser download it instead of displaying HTML. This almost works perfectly.
My "HttpGet" code in the controller looks like this:
Response.Headers.Add("Content-disposition", "attachment; filename=export.tsv");
return View(MyModel);
My razor view looks like this:
#Model IEnumerable<MyModel>
#{
Layout = null;
String LineBreak = Environment.NewLine;
String Tab = "\t";
}
Header1 Header2 ...
#if (Model.Count > 0)
{
foreach (MyModel myModel in Model)
{
#myModel.Field1#Html.Raw(#Tab)#myModel.Field2 ... #Html.Raw(#LineBreak)
}
}
This works splendidly except that this ugly error message appears as a first line in the file:
System.Collections.Generic.List`1[MyApp.Models.MyModel] IEnumerable<MyModel>
The rest of the file is exactly what I need.
Does anyone know how to remove this message? Or if there is something wrong with my general approach...
Full project available here: https://github.com/under3415/ExportError/ (just click on download link and examine the file)
You've written #Model, while the correct syntax is #model (lowercase - it's case-sensitive).
A first-line #model directive specifies the model type. #Model dereferences the actual model instance. What you're seeing is its ToString representation.
You're getting this error because you're returning view with the model return View(MyModel);, you should be using FileResult
Here are the complete instructions on it
Download file of any type in Asp.Net MVC using FileResult?

MVC Helpers Working inline, but not in App_Code

Originally I repeated lines of code for each menu item and just hard coded the various menu item values but then I came across helpers and taught I would give it a try. Now 6 lines of code (for each menu item) are reduced to one (for each item), and I have a single place to go to alter anything instead of changing it in 5 places. All great stuff. Here is the code:
#helper MenuItem(string action, string controller)
{
<a href="#Url.Action(action, controller)" id="#controller">
<div class="MenuItem">
<img src="#("/XXX.YYY.Web/Content/Images/Icons/Menu/mnu"+controller+".png")" /><br />
//I had to put the XXX.YYY as a literal string because the ~ didn't work, it was quoted literally also instead of showing the home folder.
#controller
</div>
</a>
}
My problem is that it works when I use it inline, say at the top of my _Layout.cshtml with the following lines of code:
#MenuItem("Index", "Home")
#MenuItem("Index", "Chart")
But when I remove it out to a generic helper called LayoutHelpers.cshtml under the App_Code folder so I can reuse it, and alter the code accordingly as follows:
#LayoutHelpers.MenuItem("Index", "Home")
#LayoutHelpers.MenuItem("Index", "Chart")
Note: Nothing in the actual helper changed. Only the above 2 lines in the _Layout.cshtml file changed.
When I make those changes I get the following error:
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0103: The name 'Url' does not exist in the current context
Source Error:
Line 3: #helper MenuItem(string action, string controller)
Line 4: {
Line 5:
Line 6:
Line 7: ##
Now the curious thing is, notice how it works on line 7 "mnuHome.png" as opposed to mnucontroller.png. Yet it says that line 5 is in error.
I also have a problem with the ~ not working in the helper. ie. the ~/Content is shown as a literal string instead of it being compiled to a proper path which should always point to the home folder of the app.
Following is a link that I am using for reference:
http://weblogs.asp.net/jgalloway/archive/2011/03/23/comparing-mvc-3-helpers-using-extension-methods-and-declarative-razor-helper.aspx
Specifically less than 1/4 of the way down the page under the heading "Razor Declarative Helpers". From here on.
Thanks in advance for your help.
The standard helpers (such as UrlHelper and HtmlHelper) are not available in a Razor inline #helper. If you need to use it will need to pass the UrlHelper as parameter to your helper:
#helper MenuItem(UrlHelper url, string action, string controller)
{
<a href="#url.Action(action, controller)" id="#controller">
<div class="MenuItem">
<img src="#url.Content("~/XXX.YYY.Web/Content/Images/Icons/Menu/mnu"+controller+".png")" />
<br />
#controller
</div>
</a>
}
and then when calling pass the correct instance:
#LayoutHelpers.MenuItem(Url, "Index", "Home")
#LayoutHelpers.MenuItem(Url, "Index", "Chart")

Categories