Error in RenderPartial in loop asp.net mvc - asp.net

I am trying to render multiple Views using a loop like this
#model IEnumerable<RamtaJogi.Web.Razor.Controllers.IMenuRenderer>
#foreach (var item in #Model)
{
{#Html.RenderPartial(#item.ViewName, #item.ViewData);}
<br />
}
here is my IRenderer
public interface IMenuRenderer
{
string ViewName { get; }
object ViewData { get; }
}
But it throws an error CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
I pass a collection of objects of type IMenuRenderer to my view.
Any idea what is wrong with my codes. Can someone help here.
Regards
Parminder

You have too many # characters.
You should only use #s to enter the foreach.
Since RenderPartial returns void, you cannot print its result with an #.
Parameters also never get #s.
Change your code to
#model IEnumerable<RamtaJogi.Web.Razor.Controllers.IMenuRenderer>
#foreach (var item in Model)
{
#Html.Partial(item.ViewName, item.ViewData)
<br />
}

You can create a custom helper.I think this will help you. ASP.NET MVC: Custom Html Helpers in Razor

Related

how to insert partial view from another controller in asp.net mvc 5

I want to insert a partial view from NewsController into HomeController.
In my NewsController
public ActionResult LastNewsPatial()
{
var lstLastNews = db.Articles.Take(5).OrderByDescending(m => m.CreatedDate).ToList();
return PartialView(lstLastNews);
}
In Views/News folder i create LastNewsPatial.cshtml
#model IEnumerable<mytest.com.Models.Article>
#foreach (var item in Model) {
<div class="glidecontent">
<img src="#item.ImageURL" style="float: left; margin-right:21px;" />
<strong>#item.Title</strong><br /><br />
#item.Content
</div>
}
In Views/Home/Index.cshtml i insert a LastNewsPatial view
#Html.Partial("~/Views/News/LastNewsPatial.cshtml")
When i run my project then I received a error
Object reference not set to an instance of an object.
at row
#foreach (var item in Model)
in LastNewsPatial.cshtml
How can I fix it?
The reason for your error is that the Model isn't passed to the view... infact the action isn't even called at all. Set a breakpoint and you'll confirm this.
I think you should be calling #Html.RenderAction inside the index instead of #Html.Partial.
Instead of #Html.Partial("~/Views/News/LastNewsPatial.cshtml")
use
#Html.RenderAction("LastNewsPatial","News")
or #Html.Action("LastNewsPatial","News")
You don't need to give .cshtml in name of view when rendering a view. Only give name of PartialView without .cshtml like this.
#Html.Partial("~/Views/Shared/LastNewsPatial")
You can also use #Html.Action() to render your view like this
#Html.Action("LastNewsPatial","News")
This worked for me: #Html.Partial("../Views/Shared/LastNewsPatial")
The .. instead of the ~
Some of the answers here are missing the question
You use this
#Html.Partial("~/Views/News/LastNewsPatial.cshtml")
Which creates a partial view without a model. So in order for this to work you need to pass model.
#Html.Partial("~/Views/News/LastNewsPatial.cshtml", your_model)
Your problem is not view related and you simply pass no object to the partial. How to do it is up to you. Do you want a Html.Partial or Html.Action? Depending on your needs.
P.S.
Use RenderPartial and RederAction they are better practices since Partial and Action return an HTML string where instead using render allows ASP.NET to write directly to the response stream.

Getting values of check-box from formcollection in asp.net mvc

