MVC: Set Name Attribute w/Helper - asp.net-mvc

I have a situation in an MVC3 app where I would like to be able to set the name attribute on some html being generated by a helper (DropDownList).
It appears this is not possible. Apparently the helpers silently override whatever value you may specify for the name attribute in the html attribute object that you pass to the helper.
I'd like to confirm that before I waste too much more time on trying to work with the existing helpers.
And, as an aside, if it is not possible by design...I think that's a foolish limitation in the MVC framework. Yes, I know that assigning the wrong name attribute can break the automatic model binding. But I should be able to do that when I need to. After all, I can always write the raw html using whatever name attribute I chose. The helpers should help, not be a straitjacket.
Edit to discuss whether editor templates maintain navigational context
Darin, I am using editor templates (I was using the term "partial" generically, since editor templates are a special kind of partial view).
Editor templates do modify the HtmlFieldPrefix -- that's how I noticed I had a problem :). I was using a call like this:
// call in higher level partial - context is 'eae'
#Html.EditorFor(m => m.Value)
...
// inside editor template for typeof(Value) context is 'eae:Value'
That context shift is needed to keep the default binding mechanism working properly. I'm using a different approach, where I want the context to stay fixed throughout a call chain of partials (i.e., as execution burrows down into deeper partials I want the context to stay the same).

This is by design. The HTML helpers do not allow you to override the name attribute. They generate the name based on your view model so that the default model binder is able to properly bind the values according to the well established conventions when the form is submitted.
And, as an aside, if it is not possible by design...I think that's a
foolish limitation in the MVC framework.
You could open a ticket on MS Connect and hope this could change in a future version of the framework. Until then you could also write your own custom helpers that will allow you to override the name attribute for the cases when you need such functionality. Personally I've never needed it so far but I am sure you have valid reasons. Another possibility is to write a custom model binder on the server.

Related

How to force one method on Razor ambiguous reference?

On one MVC 4 project, we have a lot of Pages.cshtml that receive a collection of Models (generally hundreds of rows), which we serialize as JSON via
#Html.Raw(Json.Encode(Model));
The problem is that on some of those pages we are receiving an exception (The length of the string exceeds the value set on the maxJsonLength).
We know what is the reason and how to fix it. The thing is that I would like to create a similar Json.Encode() method (using Json.Net), so we do not need to modify all the cshtml pages. If I create a Json.Encode() method, Razor complains about ambiguous reference between My.Namespace.Json and System.Web.Helpers.Json.
Again, we know how to solve this by adding an alias on the page:
#using Json = My.Alias.Json
What I'm trying to do is to transparently instruct Razor to choose this alias for all the cshtml pages that uses this Json.Encode. The reason is that I want this to be transparent, so later if somebody adds a new page, automatically he will start to use our custom JSON implementation.
I think on Views/Web.config you can add namespaces and some configurations for Razor, but I don't see how to explicitly set the aliases.
Interesting issue, but as far as I know that's not possible. See e.g. this: C#: Globally alias a generic class name?
As an alternative you could create a helper method Html.JsonEncode() and teach, drill or entice everyone to use that.
If you make it also do the Raw() call and return IHtmlString, then you can do #Html.JsonEncode(Model) as opposed to #Html.Raw(Html.JsonEncode(Model)) and before you know it everybody is a fan of your new method.

Reading Form Post data vs strongly typed View

I have a set of HTML pages containg input elements. I am in the process of converting them into MVC Views.
Considering performance & cleanliness of code. What is the correct way to proceed,
Processing Form as posted FormCollection, or
Create Strongly typed view to obtain input values from the Model.
One advantage of using HTML helpers is it enables better compile-time checking of your views (allowing you to find errors at build-time instead of at runtime), and also supports richer intellisense when editing your view templates within Visual Studio.
Another advantage might be HTML helpers allows you to set any custom attributes on the HTML tag. You can do that with the helper by either passing in a dictionary or using an anonymous type like following.
#Html.TextArea("FirstName", Model.FirstName, new { parameter = "value" });
Source 1
Source 2
You can use an overload of TextBoxFor to set/override the input element attributes:
#Html.TextBoxFor(m => m.Name, new { #Value = "0", readonly="readonly" #class="cssClass"})
This is actually a good question..I don't know who voted it down...there are too many strict view model evangelists in my opinion.
After Having worked with MVC for awhile my view is that for very simple things the #Html helpers work very well...however they lead to a way of thinking about the webpage/server interaction that is limiting in the long run, especially for more complicated uses. It lets you rely heavily on unobtrusive validation without having to understand how validation works on the client..this is great for the introductory programmer...as I once was...however not understanding at least the jquery validation libraries will handicap you eventually. Doing any serious web/web-application development where validation is more complicated than checking if a value is required becomes much more diffucult. In addition you are relying on Microsoft to keep their validation library in sync with the jquery validation libraries should you update them(I've ran into this issue).
In addition you need to consider what if any front-end libraries you are using and if any of them don't work well with the output of these helpers(bootstrap is one notable one). That being said form collection is faster and less restrictive...using it and the pure validation libraries will be easier and more expressive...letting you write whatever code you want. After all..how hard is it to write if(!String.IsNullorEmpty()) on the server-side or whatever type of validation you need in addition to the client.

