Use ASP.NET MVC DisplayTemplate implicitly - asp.net-mvc

I have some code like this in a cshtml view
#{ int i = 0;
foreach (var record in Model.Records)
{
<tr>
<td>#record.CreatedDate</td>
<td>#Html.DisplayFor(x => x.Records[i].CreatedDate)</td>
</tr>
i++;
}
}
and in my ~/Views/Display folder I have a file called DateTime.cshtml with this in
<p>#ViewData.Model.ToShortDateString()</p>
so my view is rendering two version of the CreatedDate, one with the full DateTime string and one with the short date string.
Can I configure my ASP.NET MVC4 project to use the display template I have created whenever it displays a DateTime, without calling DisplayFor explicitly? ie how can the line '#record.CreatedDate' use my DateTime template?

No you can't. there is no way to configure MVC to use a template with this code:
'#record.CreatedDate'
You will have to keep using DisplayFor which isn't too much to write by the way...

Related

What is the Exact use of DisplayFor in mvc razor view?

What is the Exact use of DisplayFor in mvc razor view? Because it will show only string that matches the model property we pass. But in Razor view, we can directly show the property value using model.propertyvalue
What is the difference between below codes,
<span> #Html.DisplayFor(m => m.propertyValue)</span>
VS
<span> #Model.propertyValue</span>
When using #Html.DisplayFor(m => m.Property) allows you to take advantage of DataAttributes in your model class. An example would be using [DisplayFormat(NullDisplayText = "whatever you want to display when null")]. I typically have my values display an em-dash when null. Accessing the property directly with #Model.Property will bypass those attributes.

Asp.net MVC4 #Html.EditorFor .Where() Attribute

In my view i am using editortemplate as below:
edit.cshtml
#model NetasCrm.Models.CRM_OPP_DETAILS
<table class="table table-hover">
<thead>
<tr>
<th>Çözüm</th>
<th>Üretici</th>
<th>Tarih</th>
<th>Tutar</th>
<th>Sil</th>
</tr>
</thead>
<tbody>
#Html.EditorFor(model => model.CRM_SOLUTION_DISTRIBUTION, new { Solutions = ViewBag.Solutions, Vendors = ViewBag.Vendors })
#Html.HiddenFor(model => model.ID)
</tbody>
</table>
It is working but i am trying to do something(adding where clause.) as below to create an editor template for some of the items in my model.
#Html.EditorFor(model => model.CRM_SOLUTION_DISTRIBUTION.Where(p=>p.AMOUNT != 0), new { Solutions = ViewBag.Solutions, Vendors = ViewBag.Vendors })
I am getting the below error:
Templates can be used only with field access, property access,
single-dimension array index, or single-parameter custom indexer
expressions.
It's not how #Html.EditorFor() should be used, error message clear states about that.
To render what you want you may either use Html.Partial(), or create separate property in your model and move Where to it's getter.
Html.XxxFor expects a lambda expression that selects a property from the model. This is used to identify the property of the model which will be edited.
What you're trying to achieve is probably what you can do with an editor template.
Interesting articles on editor templates and their implementation:
Quick Tips About ASP.NET MVC – Editor Templates
Brad Wilson: ASP.NET MVC 2 Templates, Part 1: Introduction
In the second article you can see that if you have a custom class with the data you want to edit, you can create a template which is automatically used for your editor if you give it the right name and save it in the right place. You can make a class with a single field and include it in your model instead of the original property. This also allows to edit several properties at once (declaring a class with those properties)
Othe option would be a custom html helper:
Creating Custom HTML Helpers (NOTE: this technique will work perfectly with C#/Razor syntax)

Can one MVC Edit Template delegate to another?

I have a strongly-typed Razor 2 editor template. When the view model meets certain conditions, I want the view to delegate to an alternative template of the same type. I use the TemplateName argument to the EditorFor helper to select the alternative template:
#model MyType
#if (Model.IsSpecialCase)
{
#Html.EditorFor(m => m, "SpecialCaseTemplate")
}
else
{
#* Default markup *#
}
Problem is, Razor does not call the alternative template; it simply passes over the EditorFor method. If I change the type of the second template, it shows it correctly. I can work around this using a Partial View, but I would rather not, as I have a scheme going with Editor Templates that I want to stick to.
Anyone know how I can get this to work?
Edit
Looks like this has something to do with the behaviour described here: ASP.net MVC - Using EditorFor with the same model type twice. In short, that MVC does not support using the EditorFor method on the same object twice.
The best way to do this, is by returning a different view from your Controller:
public ActionResult someaction(){
var Model = ...;
if (Model.IsSpecialCase){
return View("SpecialCaseTemplate");
}
else{
return View();
}
}
Alternatively, you could do in the view like this:
#model MyType
#if (Model.IsSpecialCase)
{
Html.RenderPartial("SpecialCaseTemplate", model);
}
else
{
#* Default markup *#
}

Using EditorFor template for DisplayFor in MVC4?

I'm using an Editor Template to make an Html.EditorFor(property) in my viewModel's view. There's a different .cshtml file containing "#Html.EditorFor(property)".
Now, depending on the value of a property of my viewModel, I need to display a DisplayFor instead.
I tried doing this by adding some conditional logic in my EditorTemplate but can't seem to access the properties of my viewModel from there (since the editor template is using #model.someOtherModel and not #viewModel). So if I can say something like
// Razor
if(true)
{ EditorFor(property) }
else {DisplayFor(property)}
in my viewModel's view, that would work. I just don't know how to define a "Display Template" for my object, in the same way I defined an Editor Template.
Another solution might be accessing the viewModel data from the Editor template... is this possible?
In Razor, you should be using something like the following syntax:
#if (condition) {
#Html.EditorFor(modelItem => model.property)
} else {
#Html.DisplayFor(modelItem => model.property)
}
Are you getting a specific error you can share?

