Passing model data to asp.net mvc EditorTemplates - asp.net-mvc

ScottGu in this post link text shows how one can utilize EditorTemplates for things such as a Country DropDownList. My question is how can one pass a dynamic list of Countries to the EditorTemplate?

Even better you make the partial view strongly typed and pass the model to the EditorFor helper
#Html.EditorFor(m=>m.SelectedCountry, Model.AvailableCountries)

Probably the most elegant solution is using a Custom Attribute, you can later access Model metadata using: ViewData.ModelMetadata.
e.g:
[Foreign(Type="DropDown", TableName="Countries")]
public int IdCountry { get; set; }
where ForeignAttribute is a class you must declare, and later use it to build your editor template.

You can pass it in ViewData and feed ViewData from and ActionFilter if the data is required very often (although arguable it is an anti-pattern).

Similar to #Benja's answer
You can also use the [AdditionaMetaData(key,value)] attribute in a similar fashion without having to define your own attribute. Key and value have to be strings.
The extra data can be retrieved in the view with: #ViewData.ModelMetadata.AdditionalValues["DropDownData"]

Related

Avoiding foreach for #html.checkboxfor

I am developing an application using MVC. I had a requirement where I have to display checkbox for a list.
I was going through different posts for doing this, one of them is the use of avoiding foreach for looping and making use of #html.editorfor() as described in the answer by Darwin dimitrov here:
This answer works fabulously fine, but I have a clarification , it is:
In the same view I have 2 requirements , the one with checkboxfor and the other one with radiobuttonfor
So, If I am using
<div>#Html.EditorFor(x => x.RoleAccess)</div>
How do I write the (~/Views/Shared/EditorTemplates/RoleAccessViewModel.cshtml) to serve for checkboxfor for one requirement , and the other one for #radiobuttonfor .
Wont this approach be hardcoded which will always render the RoleAccessViewModel.cshtml whenever EditorFor(x => x.RoleAccess) is used?Please execuse me If I have used any technical terms wrong way,as I still a novice in mvc.
The EditorFor method has an overload that accepts a template name as argument. I think that solves your problem if I understand it correctly. See http://msdn.microsoft.com/en-us/library/ee407414%28v=vs.118%29.aspx
You can also solve this by using the UIHint attribute on your property instead (or in addition to) relying on naming the template after your view model. Then you can create an alternate template to render the radio buttons and specify that:
[UIHint("RadioList")]
public List<Something> MyRadioButtonList { get; set; }
EditorFor will then look for the template: Views\Shared\EditorTemplates\RadioList.cshtml
You could do the same for your checkbox list, as well, instead of relying on the view model. For example, [UIHint("CheckboxList")] and CheckboxList.cshtml. Then, you'd be able to apply these templates more broadly.

Will Razor's EditorFor() syntactic sugar create a checkbox list in the View?

I've been jumping through hoops to add an array of checkboxes to a View in an asp.net MVC project (using a custom jQuery plugin), but just realized it might be possible using the "in-the-box" functionality of the MVC / Razor extravaganza.
Theoretically, the following should work:
If a model has an array of bool, such as:
public bool[] chicagoBoolsFools { get; set; }
...calling this in the View:
#Html.EditorFor( model => model.chicagoBoolsFools)
...should create an array of checkboxes bound to the Model member.
Is this the case only in theory, or also in actuality?
Unfortunately #Html.EditorFor doesn't even create checkboxes... Maybe I am misunderstanding you but I would try something more along the lines of this post.
Try stuffing a model with either a list of Checkboxes (represented by a string and a boolean value) or just a basic string property for each checkbox, which can then be rendered in the view using several #Html.CheckBoxFor calls.
#Html.CheckBox or #Html.CheckBoxFor are key here.

Which way is better to populate the Dropdownlist in MVC?

