I'm pretty new to MVC and just read an article about helpers. Now I have this code on the View:
<div class="display-label">Ingredients:
<% foreach (var e in Model.Products_Ingredients)
{%>
<%: e.Ingredient.Name%><br />
<%: e.Percentage%>
<%if (e.Percentage != null)
{%>
%
<%}%>
<br />
<%}%>
</div>
How do I go on and create a Helper that would replace that code with something simpler like:
<div class="display-label">Ingredients: <%: MyHelpers.Ingredients %> </div>
Thank you!
you'll need to make an HtmlHelper Extension Method
public namespace User.Extensions
public static HtmlHelperExtensions
{
public static string Ingredients(this HtmlHelper, Product_Ingredients productIngredients)
{
string result = string.Empty;
// loop through your ingredients and build your result, could use TagBuilder, too
return result;
}
}
}
Then you can call <%=Html.Ingredients(Model.Products_Ingredients) %>
make sure you add this assembly reference to the page
<%# Import Namespace=User.Extensions" %>
or to your Web.Config so all pages have access
<pages>
<namespaces>
<add namespace="User.Extensions" />
public class MyHelpers
{
public static string Ingredients(IEnumerable<Products_Ingredients> pi)
{
//html code as string
// <%: pi.Ingredient.Name%><br />
// <%: pi.Percentage%>
// <%if (pi.Percentage != null)
// {%>
// %
// <%}%>
// <br />
return htmlCode;
}
}
In your page add
<%# Import Namespace=namespace.MyHelpers" %>
<div class="display-label">Ingredients: <%: MyHelpers.Ingredients(Model.Products_Ingredients) %> </div>
Related
I wrote something like this in the controller.
public ActionResult Giris()
{
ViewData["Tarif"] = (from t in _entities.Tarif
join k in _entities.Kullanici on t.KID equals k.KID
select new {KAdi = k.KAdi, TAdi = t.TAdi})
.Take(4);
return View();
}
I am using it as below in the view page.
<% foreach (var item in (IEnumerable<dynamic>)ViewData["Tarif"]) { %>
<div class="begenilen-video" style="float:left">
<img class="video-resmi" alt="reklam" src="../../Uygulama/Resimler/Reklam/1.jpg" />
<span class="benzer-yemek-tarifi-adi"></span><%=item.TAdi %><br />
<span class="benzer-yemek-tarifi-ekleyen">Ekleyen: </span><br />
<span class="benzer-yemek-tarifi-izlenme">İzlenme: </span>
</div>
<% } %>
However,I am receive the error in the select statement.How do I invoke the items in the view page?
Thanks in advance.
As a guess because you haven't posted the error:
The object being stored in ViewData["Tarif"] will be of the type IQueryable<T> where T is an anonymous object and in your view you are casting to IEnumerable<dynamic>. IQueryable is also lazily loaded so you will be trying to execute your query once the object has been disposed.
You should really create a strongly typed view model
public class ViewModelType {
public IEnumerable<TarifType> Tarif { get; set; }
}
Tarif type
public class TarifType {
public string KAdi { get; set; }
public string TAdi { get; set; }
}
controller
public ActionResult Giris() {
var viewModel = new ViewModelType();
viewModel.Tarif = (from t in _entities.Tarif
join k in _entities.Kullanici on t.KID equals k.KID
select new TraifType { KAdi = k.KAdi, TAdi = t.TAdi }
).Take(4)
.ToList();
return View(viewModel);
}
view
<% foreach (var item in viewModel.Tarif) { %>
<div class="begenilen-video" style="float:left">
<img class="video-resmi" alt="reklam" src="../../Uygulama/Resimler/Reklam/1.jpg" />
<span class="benzer-yemek-tarifi-adi"></span><%=item.TAdi %><br />
<span class="benzer-yemek-tarifi-ekleyen">Ekleyen: </span><br />
<span class="benzer-yemek-tarifi-izlenme">İzlenme: </span>
</div>
<% } %>
I have a class that looks like this;
public class item
{
public string Tradingname { get; set; }
}
I have a Partial View that inherits from the "item" class;
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<item>" %>
<%= Html.TextBoxFor(x => x.Tradingname) %>
In my view I create a number of them. Let's Say 2;
<% using (Html.BeginForm())
{ %>
<% Html.RenderPartial("TradingName", new Binding.Models.item()); %><br />
<% Html.RenderPartial("TradingName", new Binding.Models.item()); %><br />
<input type="submit" />
<%} %>
Then in my controller I was hoping to be able to write this;
[HttpPost]
public ActionResult Index(List<item> items)
or
[HttpPost]
public ActionResult Index([Bind(Prefix = "Tradingname")]List<item> items)
But I can't seem to get any data back from my partial views into my List. Anyone know how I can get a variable list of data back from a variable set of partialViews?
I would recommend you using editor templates:
Controller:
public class HomeController: Controller
{
public ActionResult Index()
{
List<item> model = ...
return View(model);
}
[HttpPost]
public ActionResult Index(List<item> items)
{
...
}
}
and in the view:
<% using (Html.BeginForm()) { %>
<%= Html.EditorForModel();
<input type="submit" />
<% } %>
and finally simply move the partial in ~/Views/Home/EditorTemplates/item.ascx (name and location are important):
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<item>" %>
<%= Html.TextBoxFor(x => x.Tradingname) %><br/>
Given following view model:
class DetailsViewModel
{
public HeaderViewModel Header {get;set;}
public FooterViewModel Footer {get;set;}
}
I'm using editor template for Header view model:
<%: Html.EditorFor(x => x.Header) %>
The editor template (EditorTemplates/HeaderViewModel.ascx)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HeaderViewModel>" %>
<% ViewData.TemplateInfo.HtmlFieldPrefix = ""; %>
<%: Html.EditorFor(x => x.Search) %>
The result:
<input type="text" value="" name="Search" id="Search" />
If I remove the line
<% ViewData.TemplateInfo.HtmlFieldPrefix = ""; %>
the result is:
<input type="text" value="" name="Header.Search" id="Header_Search" />
Is there another way to achieve the same - render the names of the control without prefix?
I was thinking about a helper:
public static MvcHtmlString EditorWithoutPrefix<TModel, TValue>(
this HtmlHelper<TModel> html, TValue value)
{
var htmlHelper =... // create new HtmlHelper<TValue> and set it's model to be 'value' argument
return htmlHelper.EditorForModel();
}
and use it:
<%: Html.EditorWithoutPrefix(Model.Header) %>
but it is throwing exceptions.
Or maybe you know another elegant way to render names without prefix?
You could use the proper overload:
<%: Html.EditorFor(x => x.Search, "SearchViewModel", "") %>
Ok, here is my problem. I am trying to pass a view model of mine, which has multiple list in it, to my view. Then in my view i need to edit the different list. Then on my post i need to save the edits. Although, when i pass my viewmodel back to my post, it is empty! Can somebody explain what i am doing wrong? i am not worried about saving the information right now, i am just worried about getting the data back to the controller. The ViewModel is null when i hit that portion.
Controller
public ActionResult ManageNewsArticles()
{
NewsViewModel newsViewModel = new NewsViewModel();
newsViewModel.ListBreakingNews = db.NewsArticles.Where(n => n.PageSetupID == 1).ToList<NewsArticle>();
newsViewModel.ListMainArticle = db.NewsArticles.Where(n => n.PageSetupID == 2).ToList<NewsArticle>();
newsViewModel.ListSubNews1 = db.NewsArticles.Where(n => n.PageSetupID == 3).ToList<NewsArticle>();
newsViewModel.ListSubNews2 = db.NewsArticles.Where(n => n.PageSetupID == 4).ToList<NewsArticle>();
newsViewModel.ListSubNews3 = db.NewsArticles.Where(n => n.PageSetupID == 5).ToList<NewsArticle>();
return View(newsViewModel);
}
[HttpPost]
public ActionResult ManageNewsArticles(NewsViewModel newsViewModel)
{
if (ModelState.IsValid)
{
db.SaveChanges();
return RedirectToAction("Admin");
}
return View(newsViewModel);
}
here is my View
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TrueNews.ViewModels.NewsViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Manage News Articles
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Manage News Articles</h2>
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm(Model)) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<%: Html.EditorForModel(Model) %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to Admin Controls", "Admin") %>
</div>
</asp:Content>
NewsViewModel
public class NewsViewModel
{
public List<NewsArticle> ListBreakingNews { get; set; }
public List<NewsArticle> ListMainArticle { get; set; }
public List<NewsArticle> ListSubNews1 { get; set; }
public List<NewsArticle> ListSubNews2 { get; set; }
public List<NewsArticle> ListSubNews3 { get; set; }
} // End of Class
I couldn't get your view to display correctly using the EditorForModel syntax, however I did replicate your problem and found this article which provides one way of solving it:
http://weblogs.asp.net/nmarun/archive/2010/03/13/asp-net-mvc-2-model-binding-for-a-collection.aspx
I created a quick table NewsArticle containing Id and Stuff columns and then had the following form in the view:
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<% for (int i = 0; i < Model.ListBreakingNews.Count; i++)
{ %>
<div>
Id</div>
<div>
<%= Html.TextBox(string.Format("ListBreakingNews[{0}].Id", i), Model.ListBreakingNews[i].Id) %>
</div>
<div>
Name</div>
<div>
<%= Html.TextBox(string.Format("ListBreakingNews[{0}].Stuff", i), Model.ListBreakingNews[i].Stuff) %>
</div>
<% } %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
and the items in the list were passed when posted. I also found that previously you had Html.BeginForm(Model) which when I added it caused nothing to be passed through in the view model - I am only a newbie to MVC so I don't know why this happens but my code below worked only with Html.BeginForm() and not Html.BeginForm(Model).
I hope this helps.
I try to creat list for detail view. then put a search text box on the top of the list. Hope the search result will replace the list partially.
My control code like:
public ActionResult Index(int? page)
{
Repository repository = new Repository();
var listitems= repository.FindAllItems();
return View(registry_page);
}
public ActionResult Search(string keyword)
{
try
{
Repository repository = new Repository();
var listitems = repository.FindItemsByKeyWord(keyword);
return View("Index", registries);
}
catch
{
return View("Index");
}
}
My View code like:
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>" type="text/javascript"></script>
<% using (Ajax.BeginForm("Search", new AjaxOptions { UpdateTargetId = "MyList" }))
{ %>
<p>
Search:
<input id="keyword" name="keyword" type="text" />
<input type="submit" value="Go" />
</p>
<% } %>
<div id="MyList">
<table idth="780px">
...
<% foreach (var item in Model)
{ %>
<tr>
...
</tr>
<% } %>
</table>
</div>
When I submit the ajax form, it did reach the right action Searcn and I did get the right result from repository, but the list in the view wasn't replaced with the new result.
If I change search action like:
public ActionResult Search(string keyword)
{
string teststring = "<div>This is a test string to replace the list</div>";
return Content(teststring);
}
The list wil be replace by the test string.
How to fix this problem?
You can pull MyList out into a Partial view, MyPartialList.ascx
Your search actionresult should then return this partial view, something like this:
public ActionResult Search(string keyword)
{
Repository repository = new Repository();
var listitems = repository.FindItemsByKeyWord(keyword);
return PartialView("MyPartialList", listitems);
}
In the index view, render the initial list like this:
<div id="MyList">
<% Html.RenderPartial("MyPartialList",Model); %>
</div>
Your partial, MyPartialList.ascx would look like this:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Item>>" %>
<table ..>
<% foreach(var item in Model){%>
// print it out
<%}%>
</table>