How can I edit child objects in an MVC4 form?

I have the following:
#foreach (var parent in Model.Parents)
{
#foreach (var child in parent.Children)
{
#Html.TextAreaFor(c => child.name)
}
}
How can I get editing to work for child objects? I tried something like this as well:
<input type="hidden" name="children.Index" value="#child.Id" />
<textarea name="children[#child.Id]" >#child.Name</textarea>
To pass an IDictionary to the controller but I get an error:
[InvalidCastException: Specified cast is not valid.]
System.Web.Mvc.CollectionHelpers.ReplaceDictionaryImpl(IDictionary`2 dictionary, IEnumerable`1 newContents) +131
This seems like a very common task... is there a simple solution to this? What am I missing? Do I need to use an Editor Template? If so, any MVC4-compatible examples would be fantastic.
is there a simple solution to this?
Yes.
What am I missing?
Editor templates.
Do I need to use an Editor Template?
Yes.
If so, any MVC4-compatible examples would be fantastic.
ASP.NET MVC 4? Man, editor templates exist since ASP.NET MVC 2. All you need to do is to use them.
So start by getting rid of the outer foreach loop and replacing it with:
#model MyViewModel
#Html.EditorFor(x => x.Parents)
and then obviously define an editor template that will be rendered automatically for each element of the Parents collection (~/Views/Shared/EditorTemplates/Parent.cshtml):
#model Parent
#Html.EditorFor(x => x.Children)
and then an editor template for each element of the Children collection (~/Views/Shared/Editortemplates/Child.cshtml) where we will get rid of the inner foreach element:
#model Child
#Html.TextAreaFor(x => x.name)
everything works by convention in ASP.NET MVC. So in this example I assume that Parents is an IEnumerable<Parent> and Children is an IEnumerable<Child>. Adapt the names of your templates accordingly.
Conclusion: everytime you use foreach or for in an ASP.NET MVC view you are doing it wrong and you should consider getting rid of it and replacing it with an editor/display template.

Resources