Hi i have just started MVC 4 in c#, i am having issue in rendering partial view.
i have created model for the partial view and controller action in which i am just
sending a single string for the testing reasons but when i try to render it.
it just show the following error.
[NullReferenceException: Object reference not set to an instance of an object.]
here is my controller class.
enter code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using my_photos.Models;
namespace my_photos.Controllers
{
public class DefaultController : Controller
{
public ActionResult Index()
{
ViewBag.Massage = "Hello Word";
return View();
}
public ActionResult About() {
ViewBag.Message = "About Page";
return View();
}
public ActionResult _RightView() {
var model = new my_photos.Models.partial(){
Winner = "Shafee Jan"
};
//ViewData["name"] = model;
return View(model);
}
}
here is model class for partial view
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace my_photos.Models
{
public class partial
{
public string Winner { get; set; }
}
}
here my partial view
#model my_photos.Models.partial
<div class="body">
<div class="content">
<div class="header">
<h1 class="nav-heading">Data</h1>
<p class="paragraph" > Winner :#Model.Winner.ToString() </p>
</div>
</div>
<div class="bottom">
<div class="header">
</div>
</div>
</div>
and here is my main layout in shared folder
#model my_photos.Models.partial
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>_Layout</title>
<link href="#Url.Content("~/Content/Style/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/Style/Side_barnav.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<header>
<h3> Photos app</h3>
<p> In this app my major concerns are with the <strong>theaming</strong>!</p>
<div class="nav">
<ul class="main-menu">
<li>#Html.ActionLink("Home","Index", "Default")</li>
<li>#Html.ActionLink("About","About", "Default")</li>
<li>#Html.ActionLink("Contact","Contact", "Default")</li>
</ul>
</div>
</header>
<section>
#RenderBody()
#Html.Partial("~/Views/Shared/_partial.cshtml")
</section>
<footer>
<div class="fotter-menu">
<ul>
<li>#Html.ActionLink("Home","Index","Default")</li>
<li>#Html.ActionLink("About","About","Default")</li>
<li>#Html.ActionLink("Contact","Contact","Default")</li>
</ul>
<ul>
<li>#Html.ActionLink("Resources","Resources","Default")</li>
<li>#Html.ActionLink("Testimonial","Testimonial","Default")</li>
<li>#Html.ActionLink("Team","Team","Default")</li>
</ul>
<ul>
<li>#Html.ActionLink("Home","Index","Default")</li>
<li>#Html.ActionLink("Home","Index","Default")</li>
<li>#Html.ActionLink("Home","Index","Default")</li>
</ul>
</div>
</footer>
</body>
</html>
when ever i try to get value form the model it give me the following error.
kindly help me through this.
[NullReferenceException: Object reference not set to an instance of an object.]
This is happening because your model is null, as you can see, in actions About and Index there is no model being passed. Also partial is a keyword in C#, it will be better to have a more signifiant name.
To solve this you have to pass a model to every view that uses that layout that is expecting this model. In your case is null and an error is thrown.
public ActionResult Index()
{
ViewBag.Massage = "Hello Word";
var model = new my_photos.Models.partial(){
Winner = "Shafee Jan"
};
return View(model);
}
It is necesary to pass the model because on the below line of code the partial is rendered by default with the current view model.
#Html.Partial("_partial.cshtml", Model) #* Model is passed by default if there is no other parameter specified *#
I think what you really want to do is to call the _RightView action in your layout.
#Html.Action("_RightView", "Default")
Don't forget to modify the action to return a partial view and the passing of model in the other actions won't be necessary
public ActionResult _RightView() {
var model = new my_photos.Models.partial(){
Winner = "Shafee Jan"
};
//ViewData["name"] = model;
return PartialView("_partial", model);
}
hey this is not a big problem you are giving partial class reference to both layout and partial view.
so if you are access a _RightView Action it does't thrown a error because you are passing a object to view properly but when comes it partial view you are not passing object reference so just pass the model in
#Html.Partial("~/Views/Shared/_partial.cshtml",Model)
That's it
Related
I checked all the solutions but still doesnt work.I got a partial view page in layout page and When ı run only partial page it works but when ı run another page with layout it doesnt work.
I hope you can help me
Here is my Model :
public CheckListType CheckListType { get; set; }
public IEnumerable<SelectListItem> CheckListTypeList1 { get; set; }
And my Controller :
public ActionResult ListCheckListType()
{
ControlListTypeModel listTypeModel = new ControlListTypeModel();
List<SelectListItem> CheckListTypeList = new List<SelectListItem();
foreach (CheckListType item in checklisttypeRepository.List().ProcessResult)
{
CheckListTypeList.Add(new SelectListItem { Value = item.CheckListTypeId.ToString(), Text = item.CheckListType1 });
}
listTypeModel.CheckListTypeList1 = CheckListTypeList;
return PartialView("~/Areas/User/Views/CheckList/ListCheckListType.cshtml", listTypeModel);
}
View :
#using TodoListApp.Areas.User.Models.ViewModel
#model ControlListTypeModel
<form action="/CheckList/ListCheckListType" method="get">
<div>
CheckListType :
</div>
<div>
#Html.DropDownListFor(modelitem=>modelitem.CheckListType.CheckListTypeId,Model.CheckListTypeList1)
<button type="button" class="butt button bg-info" style="height:40px; width:98px;">Choose CheckListType</button>
</div>
Layout :
<div class="container body-content">
#Html.Action("ListCheckListType");
#RenderBody(){
}
<hr />
<footer>
<p> #DateTime.Now.Year </p>
</footer>
</div>
HttpException: A public action method 'ListCheckListType' was not found on controller
The problem occurs because it searches ListCheckListType action in wrong controller while rendered in partial view. Specifying controller name as well should fix the exception
#Html.Action("ListCheckListType", "Home"); //if action is in HomeController
I have a asp.net mvc application. One of it's controller calls an aspx page instead of normal razor view page. I followed this https://www.hanselman.com/blog/MixingRazorViewsAndWebFormsMasterPagesWithASPNETMVC3.aspx
Now the problem is I need to send some data from my controller to that aspx page which I can't do using Viewbag.
Any idea how can I send data from my regular controller to my aspx page?
Passing data using model to view(aspx engine) from controller:
Model:
public class Product
{
public string ProductID { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public int Price {get; set;}
}
Controller:
public ActionResult Index()
{
List<Product> productLst = new List<Product>{
new Product{ProductID="P01",ProductName="Pen",Quantity=10,Price=12},
new Product{ProductID="P02",ProductName="Copy",Quantity=12,Price=20},
new Product{ProductID="P03",ProductName="Pencil",Quantity=15,Price=22},
new Product{ProductID="P04",ProductName="Eraser",Quantity=20,Price=27}
ViewData["Message"] = "Your message comes here";
return View();
}
ASPX View:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<Product>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Index</title>
</head>
<body>
<div>
<h3>Passing Data From Controller To View using ViewData</h3>
<h3><%= Html.Encode(ViewData["Message"]) %></h3>
<%foreach (var item in Model)
{ %>
<p><%=item.ProductID %></p>
<p><%=item.ProductName %></p>
<p><%=item.Quantity %></p>
<p><%=item.Price %></p>
<%} %>
</div>
</body>
</html>
References for model binding in aspx engine,
https://www.codeproject.com/Articles/391289/Implementing-ASP-NET-MVC-Views-in-three-different
https://weblogs.asp.net/gunnarpeipman/asp-net-mvc-3-using-multiple-view-engines-in-same-project
Assign dynamic HTML attribute for any HTML tags:
<input checked="#isRazor" type="checkbox"><!-- Razor engine -->
<input checked="<%:isASPX%>" type="checkbox"><!-- ASPX engine -->
You can do more mixing of HTML tags with Razor and ASPX View Engine, Following code block shows how you can do that.
Your Sample Html Code or Text #RazorCode (#AnotherRazorCode)
Your Sample Html Code or Text <%: ASPXCode %> (<%:AnotherASPXCode %>)
Instead of that, You can go with creating your own Custom Model to passing the data from Controller to View.
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<YourModel>" %>
<% foreach(var item in Model) { %>
<tr>
<td><%: item.Name %></td>
</tr>
Have you tried passing it through ViewData, like so?
in the action: ViewData["myvar"] = "realvalue";
in the view: string parl = ViewData["myvar"];
NOTE: Alternatively you can use Session like this example:
in MVC action:
Session["UserName"] = "Test";
in WebForms:
string UserName = (string)Session["UserName"];
That is all!
In ASP.NET web forms it is possible to modify page controls from the master page. For example, on a page "/Sample" I could set TextBox1 as readonly by doing the following.
//Site.master.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Path.ToUpper().Contains("/SAMPLE"))
{
TextBox TB = MainContent.FindControl("TextBox1") as TextBox;
TB.ReadOnly = true;
}
}
The question is... Is there an equivalent way to do this in an MVC application that uses a SiteLayout?
Background: We have purchased an MVC application and have access to modify the
source code. We need to customize the behaviors on some of the pages. It
will only be used by a few dozen people so a performance hit won't really be noticeable. If this was a Web Forms
application we would use the above method. However this application
is written with MVC and it is making our web form programmer (me) confused on how best to proceed. Customizing numerous pages is going to be a headache when
we have to patch the software. Having all the changes in one central location
would be easier to manage going forward. How can you have one place where you can customize other pages programmatically in MVC?
There is no MVC equivalent for FindControl, since views are built in a single operation, where ASP.NET controls are built up and modified over several different events. You don't need to find the control, you specify all of its attributes as it is built.
The rough equivalent to an ASP.NET control (at least in this context) is an HTML helper. HTML helpers are implemented as static extension methods, which allows them to be shared between views and perform some actions as the view is loaded.
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class MyExtensions
{
public static MvcHtmlString TextBox1(this HtmlHelper helper, string name)
{
if (helper.ViewContext.HttpContext.Request.Path.ToUpper().Contains("/SAMPLE"))
{
return InputExtensions.TextBox(helper, name, null, new { #readonly = "readonly" });
}
return InputExtensions.TextBox(helper, name);
}
}
Usage
~/Views/Shared/_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title - My ASP.NET MVC Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">#Html.ActionLink("your logo here", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
#Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#* Render custom HTML Helper *#
#Html.TextBox1("test")
#RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© #DateTime.Now.Year - My ASP.NET MVC Application</p>
</div>
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
Note that it is also possible to put the logic directly in the view, but then you cannot reuse logic in other views and it makes your view look cluttered.
As for reading the data back out of a textbox, you need to put it within a <form> tag so it can be posted to a controller action method, which is the rough equivalent of a submit button click event. Unlike ASP.NET, MVC supports multiple <form> tags so you don't have to mix your logic for different actions on the page.
Your question is very broad. But generally, if you want to provide read only rendering for your controls in your razor views based on some conditions, you can try the below approach.
You should add a IsReadOnly property to your view model and use that to render the control the way you wanted.
public class CreateCustomerVM
{
public bool IsReadOnly {set;get;}
//Other properties goes here
public string Email { set; get; }
public string Name { set; get; }
}
In your Action method set the IsReadOnly propery value based on your condition.
public ActionResult Index()
{
var vm=new CreateCustomerVM();
//Set the value based on your condition
vm.IsReadOnly=true;
return View(vm);
}
And in your view , you use the IsReadOnly property to determine whether you want to display a readonly control or not.
#model YourNameSpaceGoesHere.CreateCustomerVM
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Email)
if(Model.IsReadOnly)
{
#Html.TextBoxFor(m => m.Name, new { #readonly = "readonly" })
}
else
{
#Html.TextBoxFor(m => m.Name)
}
<input type="submit"/>
}
I am manually adding the following Model Error in my controller,
ModelState.AddModelError(string.Empty, "An error occurred");
However when the view is loaded, the #Html.ValidationSummary(true) is not showing any errors.
I have also tried #Html.ValidationSummary(false).
I have read many articles on this behavior and I have tried all the suggestions with no luck.
Any suggestions are greatly appreciated!
I can see it work. See the sample here: http://dotnetfiddle.net/Jz7wQj
Beware when using custom ViewData objects.
Problem Reproduced
Model
using System.ComponentModel.DataAnnotations;
namespace BrokenValidationSummaryTest.Models
{
public class MyModel
{
[Required]
public string Whatever { get; set; }
}
}
Controller
using BrokenValidationSummaryTest.Models;
using System.Web.Mvc;
namespace BrokenValidationSummaryTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Submit(MyModel postedData)
{
return View(viewName: "Index", model: postedData);
}
}
}
View "Index"
#model BrokenValidationSummaryTest.Models.MyModel
<ul class="nav nav-tabs" id="carrier-tabs">
<li class="active">
<a data-toggle="tab" href="#search" class="tab-level-1" data-tab-name="search">Search</a>
</li>
</ul>
<div class="tab-content">
<div id="search" class="tab-pane fade in active">
#Html.Partial(partialViewName: "TabBody", model: Model, viewData: new ViewDataDictionary())
</div>
</div>
View "TabBody"
#model BrokenValidationSummaryTest.Models.MyModel
#Html.ValidationSummary(excludePropertyErrors: false)
<h2>TabBody</h2>
#using (Html.BeginForm(actionName: "Submit", controllerName: "Home", method: FormMethod.Post))
{
<div>Whatever:</div>
<div>#Html.TextBoxFor(x=>x.Whatever)</div>
<input type="submit" value="Submit">
}
Explanation
The partial view has the ValidationSummary HTML helper. We pass a custom ViewData object to the partial view. This custom ViewData object passed to the partial view does not contain the ViewState found in the view 'Index'. The HTML helper ValidationSummary does not have enough required information to render the error messages properly.
Recommendation: if using custom ViewData, populate the custom ViewData with the ViewState of the parent view.
I am trying to get my clienside validation to work when using an ajax request in a jquery ui dialog.
This means I have no submit button and I do no post back. I could not figure out why I could not get it to work.
I posted this question . I been playing around with it can come to the conclusion is that for whatever reason I need to load up the jquery.validate.unobtrusive with my partial view. It makes no sense to me.
Is this a bug?
Edit
I also gone and posted the error on the asp.net codeplex
The added benefit to this is that if you wish you can just download my little sample application and try it out.
Or you can Follow these steps
Make an non empty asp.net mvc 3 application( I am using razor)
_Layout.cshtml
#ViewBag.Title
<script type="text/javascript">
$(function ()
{
$.get('/home/dialog', null, function (r)
{
var a = $("#dialog").dialog({
resizable: false,
height: 500,
modal: true,
buttons: {
"Delete all items": function ()
{
$('#testFrm').validate().form();
},
Cancel: function ()
{
$(this).dialog("close");
}
}
}).html(r);
});
$('#testFrm').live('submit',function (e)
{
e.preventDefault();
});
});
</script>
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
#Html.Partial("_LogOnPartial")
</div>
<div id="menucontainer">
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
</ul>
</div>
</div>
<div id="main">
#RenderBody()
<div id="footer">
</div>
</div>
</div>
</body>
</html>
ViewUserControl1 (Partial View) - Stick in Home View folder
#model MvcApplication1.Models.TestModel
#using (Html.BeginForm("test","Account",FormMethod.Post,new {#id="testFrm"}))
{
#Html.ValidationSummary()
#Html.TextBoxFor(x => x.Name)
}
Index (should exist replace with this)
#model MvcApplication1.Models.TestModel
#{
ViewBag.Title = "Home Page";
}
<h2>#ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit http://asp.net/mvc.
</p>
#DateTime.Now
<div id="dialog">
</div>
note the dialog id this will be where the ajax request of the partial view gets stored
Home Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult test()
{
return null;
}
public PartialViewResult Dialog()
{
return PartialView("ViewUserControl1");
}
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
}
}
TestModel.cs // view model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
public class TestModel
{
[Required()]
public string Name { get; set; }
}
}
web.config
<appSettings>
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Now run the application. Click "Delete all items" and "Submit Query".
Nothing should happen. No validation pops up for me.
Now go and add this line to the Partial View(ViewUserControl1)
<script src="../../Scripts/jquery.validate.unobtrusive.js" type="text/javascript"></script>
#model MvcApplication1.Models.TestModel
#using (Html.BeginForm("test","Account",FormMethod.Post,new {#id="testFrm"}))
{
#Html.ValidationSummary()
#Html.TextBoxFor(x => x.Name)
<input type="submit" />
}
Now try again.
It should now come up with validation errors.
I think I found some sort of a work around. Even though I think a automatic way should be done for something so basic as making the validation work with partial views
Work around
This is not a bug. When you load a PartialView using Ajax, you must then parse the unobtrusive validation attributes included in the new elements you are loading.
See http://forums.asp.net/t/1651961.aspx/1?Unobtrusive+validation+not+working+on+form+loaded+by+Ajax