I viewed some topics here but I still have a problem with getting values from checkboxes.
Part of Model :
public Dictionary<Language, bool> TargetLanguages { get; set; }
Part of View :
<div class="editor-label">
<label for="TargetLanguages">select target languages</label>
</div>
<div class="editor-field">
<form>
#foreach (var item in Model.TargetLanguages)
{
#Html.CheckBox("TargetLanguages["+item.Key.Name+"]", item.Value)
#item.Key.Name
}
</form>
</div>
Part of Controller :
[HttpPost, ActionName("AddDictionary")]
public ActionResult AddDictionary(FormCollection collection)
{
...
}
And the problem is I don't get any trace of TargetLanguages in my FormCollection. I tried CheckBoxFor but it wasn't help. I tried write check-box manually also.
EDITED : Okay, I just noticed where the problem was. I've got messed up markers and that was the reason why I can't get data from FormCollection.
Create all the checkboxes with the same name. In this sample I'm using 'SelectedTargetLanguages'.
#using (Html.BeginForm())
{
foreach (var item in Model.TargetLanguages)
{
<label>
#Html.CheckBoxFor(m => m.SelectedTargetLanguages, item.value)
#item.KeyName
</label>
}
<br/>
#Html.SubmitButton("Actualizar listado")
}
Then, in your action the parameter must be an array of strings like this:
public ActionResult AddDictionary(string[] selectedTargetLanguages)
Note that the name of the argument is the same name of the checkboxes. (It works even with the different casing).
You should use explicit arguments like this, rather than the generic FormCollection. Anyway, if you use FormCollection, you shpuld also receive the array.
I have asked same type of question previously. Please check the following links
MVC3 #Html.RadioButtonfor Pass data from view to controller
MVC3 #html.radiobuttonfor
I think this might helps you.

How can I run code from my layout file?

I used the following tutorial to help me build an RSS Reader in my ASP.NET MVC3 Razor application:
http://weblogs.asp.net/jalpeshpvadgama/archive/2011/08/17/creating-basic-rss-reader-in-asp-net-mvc-3.aspx
However, unlike the tutorial example, I want the RSS feed to be displayed on every page, and have therefore added it to my layout file, /Views/Shared/_Layout.cshtml
I currently only have 2 views on my site, and to get the RSS Reader to work on both views I've got the following code in my HomeController:
public class HomeController : Controller
{
//
// GET: /Index/
public ActionResult Index()
{
return View(CT.Models.RssReader.GetRssFeed());
}
public ActionResult About()
{
return View(CT.Models.RssReader.GetRssFeed());
}
}
From my WebForms experience, I would simply add the RSS Reader code in my master page code behind, and it would automatically work on every page.
Is there a Controller for layout pages which allows me to do the same?
How can I get this to work on every call of the layout page, without having to return anything?
EDIT: Following #Sebastian's advice, I've now added this code to a Partial View, removed CT.Models.RssReader.GetRssFeed() from return View() and included this in my layout file:
#Html.Partial("_MyPartialView")
The code in this partial view is:
<ul>
#foreach (var item in Model)
{
<li>
#item.Title
</li>
}
</ul>
However, I'm not getting a runtime error:
Object reference not set to an instance of an object.
It's erroring on the line #foreach (var item in Model)
You have to create a partial view and add functionality there.
Then in your layout, render this partial.
EDIT
Is your partial view really a partial view? The reason I said that is because you have "_" in front of the name which suggests that it might be a layout (might just be a naming convention).
To fix object reference error, you have to add the #Model declaration on top of your partial view.
Hope it helps.
UPDATE
In order to use different model in partial view, you need to explicitly declare which model you are going to use on render partialmethod.
#{Html.RenderPartial("../YourFeed", Model.YourFeedModel);}
Let me know if that resolved your issue.
The new error you are having is due to you not passing a Model to the partial view. You can do this with the second argument of the Html.Partial function...
Html.Partial("ViewName", MyModel);
As I think you are trying to do this in a Layout page you could also consider using a static reference to get your RSS feed. So forget about needing to pass in a Model and in your partial have:
#foreach (var item in RssRepository.GetFeed())
{
<li>
#item.Title
</li>
}
this like to a class something like...
public static RssRepository
{
public static MyModel GetFeed()
{
return new MyModel();//<- return what you would normally pass as a Model for RSS feeds
}
}
Hope that all makes sense

Passing Querystring data to a Model in ASP.NET MVC 2

