MVC Customizing display template: Model.Value vs #ViewData.Model - c#

I've seen two "Display templates customezing" examples.
In the 1. example programmer use Model.Value and in the 2. example he use #ViewData.Model.- See below
Exampel 1 (DateTime view:)
#model DateTime?
#Html.TextBox("", Model.HasValue ? Model.Value.ToString("dd/MM/yyyy") : "", new { #class = "ka_" })
Example 2:
<a href="#ViewData.Model" target="_blank">#ViewData.Model<a/>
What is the difference between them ?
What to select ?

In most cases you use both in your views. The model specifies the data for you're main view. It's the data that is created by the controller action. The ViewData dictionary is normally populated by other components.
Let's take for example an Product (view)model. A product would have a price, a description, a sku and in most cases a stock indication.
You're Product (view)model does not contain data any user information, website navigational data. That data is placed in the ViewData dictionary by other components and can be used by (parent) views to render the full page.
A bit offtopic, but at our company we have a very strict rules about what a view is allowed to do. In short is it not allowed to change/modify any data (not even the page title!) or to retrieve any data. The only code allowed in our views are conditional constructs and calls to helper methods. It helps if new developers on the team start with view engines that have no an 'eval' constructs like SuperSimpleViewEngine (from NancyFx) or XsltViewEngine. Razor and WebForms make it to easy to 'cheat'..

Related

ASP.NET MVC : DropDownList to model field

My model is a rpg character. He has a field "Game", that is a strongly types object containing "Careers" fields, themselves strongly types object.
Model must choose a career amidst multiple choices.
I currently display it as is :
#Html.DropDownListFor(model => model.career,
new SelectList(Model.game.professions, "name", "name"),
)
(where professions is of type List[career]).
However, this does not bind the selected value of the dropdownlist to the career field of my character.
Any hint? I've been searching for a while, but I only find way to populate a dropdownlist from a model, and nothing on how to ensure the selected value is passed back to the model.
Thank you
Edit = I accepted RedGoodBreaker's answer even though it wasn't what I expected because it helped me find the solution.
Point is : you can't select an object via DDL in mvc, you can only select a basic type that references to that object (in my case, I chose the string field "name" of my career).
#Html.DropDownListFor generates html like
<select id="CarType" name="CarType">
<option value="a">Volvo</option>
<option value="b">Saab</option>
<option value="c">Mercedes</option>
<option value="d">Audi</option>
</select>
so as you can see they are simple strings(in your case both value and text are the same). when you select one posting form will produce something like that:
...
CarType="a"
...
You can do several tricks but question is it worth doing it and do you really need it.
Normally your model should have field CarrerName and dropdownlist should be bound to it. In Controller Action which accepts form submission you should rehydrate Carrer from database or other store using CarrerName (this is why we asked about id).
I understand that Skills are some kind of dictionary that does not change much. Options for storing are(there maybe some others that i am not aware):
save your dictionary to Session before presenting form or better after logon if this dictionary does not change. You can access it after form submission and find apropriate key (best int or guid)
System.Web.Caching.Cache.
TempData.
Database.
this options have its cons and pros about which you must read because i don't know your application specification.
If you need this data before submission in view or javascript you have to do it yourself ( there is no simple one-liner). I can help but i dont know what do you want to achieve.
Your career object should have Id field and you need to pass it to DropDownListFor
Please refer the below link
MVC DropDownList
and then in the Razor view
#Html.DropDownListFor(m => model.career, new SelectList(Model.game.professions, "Value", "Text"), "Career")
Of course the model needs to be passed into the view with the values in the List already populated

Object with items : View-Controller communication

So, I have no clue how to search for an answer to this problem, mainly because there are several aspects to it which I don't know how to solve. So - here it is.
I have an object, let's call it ObjectWithItems which has a List<Item> of Item objects. Both have separate Views and Controllers (which seems logical to me, but I can't be sure).
What I'm trying to achieve is this – go to Create action of ObjectWithItemsController and fill the necessary information specific to it. Then, I click an ActionLink "Add item", which takes me to the Create action of the ItemController. The View is rendered and I enter information for that specific Item.
What I don't know how to do is the following: when I submit the current Item, it should be passed to the former Create view of the ObjectWithItems and added to the List<Item>. Furthermore, it should contain the information inputted before calling the Item Create method and the rendering of the corresponding View.
I know this is a bit blurry description, but that is because I have just started learning ASP MVC and still don't know what's what. Any tested approaches for this?
Using Session["key"] object allow you to store any kind of object, Ex :
List<Table> Rows = db.Table.Where(t => t.id < 100).ToList(); // 100 first rows
Session["TableRows"] = Rows;
And later when you want to retreive them :
List<Table> Rows = (List<Table>)Session["TableRows"] // don't forget to cast it
Your objects will exist in Session as long as you don't reach the ASP timeout
Communication between View-controller is done through HTTP Post of the form.
< form class="form-horizontal" method="post" >
or #using (Html.BeginForm())
More info here with example

Displaying results in View linq to sql mvc 4

