pass viewModel object from controller to view in asp.net MVC - asp.net-mvc

I have the following method in controller
public ActionResult Categorized()
{
var x=new Test.Models.MobileClass();
return View(x);
}
x object contains methods that return xmldocument data
how can I pass this object to view to access methods and display data from xmldocument in browser
I can display it element element by using the following code
document.writeln("#Model.getxml().ChildNodes.Count");
but I want to use for loop displaying the contents of object and the following code didn't work in javascript
var size=parseInt("#Model.Getxml().ChildNodes.Count");
for (var i=0; i<size; i++)
{
document.writeln("#Model.Getxml().ChildNodes[i].InnerText");
}
can you help me please

First of all, your view should not be calling Getxml and mucking about with the XML DOM. It's the job of the controller to present the view with "ready to render" data. That's what a ViewModel is for.
public ActionResult Categorized()
{
var foo = new Test.Models.MobileClass();
var xml = foo.Getxml();
var viewData = xml.ChildNodes.Cast<XmlNode>().Select(x => x.InnerText);
return View(viewData);
}
Now we're passing an IEnumerable<string> to the view, containing just the values we want to render.
In the view, you should not be using javascript to render your data to HTML - use the view to render your data to HTML - the Razor template engine is really good at that! Something like...
<ul>
#foreach (var item in Model) {
<li>#item</li>
}
</ul>

The javascript will fail, since the variable i will be evaluated on the server side and doesn't exist then.
Use a foreach in the view, with razor:
#foreach(var child in Model.Getxml().ChildNodes)
{
child.InnerText
}

Related

Pass list of categories to partial view

I have a partial view which will display list of Main Categories and under each Main Category all of its subcategories. But the problem is I don't know how can I pass this Category List to my partial view. Please check the code bellow. I've also attached my .edmx table map picture to give you better idea. Once I pass it to partial view I want to loop though all categories and sub categories to display them
[ChildActionOnly]
public PartialViewResult _GuestNav()
{
using (var db = new TestEntities())
{
db.Categories.ToList(); // get list from here
return PartialView("_GuestNav"); // then pass that list to partial view
}
}
Here is the main action code:
public ActionResult Categories()
{
using (var dbCtx = new DbContext())
{
var categories = dbCtx.Categories.Include(x => x.SubCategories).ToList()
return View(categories);
}
}
Then in your Categories.cshtml you will have the code as below:
#model IEnumerable<Categories>
<ul>
#foreach(var category in Model)
{
<li>#category.CategoryName
#if(category.SubCategories.Any())
{
Html.RenderPartial("~/Partial/_SubCategory.cshtml", category.SubCategories);
}
</li>
}
</ul>
At last you supply a partial view called _SubCategory.cshtml in the Partial folder of Category folder as below:
#model IEnumerable<SubCategory>
<ul>
#foreach(var subCategory in Model)
{
<li>#subCategory.SubCategoryName</li>
}
</ul>
In your case if you want to pass this list to the partial view you specified you can do it as below:
[ChildActionOnly]
public PartialViewResult _GuestNav()
{
using (var db = new TestEntities())
{
var categories = db.Categories.Include(x => x.SubCategories).ToList(); // Added the include if you want to add subcategories as well
return PartialView("_GuestNav", categories); // then pass that list to partial view
}
}
Yo can use model binding, pass a Model or ViewModel as a parameter and access it from the partial view. For example, in your _GuestNav action:
...
return PartialView("_GuestNav",db.Categories.ToList());
Here's a link on how to accomplish that.
Then you can bind the model in your view. For example:
...
#model IEnumerable<Categories>;
For more detail, check out the examples from the link.
The PartialView method has an override that accepts an object. You need to store the results of the db.Categories.ToList() call in a variable and pass that to the method like this:
using (var db = new TestEntities())
{
var cats = db.Categories.Include("SubCategories").ToList(); // get list from here
return PartialView("_GuestNav", cats); // then pass that list to partial view
}
Just make sure your partial view expects a list of categories as its model. Then, inside your view you can iterate over the model and display the subcategories.
You should also look into how to use a viewmodel for your views.
EDIT
You may need to use an include statement since navigation properties are generally lazy loaded. Updated my answer.

MVC3 (Razor) Passing Model Data from View to Controller