Is there anything out there to help handle "field level" authorization for ASP.NET MVC3?

I know you can use the Authorize attribute to control access to a Controller or ActionMethod... but what about more fine grained control? It seems common to have specific fields be allowed/disallowed based on a user's role, for instance. Maybe on an employee profile the employee can edit his profile information, but only a supervisor can change his job title...
Optimally I'd like to be able to develop views, models and controllers normally and have a configuration page on the website that site admins could then use to configure authorization at whatever granularity is required. In other words the programmers shouldn't worry about it (except for the guy writing/integrating that specific part of the system.)
I can envision DisplayFor and EditorFor checking attributes to render fields as ReadOnly, Hidden, etc... and maybe the attributes get added at run time from an Authorization Provider of some kind.
The question is: Is there a framework or something out there that already does this?
Write a custom ModelMetaDataProvider that will allow you to alter the metadata for each model and it's properties before they make it to the view. The built in helpers will not render a field if it's metadata value ShowForEdit = false or ShowForDisplay = false.
You can utilize a rules engine or some other ACL to manipulate the metadata on each model and property to get most of the behavior your looking for out of the box without touching the built in helpers. On edge cases where you need more control you can write your own helpers and pass more complex data in the metadata.AdditionalValues dictionary.
You can implement security at field level using HtmlHelper. In the following example they used textbox only implementation but it can easily be extended for all type of controls:
http://bartreyserhove.blogspot.ca/2008/12/field-level-security-using-aspnet-mvc.html

Can I use a MVC Global Action Filter to disable form fields?

Some users of our application will have read-only access to many of our pages, in our current web forms app this means they see the form, but all of the fields are disabled. We're looking at MVC 3 and searching for the cleanest, most idiomatic way of implementing this functionality.
Some ideas so far:
Some combination of a global action filter and edit templates.
A custom Html helper, something like Html.SecureTextBox etc...
I'm leaning towards number 1, but I'm wondering if any of you guys/gals with more MVC experience have solved this problem in a better way.
I agree with using a base view model, or perhaps just an interface with a "CanEdit" type of property. If you go the interface route, you could set the property in an ActionFilter in the OnActionExecuted method.
To tie it to the view, creating a new HtmlHelper would be pretty easy. I'd use TextBoxFor as the base class, since it has access to the view's model. You can then inspect the property and create the necessary HTML attribute. However, with going this route you will need to create a new helper for each type of input control you need (textbox, select list, etc).
Without knowing all the details of what you are doing, a much simpler idea would be to not provide a Save button for read-only users. The Save button would be driven by one property in the view model (or ViewData, if you like).
Several other people mentioned that a server-side restriction is still needed to prevent people from bypassing the client-restrictions. You will need an action filter for this. This link has a good idea about that.
My preference would be to set a variable in a common base view model (or ViewData), using a global action filter, and then use a bit of jquery to dynamically disable the input fields, delete buttons etc.
$(':input').attr('readonly', true);

Suggested approach to generate pages based on attributes on properties in model in ASP.Net MVC!

We need to generate forms for Create/Display/Edit on our website. The requirement is that these need to be metadata driven. We will have properties on our Model attributed with the type of control to generate for that property.
[RenderAs("DatePicker", Order = 1)]
public DateTime DateOfBirth{get; set;}
The idea is to have templates for each of these like Date-Picker.ascx, etc in the SharedFolder
We need to generate around 25 such forms and are looking for a reuseable way of accomplishing this. What would be the best way to handle validations with this (basic validations like required, less than, greater than, etc)? What do you suggest for dependent field validations (less than field, greater than field)? Does this sound sensible?
Thanks
It sounds like you're looking for MVC 2 templates.
Use DisplayForModel for read only views and EditorForModel for create/edit forms built from the metadata in your view model. Use Data Annotations attributes to decorate the view model with validation rules and other rendering information (label, custom template to use, etc.).
Here's a quick intro video to MVC 2 templates.
Check out ASP.Net Dynamic Data. It is pretty much what you are looking for. (And if you can use .Net 4.0 then you should be able to use MVC, webforms, and DynamicData all in one project.)
You are mixing Model and View concept. Why do you need MVC THEN?
On practice, you will face situations when Admin need some minor changes compared to regular user, and it will be hard to support in cases when form is generated using attributes.
I am not saying this is best, but we decided to stick with form concept and every form able to decide WHAT to show and HOW to show.
And we defined number of helper methods like RenderDatePicker which do all dirty work.

Resources