As I am learning MVC 3 it has become apparent that naming is critical to getting the Dbase-Model-Controller-Views to talk together.
Is there an already existing list of naming conventions that should be used in a MVC application?
Something like:
Table names (plural)
Model names (singular of Table Name)
View folder must be same name as controller class (ie Contract -> derived from ContractController)
The only major convention is that controller class names must end with "Controller". Any other conventions simply represent best practices and are not required for your application to work.
The table and model naming conventions you mentioned are there because they make the code "read" better (Select * From products where category = 1; Products.Insert(new Product()))
MVC automatically looks for a view that matches the name of the action method and it starts looking in a folder that has the same name as the controller. However you can easily trump that by specifying the view name in your view result (return View("MyCustomName"))
Not many name conventions exist that will break your application, other than the few such having your controllers end with "Controller" and name inference of the "View()" call from the action name.
MVC is based on the ideology of convention over configuration, so as I found out slowly, there are many conventions that are useful to follow, I have yet to come across a list though. They are subtle and very convenient... usually.
Related
Most examples of Web API that I've seen show URIs in this format:
/api/values/ (returns all records)
/api/value/{id} (returns a specific record)
I can think of times I would not like this URI convention, but for my current project it's perfect. Though, it's not working for me and I don't know what I could have done to effect this. For me, I can have one or the other - singular or plural.
If my controller class is named ValuesController, then my Web API is
/api/values/
/api/values/{id}
If my controller class is named ValueController, then my Web API is
/api/value/
/api/value/{id}
I used ADO.NET Entity Data Model to create several entities in model designer. All have a singular naming convention. For example, Activity, State, Country, User, etc. Though, EF appears to create plural database tables no matter.
I created APIControllers for each of these entities. I've tried 2 naming conventions with my controllers - both plural and singular, but I am not seeing the expected (and desired) results with the URIs. The plural and singular Web API are always the same no matter what I try.
FYI, I just checked the default API that is created automatically (ValuesController). To return all records I have to specify /api/values/ and to return a single record I have to specify /api/values/{id} - both are plural and I'm sure it wasn't that way by default.
What effects this? Where is the logic that configures/recognizes a distinguished form of the URI for plural and singular?
The default route that is configured in Web API's RouteConfig.cs file specifies a parameter named controller, similar to this:
routes.MapHttpRoute("Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional };
When you're making a call to either /api/values or /api/values/{id}, the route value for your controller will be values in both cases. Consequently, the controller that Web API resolves by convention will be the ValuesController.
(Note that there's no automatic pluralization performed whatsoever. You can implement a custom IHttpControllerSelector, if you really wanted to implement that behavior. I strongly recommend not to do that, though.)
I'm building my first MVC project and I have a question about the model.
Each webpage can only contain 1 model, yet my page will require 2 models, one is the search option (the ability to narrow your search such as selecting price range, colour etc) as well as the data.
Is it really as simple as creating a new Model, similar to a ViewModel which in this case would only have 2 properties, a SearchModel and a ProductModel?
Yes, there are really two "models" which is sometimes confusing. There's the "View Model" and the "Domain Model." The view model is passed directly to and from the view. The domain model describes the real-life domain that you're dealing with and is what the database persists. Often, they are the same thing, such as if you're displaying information for a single real domain object (e.g., a car). If you have two domain models that go on one page, you should make a view model with both as properties.
If you are looking to have two models in a view then this question might provide useful information:
multiple-models-in-a-view
Edit:
A good example is the 'Manage' view in the default 'Account' controller of a fresh mvc app. It uses a partial view to handle the changing of a user's password. Whilst both views are using the same model type it shows how to implement a partial view. In this case both the main view and the partial are submitting to the same method on the controller, hence they need to use the same model (which is a parameter for the controller method). But if the partial were to invoke a different controller method then the submitted model could be different. Hope this makes sense :)
There is a naming convention to use underscore prefix for views which are not accessed directly (partial view, layouts, etc.) in ASP.NET MVC razor. I am not sure whether I should to use this prefix for view which is accessed only from child action.
No, you should not. As you said, prefixes are used by convention for views not accessed directly. But if child action has view, it means it IS accessed, so prefixing that view name with underscore would mean breaking another convention (more robust and conventional one :)) - naming views according to action names. So don't prefix them, or you will have to explicitly specify view name in child action.
For my application (ASP.NET MVC 3.0 RTM, Razor View Engine), I would like to use DataAnnotations for my models. If I keep the model classes within the web project, I can have resx resources in App_GlobalResources or App_LocalResources without embedding the .resx into .resources files.
Ignoring newly spawned AppDomains and other considerations, this is ideal because changing something minor in a localized resource like a typo or incorrect translation doesn't require compilation.
However, after moving my models to a class library I don't see any way to keep .resx files as the output and still use DataAnnotations attributes. Am I missing something?
The problem lies in the way the attributes find resources. For instance, a "Name" property might look like this:
[Display(Name = "MyEntity_Name", ResourceType = typeof(Validations))]
[Required(ErrorMessageResourceName="MyEntity_Name_Required",
ErrorMessageResourceType = typeof(Validations))]
[StringLength(150, MinimumLength = 2)]
public string Name { get; set; }
This requirement for a strongly-typed resource wrapper has become the bane of my existence over the past 24 hours.
I've tried to genericize the wrapper, but it seems like the validation attributes specifically look for a property on the wrapper called MyEntity_Name for the DisplayAttribute and MyEntity_Name_Required for the RequiredAttribute. I haven't dug any deeper into the DataAnnotations code to see if there is some magic I can pull off. I was hoping someone else encountered this and had any ideas.
The Question
Is it possible to use DataAnnotations ValidationAttributes (including DisplayAttribute) in a class library without embedding the resx files into .resources files?
The Gotchas :(
In the future, I'd like to move from resx to database-driven resources with very minimal coding effort. I can't do that right now because of limited resources (no pun intended). So, I want to avoid bypassing the ResourceProvider. Also, I want to avoid rewriting or wrapping all of the attributes in the System.ComponentModel.DataAnnotations namespace.
Am I missing something?
Yes, you are missing View Models. Controller actions take/pass view models from/to views and not models. View models are classes which are specifically tailored to the needs of a given view. They contain the only the required properties and the proper formatting for the given view. A view model could be a subset of a model or an aggregation of multiple models (it depends on the requirements of the view). View models are always defined in the web project because they are very tightly coupled to views. So it is view models that you should localize/globalize with resources.
Example of workflow:
The controller action is invoked and it queries the repository to fetch a model
The controller maps the model to the corresponding view model (AutoMapper could you here)
The controller passes the view model to the view and the view displays it with the proper formating/localization.
Conclusion: models should not be formatted/localized or they become more difficult to reuse.
If I have a table Orders with fields CustomerID, OrderID and OrderDate, then the "Linq-to-SQL classes" generated class will be called Orders, with members called CustomerID, OrderID and OrderDate. So far so good.
However, if I then do Html.LabelFor(m => m.OrderDate) then the generated text will be "OrderDate" instead of "Order Date".
I tried using Order_Date as the field name, but that didn't work. Is there any way to get it to infer a better display name?
[I know that I can use data annotations to specify the display name explicitly, but I really don't want to do that for all my classes/members - I just want it to work by convention.]
I suggest you create your own HTML Helper for this, something like Html.MyLabelFor.
The rules to apply from here are up to you. You can simply split the word by case.
There is a solution available for your requirements contained within the answer to this question. Asp.Net MVC 2 LabelFor Custom Text.
This method takes advantage of existing MVC 2 architecture to place conventions over the entire *For rendering methods instead of one off HTML helpers and without having to re-label everything with spaced property names.
How to "DRY up" C# attributes in Models and ViewModels?
Essentially what your doing is overriding the default ConventionModelMetadataProvider behavior of MVC 2 and providing hooks for you to insert your own opinionated conventions.