ASP.NET MVC best approach to provide data to Views - asp.net-mvc

I'd like to to provide data to a table in the views. The data is not only from database but also from a csv file.
Should I store the data in the ViewData, or should I store it in a object and pass it to views? What is the best approach, or any other methods I can use? Thx!

Use strongly-typed views and pass the object directly to the view:
// Model (PersonRepository class)
public static Person Get(Int32 id) {
using (MyContext context = new MyContext()) {
Person p = context.Person.First(p => Person.id == id);
return p;
}
}
...
// Controller
public ActionResult Show(Int32 id) {
return View(PersonsRepository.Get(id);
}
...
// View
<%# Page Inherits="System.Web.Mvc.ViewPage<Models.Person>" Title="" Language="C#" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%= Model.Id %> <br />
<%= Model.Name %> <br />
</asp:Content>

You should create a model object, fill it in the controller with data from heterogeneous sources and pass that model to the view.

Related

LINQ to SQL datacontext passing data to a grid in view

just trying to fathom out LINQ to SQL and datacontext class.
I am learning MVC coding and have a database with some test data.
I have created my datacontext and have been able to get this far in the controller.
ClientClassesDataContext context2 = new ClientClassesDataContext();
var result2 = context2.up_GetClient(4,1);
up_GetClientResult myObject = result2.SingleOrDefault();
return View(myObject);
This returns a list of clients, my part I'm stuck at is how to pass this to the view and put it in a grid style.
Even passing the object to the view with only one row of data, I'm kinda stuck on how t even access items and display in, say, a text box.
Even just any pointers or links on best practice for LINQ to SQL etc would be a great help. There seems to be a lot of varying info out there.
The View is empty with the code below.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Test</h2>
</asp:Content>
Any help or pointers would be appreciated.
Model:
public class MyModel
{
IEnumerable<client> _getClient { get; set; }
}
Controller:
ClientClassesDataContext context2 = new ClientClassesDataContext();
var result2 = context2.up_GetClient(4,1);
MyModel _mymdl=new MyModel();
_mymdl._getClient = result2.SingleOrDefault();
return View(_mymdl);
VIew:
#model ProjectName.web.MyModel
#{
ViewBag.Title = "";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
foreach (var item in Model._getClient)
{
//Add your login to create Table
}
</div>

How to fetch one row from db in asp mvc

ASP.net mvc in new for me, for some time I used php (no mvc), but now i'm interested, how I can fetch one row from db? without foreach, for example in title...
here is some code:
controller
public ActionResult Index()
{
var pages = (from page in db.Pages where page.PageName == "index" select page).ToList();
return View(pages);
}
view:
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<% foreach (var item in Model)
{ %>
<%= Html.Encode(item.Text) %>
<% }
%>
</asp:Content>
In your controller, instead of .ToList() you can use the .FirstOrDefault() method, this will return only the first row from the database.
Then in your view you won't need the foreach.
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%= Html.Encode(item.Model.Text) %>
</asp:Content>
What you're doing there is creating a List datatype variable and passing it in as the Model to your view. Assuming this is the only piece of data your page needs. Here's what you would do;
public ActionResult Index()
{
string page = db.pages.where(p => p.PageName == "index").FirstOrDefault().PageName;
return View(page);
}
There in your page, Model will now be that single string value and you can do this;
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%= Model %>
</asp:Content>
Although it is best practice to create a ViewModel for the page with the just the properties your page will need and pass that in as the Model.
public class MypageViewModel
{
public string PageName { get; set; }
}
Then do this in the controller
public ActionResult Index()
{
MypageViewModel MyModel = new MypageViewModel();
MyModel.PageName = db.pages.where(p => p.PageName == "index").FirstOrDefault().PageName;
return View(MypageViewModel);
}
Hope that helps.
If you are using Entity Framework:
var singleItem = db.pages.Find(id);
This will use the Primary Key of your entity.
If you have a composite primary key consisting of multiple properties, Find will still work (because it can take multiple values):
var singleItem = db.pages.Find(key1, key2);

ASP.Net MVC Model problems

Can you please help me understand what is the issue with generic collection? Thanks in advance!
Error: The model item passed into the dictionary is of type 'System.Collections.Generic.List1[DomainModel.Product]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[DomainModel.Entities.Product]'.
MODEL:
namespace DomainModel.Concrete
{
public class SqlProductsRepository : IProductsRepository
{
private Table<Product> productsTable;
public SqlProductsRepository(string connString)
{
productsTable = (new ProaductDataContext(connString)).GetTable<Product>();
}
public IQueryable<Product> Products
{
get { return productsTable; }
}
}
}
INTERFACE
namespace DomainModel.Abstract
{
public interface IProductsRepository
{
IQueryable<Product> Products { get; }
}
}
VIEW
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMaster.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Entities.Product>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Products
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var product in Model)
{ %>
<div class = "item">
<h3> <%=product.Name%></h3>
<%= product.Description%>
<h4><%= product.Price.ToString("c")%></h4>
</div>
<%} %>
</asp:Content>
The error message tells you all your need to know;
The model item passed into the dictionary is of type
'System.Collections.Generic.List1[DomainModel.Product]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable1[DomainModel.Entities.Product]'.
If you look at your view you can see
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMaster.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Entities.Product>>" %>
The Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Entities.Product>>" is what's tripping you up. You're passing in an IEnumerable of DomainModel.Product, but you're expecting something else. It's a bit strange you have two classes named the same within close to the same namespace, but never mind, you need to ensure you're using the same class, in the same namespace in both the controller and the view.
So I'd try changing your view to become
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/ViewMaster.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<DomainModel.Product>>" %>
Then try to figure out why you have two Product classes :)

