I'm working through the NerdDinner MVC tutorial and came across this and was wondering about.
On page 62 of the pdf they have the following:
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Upcoming Dinners</h2>
<ul>
<% foreach (var dinner in Model) { %>
<li>
<a href="/Dinners/Details/<%=dinner.DinnerID %>">
<%= Html.Encode(dinner.Title) %>
</a>
on
<%= Html.Encode(dinner.EventDate.ToShortDateString())%>
#
<%= Html.Encode(dinner.EventDate.ToShortTimeString())%>
</li>
<% } %>
</ul>
</asp:Content>
They then state that instead of using an <a> tag that you can use the Html helper like so:
<%= Html.ActionLink(dinner.Title, "Details", new { id=dinner.DinnerID }) %>
The question is: Isn't it still important to Html.Encode the dinner.Title from the Model when using this approach? If not, why not? If so, is there a way to use the Html.ActionLink and still use Html.Encode?
Html.ActionLink already calls Encode, internally (see the source). You don't want to do it twice.
Related
as i'm new to ruby and rails in general i would have a short question cause i'm stuck at a minor issue.
I'm calling a content API from my controller and looping thru the response in the view directly. The main problem is: If one of the objects, has an empty value which i'm calling..it breaks the view.
Question would be how can i scip the elements which are emtpy...in example if post["heroimage"]["url"] is empty?
Example view:
<div class="gallery">
<% #blog.each do |post| %>
<a target="_blank" href="blog/<%= post["id"] %>">
<img src="<%= #host + post["heroimage"]["url"]%>" alt="" width="600" height="400">
</a>
<div class="desc"><%= post['description'] %></div>
<% end %>
</div>
There is nothing Rails or Rails views specific about your question. What you're trying to do is skip elements in an each loop in Ruby, and the answer is, next
somethings.each do |thing|
next if thing.nil?
# .. does not get called if thing is nil
end
From what I understand from the question and your comments you can use,
post.dig("heroimage", "url")
here is the link to dig method documentation. If you want to skip the image in case of empty url you can do something like this
<div class="gallery">
<% #blog.each do |post| %>
<a target="_blank" href="blog/<%= post["id"] %>">
<% if post.dig("heroimage", "url") %>
<img src="<%= #host + post["heroimage"]["url"]%>" alt="" width="600" height="400">
<% end %>
</a>
<div class="desc"><%= post['description'] %></div>
<% end %>
</div>
This will still show the title even if the image URL is empty.
This error message doesn't make a lot of sense in the context of MVC:
MasterPage cannot be applied to this page because the control collection is read-only. If the page contains code blocks, make sure they are placed inside content controls (i.e. <asp:Content runat=server />)
What's it mean?
My view looks something like this:
<%# Page Inherits="System.Web.Mvc.ViewPage<Site.Controllers.ProductCategoryController.ProductListViewModel>" MasterPageFile="~/site.master" %>
<% foreach (var prod in Model.Products) { %>
<li><%=prod.Description%></li>
<% } %>
I figured it out, it is quite a simple mistake. The problem was my view code wasn't wrapped in a content control (which maps to a contentplaceholder in the master page).
Of course my view should be like this:
<%# Page Inherits="System.Web.Mvc.ViewPage<Site.Controllers.ProductCategoryController.ProductListViewModel>" MasterPageFile="~/site.master" %>
<asp:Content runat="server" ID="Content1" ContentPlaceHolderID="BodyContent">
<% foreach (var prod in Model.Products) { %>
<li><%=prod.Description%></li>
<% } %>
</asp:Content>
Pretty obvious but I just couldn't see it!
And the error message didn't really help me.
I have a simple html form. The built-in HTML helpers are rendering. The markup is not created. What am I missing?
<asp:Content ID="Content5" ContentPlaceHolderID="IslandPlaceHolder" runat="server">
<%using (Html.BeginForm()){%>
<div id="manifest">Manifest Option: <%Html.DropDownList("docid",ViewData["manifests"] as SelectList);%></div>
<div id="release">Release Version: <%Html.TextBox("release"); %></div>
<div id="locale">Localization: <%Html.DropDownList("localization"); %></div>
<div id="label">Label: <%Html.DropDownList("label"); %></div>
<div id="session">Session ID (optional): <%Html.TextBox("sessionInput"); %></div>%>
<input type="submit" value="Build" />
<%}%>
</asp:Content>
You need to change <% to <%= to output the markup. Right now it is making the call, but doing nothing with the returned string.
You'll also need to remove the semicolon at the end of the method calls.
<%= Html.DropDownList("docid",ViewData["manifests"] as SelectList) %>
Well I'm some what baffled!
'Simple problem'
I have parts of my master page that I want to render differently depending on whether or not a ContentPlaceHolder is empty.
So:
I have a master page that as some code like:
<% if (ContentPlaceHolder1.HasControls()) {%>
<div id="LittleDiv">
<% } else { %>
<div id="BigDiv">
<% } %>
some text
</div>
<% if (ContentPlaceHolder1.HasControls()) {%>
<div id="Div1">
yadda yadda yadda
[<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"/>]
blah blah blah
</div>
<% } %>
I have a page that has some code along the lines of:
<asp:Content ID="Content1" runat="server" contentplaceholderid="ContentPlaceHolder1">
<% if (Model.SomeValue) { %>
hello!
<% } %>
</asp:Content>
(note: the logic in the example page's embeded code block may be unique, for each content place holder, for each page!)
Which seems nice however it doesn't work.
The problem is as I see it (warning I might be completely wrong!). The Embedded Code Blocks are evaluated in the objects Render. A little counter intuitively the page seems to control the master. So the master page's Render is called before the pages render. This means that the master page always sees content in the page's content control.
Is there a nice way round this?
(I have a bit of a solution but it is a monstrous hack! I won't post it yet coz I don't want to influence thinking.)
OK, here's another idea :). Instead of putting the logic in your master page...
<% if (ContentPlaceHolder1.HasControls()) {%>
<div id="LittleDiv">
<% } else { %>
<div id="BigDiv">
<% } %>
some text
</div>
Why not create a placeholder for it? e.g.
<asp:ContentPlaceHolder ID="LittleBigDivPlaceHolder" runat="server" />
You could then allow your concrete non-master pages to decide the content. You could also avoid repeating yourself by moving the logic into a Partial View that could be, say, parameterised by your different views.
Rather than looking for the resultant controls can your master page examine the contents of the ViewData dictionary and work its logic from there?
Alternatively, you could use javascript to show / hide divs on the client.
What pros(positive sides) of using Spark view engine for ASP.NET MVC project. Why it better then default view engine?
One important thing about Spark View engine is that its syntax is very similar to HTML syntax, that way your views will be clean and you will avoid "tag soup" that is in WebForms View engine.
here is an example:
Spark:
<viewdata products="IEnumerable[[Product]]"/>
<ul if="products.Any()">
<li each="var p in products">${p.Name}</li>
</ul>
<else>
<p>No products available</p>
</else>
WebForms:
<%var products = (IEnumerable<Product>)ViewData["products"] %>
<% if (products.Any()) %>
<ul>
<% foreach (var p in products) { %>
<li><%=p.Name %></li>
</ul>
<%} } %>
<% else { %>
<p>No products available</p>
<% }%>
It avoids the HTML tag soup you see a lot. Consider Spark:
<ul>
<li each='var p in ViewData.Model.Products'>
${p.Name}
</li>
</ul>
as opposed to the classic html tag soup variant:
<ul>
<% foreach(var p in ViewData.Model.Products) { %>
<li>
<%= p.Name %>
</li>
<% } %>
</ul>
The Spark syntax is much cleaner.
I really like the Bindings features.
http://sparkviewengine.com/documentation/bindings
You can specify something in the bindings and use nice xml markup for it in your views.
We have bindings for all the html helpers we use in our views eg.
<textbox for=""/>
<dropdown for="" items=""/> etc etc...