ASP.NET Page ViewData Overwritten (missing) - razor

Contents of _ViewStart.cshtml
#{
Layout = "_Layout";
ViewData["IndexLink"] = Context.Request.Path != "/" ? "/Index" : "";
}
Contents of Downloads.cshtml
#page
#model DownloadsModel
#{
ViewData["Title"] = "Downloads";
}
Snippet from _Layout.cshtml
<title>#ViewData["Title"] - ABC Sofware LLC</title>
Problem:
The <title> tag is being rendered without the view's title.
Troubleshooting Steps:
I put a break point in _Layout.cshtml to see what
ViewData contains. It has one key instead of two.
#ViewData.Keys
Count = 1
[0]: "IndexLink"
If I remove the ViewData["IndexLink"] line from _ViewStart.cshtml then ViewData["Title"] is set.
#ViewData.Keys
Count = 1
[0]: "Title"
Why does setting a ViewData key in _ViewStart.html break ViewData in the views?

Looks like this is currently a bug (see https://github.com/aspnet/Mvc/issues/7675 -- planned to be fixed in Core 2.2.0) but the current workaround is instead of:
ViewData["Key"]
you would use
ViewContext.ViewData["Key"]
in both _ViewStart.cshtml and Downloads.cshtml. Referencing
#ViewData["Key"]
in _Layout.cshtml still seems to work fine for me.

Related

Can't return data from Content Picker in Umbraco 7.6.4

I am currently trying to output data from the new Multinode Treepicker in Umbraco 7.6.4 here is my current setup and code:
Doctype
Content Node with 'Page' Doctype
Code to output the names of the selected nodes:
#{
IPublishedContent typedContentPicker = Model.Content.GetPropertyValue<IPublishedContent>("sections");
if (typedContentPicker != null)
{
<p>#typedContentPicker.Name</p>
}
}
This I took from the official Umbraco Documentation and adapted it to my project. This code is in a template with the 'page' doctype.
Currently the above code does not output anything to my page, I am expecting to see a list of nodes displayed on the page, can anyone see what the issue is or where I am going wrong?
Dumb moment, I was looking at the documentation for a content picker and not a multi-node tree picker!
Correct code is:
#{
var typedMultiNodeTreePicker = Model.Content.GetPropertyValue<IEnumerable<IPublishedContent>>("sections");
foreach (var item in typedMultiNodeTreePicker)
{
<p>#item.Name</p>
}
}

Error on looping through a RelatedLinks property of dynamic Node in Razor

I have a Razor partial which displays my site navigation:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var home = CurrentPage.Site();
umbraco.NodeFactory.Node navigationSettingsNode = MySite.Umbraco.NavigationSettings;
dynamic navigationSettings = new umbraco.MacroEngines.DynamicNode(navigationSettingsNode.Id);
var settings = home.Children.Where("DocumentTypeAlias == \"Settings\"").First();
}
#if (navigationSettings.HasValue("topNavigation"))
{
<ul>
dynamic topNavigation = navigationSettings.topNavigation;
var topNavigation2 = settings.topNavigation;
<span>#topNavigation</span>
<span>#topNavigation2</span>
foreach(dynamic item in topNavigation)
{
<li>
#item.caption
</li>
}
</ul>
}
Initially I was looping through topNavigation2 items which worked fine and with no problem.
Now I'm looping through topNavigation items and it throws an error:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'char' does not contain a definition for 'link'
I don't want to use var settings anymore, I want to use only dynamic navigationSettings variable. In order to get the right node of navigationSettings I need to some operation and I don't fancy to paste the same code in every view I want to use it so I want it to be accessible from dll and available to use anywhere.
Also the navigationSettings node in my Umbraco is outside of main content tree so is not a child of Home.
Why isn't it working? Both
dynamic topNavigation = navigationSettings.topNavigation;
var topNavigation2 = settings.topNavigation;
produce the same json result and both are dynamic objects.
How to make it work correctly?
I'm using MVC 5.2.3
It looks like your topNavigation property is a string, and so when you call for each on it, it's iterating through the characters in the string.
Also, don't use NodeFactory, it's deprecated. You should be using IPublishedContent instead.
I'd use the strongly typed content objects instead of dynamic, as a) they're faster, and b) they're easier to work with.
Here's a great article explaining the different ways of getting content: https://24days.in/umbraco-cms/2015/strongly-typed-vs-dynamic-content-access/

Why does returning partial view affect my styles from being applied to my partial view?