ASP.net MVC2 Passing data between strongly typed views

I have the following MVC2 view that is strongly typed with a viewmodel, the viewmodel contains a list of values from one db table, I need to display a single value from a second table in the view, this is my view code
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CustomerDatabase.WebUI.Models.CustomerSitesListViewModel> " %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Customer Sites
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var customerSite in Model.CustomerSites) { %>
<% Html.RenderPartial("CustomerSiteSummary", customerSite); %>
<%} %>
</asp:Content>
This is the viewmodel, notice i am including a Customer member in the viewmodel as i want to display the customer name in addition to the list of customer sites
namespace CustomerDatabase.WebUI.Models
{
public class CustomerSitesListViewModel
{
public IList<CustomerSite> CustomerSites { get; set; }
public PagingInfo PagingInfo { get; set; }
public Customer customer { get; set; }
}
}
This is my controller code for the view
public ViewResult List([DefaultValue(1)] int page)
{
var customerSitesToShow = customerSiteRepository.CustomerSites;
var viewModel = new CustomerSitesListViewModel
{
CustomerSites = customerSitesToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = customerSitesToShow.Count()
}
};
return View(viewModel); //Passed to view as ViewData.Model (or simply model)
}
This is my partial view that renders the list,
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CustomerDatabase.Domain.Entities.CustomerSite>" %>
<div class="item">
<div class="customer-list-item">
<h2><%:Model.customer.CustomerName%></h2>
<%: Model.AddressLine1 %>
<%: Model.AddressLine2%>
Although intellisense lets me access the customer object from the view with
<h2><%:Model.customer.CustomerName%></h2>
An error is thrown when i navigate to the view,
Object reference not set to an instance of an object.
Source Error:
Line 7: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
Line 8: <% foreach (var customerSite in Model.CustomerSites) { %>
Line 9: <%:Model.customer.CustomerName%>
Line 10: <% Html.RenderPartial("CustomerSiteSummary", customerSite); %>
Line 11: <%}
I think the error is due to the view rendering a list, i tried changing the viewmodel member to
public IList<Customer> {get; set;}
but this doesn't work either.
Can anyone suggest a way i can achieve this or offer any advice on where i am going wrong this is one problem i haven't been able to resolve after hours or researching on the Internet?
It looks like one of the model properties are not initialized. If you add a breakpoint on that line and check the variables I'm pretty sure you'll find 1 that is null.

