strongly-typed partial views MVC RC1 - asp.net-mvc

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...

Related

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);

partial view error

I have moved following code from my view to partial view and getting error
My view code is:
function renderSeason() {
$('#visSeasonbut').click(function() { $('#p2').load(this.href); return false; });
}
function renderGame() {
$('#visGamebut').click(function() { $('#p2').load(this.href); return false; });
}
<div id="game">
<%= Html.ActionLink("Game 1", "PitcherTitles", "Test", null, new { id = "visGamebut" })%> </div>
LiveGame.Models.Baseball.Player visPlayer1 = ViewData.Model.GetCurrentTeamPlayer(false);
if (visPlayer1 != null)
{
LiveGame.Models.Baseball.Player rosterPlayer = ViewData.Model.GetTeam(0).RosterDictProp.GetPlayer(visPlayer1.Player_IdProp);
if (ViewData.Model.InningHalfProp == true)
{ %>
show Pitcher Stats here
<%
}
else
{
%>
Show PitchTitles here
<%
}
}
and partial views are like this :
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
Wins
Losses
ERA
second one is :
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
IP
H
R
ER
BB
SO
HR
ERA
When I click links, I get error , "rosterPlayer" not found, Please suggest solution. Thanks
When you render this partial make sure you are passing a model:
<% Html.RenderPartial("SomePartialName", Model); %>
And of course don't forget to strongly type your partial to the model:
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.SomeModelType>"
%>
Also from the comment you posted it looks like you aren't passing any model to your views. So change this and ensure a model is passed or you cannot use the Model property:
public ActionResult PitcherStats()
{
Game currentGame = new Game();
return View(currentGame);
}
public ActionResult PitchTitles()
{
Game currentGame = new Game();
return View(currentGame);
}

UserControl-like behavior in ASP.NET mvc

Decided to learn ASP.NET MVC and instantly got stuck on something simple.
In Web Forms user controls allowed to separate application into components based on functionality and facilitated reuse. It seems partial views are supposed to do something similar in ASP.NET MVC, but either I am getting this wrong, or each visible page is handled by single controller and it is not possible to delegate certain page portions to separate controllers without hard-coding these controller relationships.
RenderAction can render a partial view and insert resulting HTML in the page, but if we want this view to be refreshed when the user clicks on some link within this view together with the entire page, we need all the partial view links to refer to the parent controller?
For example:
Home\Index.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Home</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
...
<% Html.RenderAction("Index", "Posts"); %>
...
Posts\Index.aspx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BlogEngine.Models.PostsViewModel>" %>
<% foreach(var item in Model.Posts){ %>
<p class="postMeta"><%: string.Format("{0} {1}", item.CreatedAt, item.CreatedBy) %></p>
<h1><%: item.Title %></h1>
<div><%: item.Content %></div>
<% } %>
<% if (Model.CurrentPage > 0){ %>
<%: Html.ActionLink("Newer posts", "Index", "Home", new { page=Model.CurrentPage - 1}, null) %>
<%} %>
<% if (Model.CurrentPage + 1 < Model.TotalPages) { %>
<%: Html.ActionLink("Older posts", "Index", "Home", new { page=Model.CurrentPage + 1}, null) %>
<% } %>
PostsController:
public class PostsController : Controller
{
private const int PostsPerPage = 2;
private readonly IPostRepository _postRepository;
public PostsController()
{
...
}
public ActionResult Index(int page = 0)
{
var model = new PostsViewModel();
int totalPages = 1;
model.CurrentPage = page;
model.Posts = _postRepository.GetPosts(page, PostsPerPage, out totalPages);
model.TotalPages = totalPages;
return PartialView(model);
}
}
There's got to be a better way than this?
I don't know if I understand correctly but you could load this Partial View in a using Ajax (by jQuery), and when you need to refresh only this part of content you reload the element. Something like this:
In Javascript:
function LoadComments(page) {
//It'll return a partial view
$("#comments").load("<%=Url.Action("Posts", "Index")%>?page=" + page);
}
$(document).ready(function() {
LoadComments(0);
});
Inside of yoru PartialView you need to render a javascript code to call the "reload" of the next (page) content, so call LoadComments(index-page)...
Look the Ajax APi of jQuery: http://api.jquery.com/category/ajax/
Cheers

ASP.Net MVC Ajax RenderPartial not rendering correctly

I have an AJAX form which returns a partial view, but instead of the target div getting updated, when I submit, only the partial view is shown. As far as I can tell, I have everything set up the way it's supposed to be, what's going wrong?
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ApplianceSurvey.Models.Item>" %>
<% using (Ajax.BeginForm("AddSurveysAJAX",
new AjaxOptions { UpdateTargetId = "SurveyListContent", InsertionMode = InsertionMode.Replace }))
{ %>
<%= Html.Hidden("itemID", Model == null ? ViewData["itemID"] : Model.ItemID) %>
<%= Html.ListBox("SurveysLst", ViewData["Surveys"] as MultiSelectList)%>
<input type="submit" value=">>>" />
<%= Html.ListBox("SelSurveysLst", ViewData["ItemSurveys"] as MultiSelectList)%>
<% } %>
and in the controller:
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult AddSurveysAJAX(FormCollection formValues)
{
//do stuff
return PartialView("ItemSurveys");
}

ASP.NET MVC best approach to provide data to Views

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.

Resources