I need to know if there is a way to pass the Model (or a part of it, i.e. thereafter a search query) data of a View (Razor Engine) to a Controller.
To explain in a better way what I have to do, that's the interested code:
VIEW:
#model IEnumerable<MvcMovie.Models.Movie>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
...
#foreach (var item in Model) { ...}
...
#Html.ActionLink("Search", "SearchIndex")
#Html.ActionLink("Create Document", "createDoc"/*, new { id = Model.ToList() }*/)
I want to pass the
#model IEnumerable<MvcMovie.Models.Movie>
in the first line (= Model used in the foreach instruction) to the Controller "createDoc" to create a report document dynamically binded with the view.
I tried everything: I tried to use a ViewData (VIEW: ViewData["data"]=Model , CONTROLLER List movies= ViewData["data"]), I similarly tried a TempData, I tried to pass the Model as routeValues in the ActionLink (as you can see: new{ id= Model.toList() }), but nothing worked.
Is it even possible to do the thing I want to?
Can anyone help me?
Your model should not be IEnumerable<MvcMovie.Models.Movie> It should be a class, say SearchMovieModel, that has IEnumerable<MvcMovie.Models.Movie> Movies as one of its properties.
If you want a search model, something like this would be appropriate:
public class SearchMovieModel{
public IEnumerable<MvcMovie.Models.Movie> Movies {get;set;}
public string SearchString {get;set;}
}
you reference this model and its properties in your view and controller.
I guess I should add the method for parsing this in the controller.
On the first call to the view, the model does not exist. You need to create it in your controller:
public ActionResult Search(){
var model = new SearchMovieModel();
//you also need to instantiate the null objects unless you do that in the model's constructor
model.Movies = new List<Movie>();
return View(model);
}
To "reconvert" the POST data back to a model, you need to specify the model and method:
[HttpPost]
public ActionResult Search(SearchMovieModel model){
if (ModelState.IsValid){
//populate your IEnumerable<Movie> here.
return View(model);
}
// the complex collection will not be parsed back into the model. You will need to repopulate it.
model.Movies = new List<Movie>();
return View(model);
}
I think that know what you want... but whit this code
#Html.ActionLink("Create Document", "createDoc", new { id = Model.ToList() })
your html is..
Create Document
and that's because is render the type not the data
Solutions
define filter model to do the search again(the recommendation of jeremy-holovacs and mine)
why ask to the server the same data again? because if someone share that link... you can imagine whats it's the result even inject fake data that your app will generate
serialize data to json for example to forward it to the controller

How to dynamically display a list of both name and value of a String/boolean pair on MVC in ASP.NET MVC