I have been reading and reading , and I can't seem to get this to work at all. I am very very new to asp.net MVC - after all the tutorials I read I finally got this much accomplished.
public class EventsController : Controller
{
private EventsDBDataContext db = new EventsDBDataContext();
public ActionResult Index()
{
var a = (from x in db.tblEvents
where x.StartDate >= DateTime.Now
select x).Take(20).ToList();
return View(a);
}
}
This is successfully finding 20 rows (like it is supposed to). Now how do I display these in the view ?? Does it have to be a strongly typed view?? It doesn't seem like it should have to be... I have tried both , I tried typing a whole view, but for now it would be nice to just get one property of tblEvents to show up in the view. This is not working, I have tried many many variations.
#{foreach( var item in Model){
#Html.DisplayFor( item.ID)
}
}
How do I get the results from the controller displayed in the view? Just the ID is good for now - I can go from there.
The problem is that your View doesn't know what type your Model is. Use the #model syntax to define the type of your model.
#model List<YourEventClass>
#foreach( var item in Model )
{
#item.ID<br />
}
See i.e. here for more information
from the root of the web project you should have a directory called Views. Within the views folder create a new folder named Events. In the Events folder create a razor view named Index. put your markup and template code in this file.
You are correct, views do not need to be strongly typed. I find it's a good idea to do so because it provides another compile time check, but it's not required.
when you run the application you will navigate from the root (typically home/index) to Events/Index. there you should see the list of 20 items rendered in the view.
I guess you can not do something like this:
#{foreach( var item in Model){
#Html.DisplayFor(modelItem => item.ID)
}
unless the view knows what Type Model is returned as (still seems weird that .Net can't figure that out on its own. So I fixed the problem and got the ID displayed properly by adding this to the View.
#model IEnumerable<GetEvents.Models.tblEvent>
This works fine for this example - I am returning one table , so the Model type is just the class for the table. But this doesn't seem right - what if I wanted to query and join tables then what would the Model Type be?? Adding this fixed my problem , but if someone has a better answer for this then I will accept that.

UpdateModel is not updating "deep" property

I have an ASP.NET MVC application. At a certain point I get a FormCollection in a Controller method that I want to use to update a model. In the collection not all of the values are properties of that model and the property to be updated is an item from a list, and that list is also an item from another list. Something like this (I hope this is clear):
propertyToUpdate --> model.Items[0].Subitems[0].SomePropertyClass.Value;
I tried this in my Controller:
UpdateModel(model);
The problem is that this is not working and I assume it has something to do with the fact that the reflection is not working. I went searching and stumbled upon this article. So I understand that using the prefix-parameter solves the problem. But not in my case, as the properties lie "deeper" in the model as items from a list.
Does anyone know how I can solve this?
Update:
Here's the EditorTemplate for the property:
#model Q95.Domain.Property
<li>
#Html.DisplayFor(p => p.Description) :
#Html.DisplayFor(p => p.Quantity.Value)
#Html.DisplayFor(p => p.Quantity.Unit.Description)
<br />
#Html.TextBoxFor(p => p.Quantity.Value)
</li>
This template is called like this:
<ul>
#Html.EditorFor(model => model.SegmentRequirement.MaterialRequirements[j].Properties)
</ul>
Is this enough code or is there something still missing?
Update2:
Ok, in all the sub-properties I defined parameterless constructors and now I call:
UpdateModel(segmentRequirement, "SegmentRequirement", form.ToValueProvider());
This updates the model, but everything from MaterialRequirements is re-instantiated... :S
UpdateModel works fine on "Deep properties".
The problem is probably the data in the collection you get isn't equal to the properties names.
Check 3 places to see the values you get from the page
The form values.
The route data
The query string
In exact that order.
The keys should match you model properties names.
Update:
How to match the keys to properties names?
The input id will be the key you will get, change the the ids to match your properties names, or even better, use the HtmlTextBoxFor helper: see this article:
Maybe you should create flattened ViewModel and then use that to populate the view, and later synchronize it with the real model.
Can you show us your model and your view, if you are not using htmlhelper, you then have to understand the naming convention very well in order to make the model binding work with your model. so the first thing in first is to show us your model and view.

Multiple field searches in MVC 3 using C #

Hi I am relatively new to MVC 3. i was just wondering if there is a way to do multiple field searches.
I'm looking to have many textboxes on a page, where the user can input search criteria such as Region, Salesperson Rating, Salesperson Subject, etc .
and then when the user clicks the search button it should populate a list with Salespeople matching the criteria entered.
I have been looking on the web and i haven't found a concrete answer...
Thank you in advance...
You could use a grid like jqgrid to get these kinds of functionalities. It's relatively easy to implement in asp.net mvc. I once wrote a mvc helper for jqgrid, it's built for mvc2 but can also be used in mvc3 as well. There's also a sample app for the helper, you can find it here to see if fits your needs.
Yes, you can have multiple parameters passed to a controller action, e.g. by defining a form with multiple input fields in your view and let the form post to the action url. The data can be passed using multiple method parameters, a custom model class that defines the relevant properties, or simply by using a form collection.

Categories

Resources