strongly-typed partial views MVC RC1

having a problem passing ViewData.Model to the partial views. It always is defaulting to null even if I equate it to a result query. I cannot access the strongly typed data because the Model is null. My current code is this,
ViewPage
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("header", this.ViewData.Model); %>
<% Html.RenderPartial("test", this.ViewData.Model); %>
<div id="userControls">
</div>
</asp:Content>
UserControl - header
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<testMVCProject.Models.information>" %>
<h2>
ACReport</h2>
<p>
id:
<%= Html.Encode(Model.id) %>
</p>
<p>
type:
<%= Html.Encode(Model.type) %>
</p>
UserControl - test
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<testMVCProject.Models.information>" %>
<% using (Ajax.BeginForm(
"pressureV2",
"Home",
new { id = ViewData.Model.id },
new AjaxOptions
{
UpdateTargetId = "userControls",
HttpMethod = "GET"
},
new { #id = "genInfoLinkForm" }))
{%>
<%= Html.SubmitButton("hey", "Lol") %>
<%} %>
Controller
public ActionResult header(int id)
{
var headerResults = from c in db.information
where c.id == id
select new information
{
id = c.id,
type = c.type
};
ViewData.Model = headerResults.FirstOrDefault();
return View(ViewData.Model);
}
public ActionResult pressureV2(int id)
{
var pressureVResults = from c in db.pressure_volume_tests
where c.id == id
select new pressureVT
{
bottomCVP = c.bottom_CVP,
topCVP = c.top_CVP
};
ViewData.Model = pressureVResults.FirstOrDefault();
return View(ViewData.Model);
}
In the comments you have said that the view is not strongly typed. Because of that:
<% Html.RenderPartial("header", this.ViewData.Model); %>
<% Html.RenderPartial("test", this.ViewData.Model); %>
will not work. If you strongly type your view to testMVCProject.Models.information and then pass an instance of that type from your constructor it will work.
Controller:
public ActionResult ShowAView()
{
Return View("WhateverYourViewIsCalled", new information());
}
You have a misunderstanding of the use of Html.RenderPartial helper.
When you use the RenderPartial you will show the view without requesting the model from the controller.
So you have to refactor your ViewPage and pass the good Model to your usercontrols:
Exemple:
Controller:
ActionResult MainView()
{
var mainviewobj = new MainViewObject();
var headerResults = from c in db.information
where c.id == id
select new information
{
id = c.id,
type = c.type
};
mainviewobj.info = headerResults.FirstOrDefault();
return view(mainviewobj);
}
View Code:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("header", this.ViewData.Model.info); %>
<% Html.RenderPartial("test", this.ViewData.Model.info); %>
<div id="userControls">
</div>
</asp:Content>
View Code Behind
public partial class MainView : ViewPage<MainViewObject>
{
}
Now the Model will not be null in your usercontrol.
But remember the usercontrol rendering partially dun execute the code in the controller
So you dun need the public ActionResult header(int id) in your Controller
Hope this helps.
Have you tried making the ViewPage generic as well?
The Controller doesn't get called when you RenderPartial - it is bypassed and the view is rendered directly. So whatever you want to pass in as a model needs to be done from the calling View.
I found this worked for me, reference the partial as you do, like so.
...form
#Html.Partial("_AboutYou", Model.AboutYou);
..end form
within the partial view at the top...
#model <namespace1>.<namespace2>.<namespace3>.CustomerInfo.AboutYou
#{
ViewData.TemplateInfo.HtmlFieldPrefix = "AboutYou";
if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}
}
I believe the problem might be that you're missing an element in the form with the name "id" so the parameter of the Action method is never populated with a value?
That way the query would always return null with the FirstOrDefault, hence the null Model.
Just my guess...

Resources