So,
I have bools for when to display a certain partial view and I noticed for one of my partial views, it displays correctly with the correct CSS styles and classes.
However, my other partial view does not display correctly (I get no errors in console too) and I have narrowed it down to this line of code seeing how this makes the difference:
#Html.ActionLink(#Culture.GetString("ResetPasswordViaQuestionAnswer"), "GetUserName", "Account", new { style = "color:black; background: none;" })
OR
#Culture.GetString("ResetPasswordViaQuestionAnswer")
Whenever I use #Html.ActionLink or #Url.Action to call my action to return my partial view, the CSS style breaks. None of my classes get properly added to my inputs and form elements.
The above calls this action:
[AllowAnonymous]
public ActionResult GetUserName()
{
LoginModel loginModel = new LoginModel();
GetUserName getUserName = new GetUserName();
loginModel.getUserName = getUserName;
loginModel.DisplayResetPasswordDialog = true;
return PartialView("Login", loginModel);
}
Which then goes to my Login partialview which inside a div contains:
#if(Model.DisplayChangePasswordDialog == true){
#Html.Partial("PasswordExp",new ViewModels.PasswordChangeViewModel())
}else if (Model.DisplayResetPasswordDialog == true){
#Html.Partial("ResetUserPassword", new ViewModels.GetUserName())
}else{
#Html.Partial("_login", Model)
}
Something in what I have done above is breaking the CSS styles and classes from being attached to my inputs. The view is loaded but the view is loaded incorrectly. No styles or classes are applied.
Why?
You can't (or shouldn't) redirect to a partial view because you're not going to be getting your _Layout file that contains your css and js.
Instead you should redirect to a view containing your partial view. That view should have a reference to your layout file.

generating page title with razor script - umbraco

So I am trying to create a script whereby depending on the document type of the page a certain pre-defined title tag format will appear, if there is nothing already written in an overwriting custom title input. I have inserted the macro within the title tag on my master template but keep on getting an Error loading Razor Script message .
Html
<title>
<umbraco:Macro Alias="NewPageTitle" runat="server"></umbraco:Macro>
</title>
Script -
#inherits umbraco.MacroEngines.DynamicNodeContext
#using umbraco.MacroEngines
#{
if(String.IsNullOrEmpty(#Model.tabName.ToString()) == false )
{
#Model.tabName
}
else if(#Model.DescendantsOrSelf("Country"))
{
<text>
Holidays in #Model.Name
</text>
}
else
{
#Model.Name;
}
}
Any help would be greatly appreciated.
Try this code out. The problem with your original code is that you were using "#Model.DescendantsOrSelf("Country")" as a boolean, and it is a list. I also removed your comparison for if(String.IsNullOrEmpty(#Model.tabName.ToString())).
Also, if you add ?umbDebugShowTrace=true to the end of your URL, you can get some valuable debugging information. There is a Chrome Extension called "Umbraco Debug" that I use to quickly access that query string and information. You may find it useful.
#inherits umbraco.MacroEngines.DynamicNodeContext
#using umbraco.MacroEngines
#{
if(String.IsNullOrEmpty(#Model.tabName.ToString()))
{
#Model.tabName
}
else if(#Model.DescendantsOrSelf("Country").Count() > 0)
{
<text>
Holidays in #Model.Name
</text>
}
else
{
#Model.Name;
}
}
its very simple just add following code into your title tag
#Umbraco.Field("pageName")
will display pageName,you may also add custom properties from document type.
e.g. you have added new property like "metaKeywords" with value "html,javascript,xml",fetch that values as following way...
#Umbraco.Field("metaKeywords")
even you don't need to add custom properties in your model

Umbraco Razor Macro Parameter access with space

I am new to Umbraco. I am currently using Umbraco 7.0. I have created a Razor
macro with a parameter that will access property from home template page. In My Macro
due to space only first word of string displays and rest of the string is not
displayed. property
name is sliderHeading with value : My First Slide. Macro inserted in the template is
as follows :-
#Umbraco.RenderMacro("HomePageSlider", new {mediaId="1084",
sliderHeading=#Umbraco.Field("sliderHeading")})
// where sliderHeading is macro parameter.
Macro definition :-
#inherits umbraco.MacroEngines.DynamicNodeContext
#if (Parameter.mediaId != null)
{
var mediaFolder = Library.MediaById(Parameter.mediaId);
if (mediaFolder.Children.Any())
{
foreach (var mediaItem in mediaFolder.Children)
{
<div class="cycle-slide" style="background-
image:url(#mediaItem.umbracoFile)" data-cycle-title=#Parameter.sliderHeading
data-cycle-desc="Remember, you are not limited to image elements. You can display
other HTML too." data-cycle-link="#"></div>
}
}
}
So, in macro, parameter value is accessed by :- data-cycle-
title=#Parameter.sliderHeading.
Now my issue is that
if property value is :- "My First Slide". Then it will give wrong output "My" on page.
if property value is :- "My First Slide" with html space (&nbbsp;) in between Then it
will give right output "My First Slide" on page.
How should I access parameter in Macro, so that it will give right output.
Seems a bit simple but won't wrapping #Html.Raw or even #Raw round your code force the parameter to output with spaces?
Like:
data-cycle-title=#Raw(Parameter.sliderHeading)