I need to dynamically display a list of both name and value of string/boolean pair on MVC view (*.cshtml) based on user selection. Specifically, both name and value of a string and boolean pair are different in each list. There are more one list that user can select. For example:
FruitName: Apple (string:string)
IsRipen: true (string:boolean)
BookName: C#
IsSold: false
One list type is defined as one report type. A list can be retrieved from report programmatically.
Possible Solution 1
Since the data type of name and value in the list are fixed (string, boolean), one idea is to build a collection as a MVC model, and pass that model to MVC razor view. The question is that how to display the name on the view,
#Html.LabelFor(model => model.Names[0]) //how to display it as 'Fruit Name'
Possible Solution 2
In ASP.NET web form, there is user control whihch can be loaded dynamically. There is partial view in ASP.NET MVC. Can the partial view do what I want? Or is there better solution.
I am new to MVC, any ideal or example would be very much appreicated.
If I understand you correctly, what you want to do is create a Partial View and call it using an action in your controller.
First, do something like this in your controller
// partial
public ActionResult report(string reportName)
{
return View(reportModel.Name);
}
Then, make sure there is a partial view that shares the name of your report.
You can then call the partial view like this:
#{Html.RenderAction("report", "Home", new{ reportName="report" });}
The line above will render the partial view Report.cshtml into the parent view or master layout.
edit
Ok. so every report has a list of name value pairs right?
Assuming that, we can write an action that passes that list to your view.
public ActionResult DisplayPairs()
{
NameValueCollection pairs = new System.Collections.Specialized.NameValueCollection();
pairs.Add("Name", "Value");
pairs.Add("Name2", "Value2");
pairs.Add("Name3", "Value3");
pairs.Add("Name4", "Value4");
return View(pairs);
}
Then we have the DisplayPairs View:
#model System.Collections.Specialized.NameValueCollection
#{
ViewBag.Title = "DisplayPairs";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>DisplayPairs</h2>
<table>
#foreach(string key in Model.AllKeys){
<tr><th>#key</th><td>#Model[key]</td></tr>
}
</table>
Which displays:
Name Value
Name2 Value2
Name3 Value3
Name4 Value4
I hope this helps
Why don't you just create a wrapper class that contains all the data you need?
public class ReportViewModel
{
IEnumerable<KeyValuePair<object, object>> Items { get; set; }
public ReportViewModel()
{ Items = new List<KeyValuePair<object, object>>() }
}
You can then create your model like so:
var model = new ReportViewModel();
model.Items.Add("BookName", "C#");
model.Items.Add("IsSold", false);
return View(model);
In your view, you just iterate over the KeyValuePairs, and print the key and value:
<ul>
#foreach(var kvp in Model.Items)
{
<li>#kvp.Key: #kvp.Value</li>
}
</ul>
(Excuse me if my razor syntax is buggy - I've not worked very much with it as of yet...)
Also, you might have to add calls to ToSting() if you have odd types of objects in your list. I think the framework does that for you if it needs to, but I'm not sure...

RenderPartial Problem (While sending data to master page)

I am trying to send some data the master page. I am using Razor as my View Engine, and AutoMapper to map between Domain and View Models. Below is my code:
//the partial view action method:
public ActionResult RenderCategories()
{
IEnumerable<TopLevelCategory> categories = _categoryService.GetTopLevelCategories();
var viewModel = new MasterPageViewModel
{
Categories =
Mapper.Map
<IEnumerable<TopLevelCategory>, IEnumerable<ParentCategory>>(categories)
};
return View(viewModel);
}
//the partial view file: (this is just a test for now)
#model Sharwe.MVC.ViewModels.MasterPageViewModel
#foreach (var item in Model.Categories) {
#item.Name
}
public class MasterPageViewModel
{
public IEnumerable<ParentCategory> Categories { get; set; }
}
I'm calling the partial view using #Html.RenderPartial("RenderCategories") from inside my _Layout.cshtml file. But I keep getting the following error:
Compiler Error Message: CS1502: The
best overloaded method match for
'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)'
has some invalid arguments
What's going on?
The RenderPartial extension method writes directly to the output stream and has no return type (void). So here's the correct syntax to call it:
#{Html.RenderPartial("RenderCategories");}
or if you prefer you could use the Partial extension method:
#Html.Partial("RenderCategories")
Contrast those with their equivalents in the WebForms view engine:
<% Html.RenderPartial("RenderCategories"); %>
<%= Html.Partial("RenderCategories") %>

Can you put a PartialView into a ViewData object?

I'm trying to mimic the webforms multiview functionality and the only way i can think of is to put a PartialView into a ViewData object? Something like the following:
View code:
<%= ViewData["PartialViewPlaceholder"] %>
Controller code:
if(//condition){
ViewData["PartialViewPlaceholder"] = partialView1;
} else {
ViewData["PartialViewPlaceholder"] = partialView2;
}
How would you go about this?
ViewData is meant to contain actual data, not views themselves, which contain markup and rendering code. Would it not be possible for you to do this:
public ActionResult MyActionMethod()
{
var model = new MyModel();
model.UsePartialView1 = false; // Tell the view not to use Partial View 1
return View("MyView", model);
}
And in the View MyView:
<% if (Model.UsePartialView1)
Html.RenderPartial("PartialView1", Model);
else
Html.RenderPartial("PartialView2", Model); %>
This will render either PartialView1 or PartialView2 using the same Model depending on the condition set by the Controller.
Or, to return a Partial View with a Model directly from your controller, instead of a normal View, you can do this:
public ActionResult MyActionMethod()
{
var model = ...
ViewData["MyViewData"] = ...
return PartialView("PartialView1", model);
}
This will return the Partial View PartialView1 directly to the client. This is mostly useful in AJAX scenarios, since the result will most probably not be an entire HTML page. Partial Views are .ascx files.

Resources