Can action parameter be a model in ASP.NET WEB API? - asp.net-mvc

I have an action where I am supposed to capture many primitive values including Enum types. I have created a model to match the required values.Can action parameter be a model in ASP.NET WEB API? Or I need to create a view model?

You don't necessarily need to create a view model.
Models, view models, DTOs can all just be classes with properties on.
How each can or cannot be used is a decision you need to make.
Usually the main requirement from an API endpoint perspective is that the class into which the parameters are being deserialised has a default constructor. Then the parameters from the request will be assigned to properties of the equivalent name.

Related

Should I use custom model binder to bind view model to entity?

Just some idea to make more use of custom model binder. I am currently still using IMapper interface to do so, though wondering whether part of the purpose of custom binder is to mapping view model or input model to business entity? I can see there might be some limitations if i use MVC custom binder. What is the advantage to use the custom binder in MVC? Will my app gain better performance?
Short answer would be No, you should not
ModelBinder by itself is part of ASP.NET MVC infrastructure. If you would take a look at ASP.NET MVC pipline (PDF) you would see that it's job is
to convert a posted web form data (a string basically) or query string from URL to an instance of particular class.
ASP.NET MVC framework has a DefaultModelBinder that
is suitable for 99% of cases. Custom model binders could be used in situations where standard data conversion fails e.g. mapping $ 1,234.56 from a textbox to a decimal value of 1234.56
Moreover ModelBinder implements IModelBinder interface with a single BindModel() method. This method expects parameters that would be hard to 'hand-craft' to make any use of them and are totally not relevant to your scenario.
What you are realy looking for is
- either custom object mapping between viewmodels and business objects where you manually assign one object property values to another
- or taking advantage of libs/frameworks such as Automapper or ValueInjecter which take care of object mapping hassle away from you
- or a mix of both

Model layer dependency on MVC attributes

We have an MVC3 project that uses nHibernate; there is a separate model project that contains all the model classes which is used by the repository and service layers. The models make use of data annotations like DisplayAttribute and RequiredAttribute from System.ComponentModel.DataAnnotations.
There are also attributes such as RemoteAttribute that are contained in System.Web.Mvc.
This of course means that the model project now has a dependency to a particular front end technology.
Assuming the solution could have other front ends what would be the best way to handle this dependency link?
RemoteAttribute does not belong in the model, since it specifies a controller/action to validate the property on the server, and the model shouldn't have knowledge of concepts like controller, action or route. The presentation layer depends on the model, not the other way around.
I would create a view model that inherits the model, overrides the property (must be virtual) and adds the RemoteAttribute. This way you can avoid duplication and mapping, although that's also an alternative.
To reduce dependency between database model and frontend technology, you can use special view model for validation qnd other front end actions in controller and put data from viewmodel to database entity after it.

Instantiate a viewmodel in an action filter?

Q: How do I make an object that is instantiated inside an action-filter available within the action-method?
Background:
I have numerous forms (among other things) in an MVC web site.
Each has its own viewmodel, which inherits from a base type (FormPage).
My convention for these is to name the viewmodel type as the action-name prepended with "Form". So my ContactUs viewmodel is FormContactUs : FormPage.
A number of base viewmodel properties are set identically for all forms, and I have a generic utility functon that I call inside the action method to do this.
Setting the viewmodel, choosing the type based on the action-name and the naming convention, and setting base properties common to all forms from within an action-filter will make this just a bit DRY-er. My only hurdle appears to be figuring out how to make an object instantiated inside the filter available within the action-method.
Q: How do I make an object that is instantiated inside an action-filter available within the action-method?
You could store it in the HttpContext.Items which is available throughout the entire request lifecycle. This being said, a custom model binder seems more adapted to your scenario than an action filter.

Sending a parameter to the controller in ASP MVC 2

I am writing an area for administering several subsites, almost all of the functionality will be the same across each site (add/edit/remove pages etc) and my repository on instantiation takes the SiteIdentity so all the data access methods are agnostic in relation to this. The problem I have at the moment is trying to make my action methods also agnostic.
The URL pattern I want to use is along the lines of:
"ExternalSite/{identity}/{controller}/{action}/{id}"
A naive approach is to have each action take the identity parameter, but this means having to pass this in to my repository on each action as well as include it in the ViewData for a couple of UI elements. I'd much rather have this something that happens once in the controller, such as in its constructor.
What is the best way to do this? Currently the best I can come up with is trying to find and cast identity from the RouteData dictionary but part of me feels like there should be a more elegant solution.
It sounds like you want to use OnActionExecuting or a Custom ModelBinder to do that logic each time you have a specific parameter name (also known as a RouteData dictionary key).
Creating a custom modelbinder in ASP.NET MVC
Creating an OnActionExecuting method in ASP.NET MVC, Doing Serverside tracking in ASP.NET MVC
You have access to your route values in Request.RequestContext.RouteData, so you can make base controller and public property SiteIdentity, in such case you can access it from all actions in all inherited controllers.

Returning ad-hoc view models from ASP.NET MVC2 Controllers

I'm porting an existing system to ASP.NET MVC2. In the current legacy app, the user can select from dozens of available fields to customize CRUD forms for different entities in the domain model, similar to the way ERP systems allow customization of core modules.
My question: I'm looking for a good pattern or example for this kind of behavior in ASP.NET MVC2. It seems to me it's rather like creating a ViewModel dynamically based upon user choices, or perhaps the right approach is data-driven view pages that aren't strongly-typed where I can reflect over the results client-side to determine field headings or something -- if that makes sense :). Or maybe I can drive AutoMapper or similar dynamically # runtime based on user choices?
The underlying domain model is EF4-based and I'm using a simple Repository pattern # present for the ViewModel.
TIA for any input! Michael
If I didn't find anything else that matched the needs and went on to do it custom, I would:
Use the ViewModel with all the fields / not just the ones the user picked.
Pass both the ViewModel and the view configuration to the view
Call some html helper that for each item in the configuration adds a field with the corresponding property in the model
The configuration could be passed as either part of a containing ViewModel or in a separate entry in ViewData
Depending on what you need, building/passing the view configuration could be put in an Action Filter. Alternatively the helper could pull it directly.
A different approach is if you need completely custom fields. I mean user defined fields. If that's the scenario, that's not typed at the controller level already, so I'd pass the list of fields/values to the view. The view can do a foreach on those adding the fields. Again that could be moved to a HtmlHelper.

Resources