I Have a List like
IEnumerable<SelectListItem> Users;
I can populate the Users Items in Dropdownlist by 3 way
1-Use ViewModel
Public class myViewModel
{
IEnumerable<SelectListItem> UserList;
}
and fill it like
viewmodel.UserList=GetUsers();
2-Use from ViewBag
ViewBag.UserList=GetUsers();
3-Use from ViewData
ViewData["Users"]=GetUsers();
What is Difference between my ways and which one is better
There's a fourth way, which I think is the best way to go.
Since you only have one object (of type IEnumerable<SelectListItem>) you could just pass it to your view as the model (no need for an intermediate ViewModel).
In terms of the possibilities, there's no real difference. The difference is that your first method and the method I just described are strongly typed, meaning you get Intellisense and compile-time validation whereas your second and third method are weakly typed and you get no intellisense and no compile-time validation.
In your case, better to use ViewModel because it's clean MVC and you get strongly-type benefits.
ViewBag and ViewData are better, for example, if you have a lot of partial views in your view, or difficult layout which need passed data. But as I understood, you need only to show dropdownlist, so use ViewModel.

ASP.Net MVC, Dynamic Property and EditorFor/LabelFor

I am using MVC 3 w/ Razor and using the new dynamic ViewBag property. I would like to use the ViewBag property with the EditorFor/LabelFor Html helpers but can't figure out the syntax.
The View does have a #model set, but the object I am trying to use is not part of that model. I am aware I can create a ViewModel but that is not what I am after.
Can anyone help?
Controller:
var myModel= _repo.GetModel(id);
var newComment = new Comment();
ViewBag.NewComment = newComment;
return View(myModel);
View:
#model Models.MyModel
#(Html.EditorFor(ViewBag.NewComment.Comment))
I haven't tried it, but this should work I think.
#(EditorFor(m => ViewBag.NewComment)
It is possible to use a Linq-to-SQL syntax, but use a completely different object on the right side.
Not knowing what your Comment Model looks like, my gut reaction would be to just do:
#Html.EditorFor(ViewBag.NewComment)
However, because ViewBag is dynamic, you may need to cast NewComment before you use it, in order to get the EditorFor magic.
#Html.EditorFor(ViewBag.NewComment as Comment)
Update
Strike that, EditorFor can only accept an Expression as a parameter, and that Expression must return a property of the page model. I don't think EditorFor or EditorForModel are going to be of any use to you if you don't want to use a ViewModel. Have you considered switching the roles of whatever it is you're using the Model for, with that of the ViewBag?
If for some reason I need to use ViewData to pass the model into my view I do the following to allow for the Html.DisplayFor() helpers.
In the views code block I cast the ViewData model object to its underlying type
var newCommentModel = ( NewComment )ViewBag.NewComment;
Then I assign the following expression to the helper using the strong-typed reference
#Html.DisplayFor( model => newCommentModel )
The expression tree now contains a strongly-typed model and the DisplayTemplate is correctly displayed.

Posting multiple values using MVC

I have a model with a property that points to a file that contains HTML. My strongly typed view to this model uses a custom HTML helper method to resolve and return the HTML from the file. Works great so far.
The HTML read from each file will contain various controls whose values I need to retrieve when the form is POSTed.
What would be the best way to have access to the POSTed control values in my controller method?
I would prefer a non jQuery solution, but I am not sure if the MVC framework can provide these values to me? Can it provide a list of key/value pairs to the controller somehow?
You could use the FormCollection in ASP.NET MVC.
public ActionResult SomeAction(FormCollection form) {
...
}
You have essentially two options.
1) Use the old fashioned Request variables as all we have done in ASP.NET web forms.
For example in your controller action method you can retrieve any value present on the form with the following method
public ActionResult SomeAction() {
var request = this.ControllerContext.HttpContext.Request;
bool boolParam = bool.Parse( request["boolParam"] ?? "false" );
}
2) Create a custom Model Binder to let the framework pack those values in a custom class object.
This method would be a little bit more difficult at the beginning because you have to create a custom Model Binder but it favour readability on your controller code. For further details on creating custom model binders give a look at the following links (you can find more with a simple search)
Custom Model Binder for Complex composite objects
Custom Model Binder and More UI Validation in ASP.NET MVC
A Custom ASP.NET MVC Model Binder for Repositories
Hope it helps
Is the content of the HTML files dynamic or known at design time? If you know it now, you could have each one post to it's own action and then strongly type the parameters.

Resources