I have a strongly typed view inheriting from a POCO class. I want to initialize the property of a model with a Querystring value at the time when view loads.
On the View Load I am using ViewData to the save the code :
public ActionResult Data() {
ViewData["QueryStringValue"] = this.Request.QueryString["Param1"]
return View();
}
In the HTML markup, I am using this code to initialize the model property in a hidden variable
<%:Html.HiddenFor(m=>m.Param,
Convert.ToInt32(Html.Encode(ViewData["QueryStringValue"]))) %>
m.param is a byte type.
URL of the request is somewhat like this : http://TestApp/Data/AddData?Param1=One
On View Save event, I am using model binding but issue is that I don't get to see the value of param initialized in the controller. It is always NULL.
My Save Event maps to a controller :
[HttpPost]
public ActionResult SaveData(MyData d)
{
string paramValue = d.Param; //this always returns null
BO.Save(d);
}
I inspected the HTML source and saw that the value of the hidden field itself is blank. Not sure why this is happening since the below code works and shows the param value in a heading element
<h2> <%=Html.Encode(ViewData["QueryStringValue"]) %> </h2>
I have no idea where I am going wrong on this.
I think, Instead of Passing the Querystring value in ViewData, You should set it as the Property value of your ViewModel/ Model and pass that to your View.
public ActionResult Data()
{
YourViewModel objVm=new YourViewModel();
objVm.Param=Request.QueryString["Param1"];
return View(objVm);
}
Now in your Strongly typed View, use it like this
#model YourViewModel
#using(Html.BeginForm())
{
#html.HiddenFor(#m=>m.Param);
<input type="submit" value="Save" />
}
Now Param value will be available in yout HttpPost action method
[HttpPost]
public ActionResult Data(YourViewModel objVm)
{
string param=objVm.Param;
//Do whatever you want with param
}
Just made this work, Issue is with this line:
<%:Html.HiddenFor(m=>m.Param,
Convert.ToInt32(Html.Encode(ViewData["QueryStringValue"]))) %>. I stated in the question that m.Param is of type byte. I figured out that issue was with casting.
I tried this code and it worked
<%:Html.HiddenFor(m => m.Param, (byte)Convert.ToInt16(this.Request.QueryString["Param1"].ToString()))%>

HTML.Partial - MVC 3 Razor

I have problem with returning a partial view from a controller with different model than my main View. For example:
public ActionResult Index()
{
//myModel - get Some Types
return View(mymodel);
}
public PartialViewResult Categories()
{
//my another Model - get different Types
return PartialView(myanothermodel);
}
And then in Index View:
#Html.RenderPartial("Categories")
I get an exception saying that it is of the wrong type. It expects first type(mymodel) instead of second type.
Is it possible to return different types for view and its partial view?
Thanks for response.
It looks like you're trying to render the action, not the view.
Call #Html.Action("Categories").
When you are using Partial View only use
#Html.Partial("Categories", Model)
or a especific Model with your own data
#Html.Partial("Categories", Model.Category)
I just understood a bit how partial view works. In your and my case actually, no need to define the Categories() action if you think the logic to get myanothermodel can be done in Index() action.
So I have mymodel.myanothermodel assigned in the Index() action and then in the strongly typed Index.cshtml I used this: (assume myanothermodel is Categories)
#{Html.RenderPartial("Categories", Model.Categories);}
alternatively:
#Html.Partial("Categories", Model.Categories)
Note that always use .RenderPartial() rather than .Partial() for best performance in .cshtml view. I used Model.Categories instead of mymodel.Categories because of the strongly typed Index.cshtml already have #model mymodel in the begining of the file.
In my practise I have the models like:
Model.Departments - IList<DepartmentModel>
Model.SelectedDepartment - DepartmentModel
Model.Employees - IList<EmployeeModel>
which is used in:
#{Html.RenderPartial("DepartmentMenu", Model.Departments);}
<div id="employeeViewContainner">
#foreach (var emp in Model.Employees)
{
Html.RenderPartial("CardView" + Model.SelectedDepartments.Name, emp);
}
</div>
This will render employee list with different skin for different department.

Resources