I'm working on creating n-tiered application where I will have two separate project
1) project EF (where it will have all my edmx...)
2) project MVC 4 (internet application.)
In my EF i have, I have my .edmx file and it generate couple of classes with all props as show below (as sample)...
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
public partial class Requester
{
public int Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
<//more...........>
}
everything is good so far!!
Back to MVC project
Now I will be creating a new Controller in my MVC project and when I'm trying to create Scaffolding and provide the Controller name and Controller expects a Model so the real question is:
What Model should I be passing here?
should I have the same class that EF created? or should I be creating another Model in my 'Model Folder` (MVC) and bind it? if yes than am I not creating duplicate property if I go ahead and create my same Model in MVC model Folder project?
What I'm trying to do? : Well my purpose of this exercise is to have my Data Access Layer (DAL) totally separate from MVC project.
any thoughts?
I'll suggest to create a view model so you can decorate the properties with view related stuff (i.e. UIHint). Also, this view model will be a reduced version of the class (for example, it can contain just the id of a related object instead of the whole object) making it easier for using as action parameters.
Also, you are talking about objects here, try not to think about "Data".
MVC really needs to be renamed VMVC - ViewModel View Controller.
The models in MVC have nothing to do with EF, Persistence, or your domain. They are a composition of multiple sources of data/settings/things which are represented/required in the View.
So create new View Models for your Views.
Edit:
All examples/tutorials which use EF Code First Models as View Models, are terrible tutorials / examples. They teach you bad practice because in the real world, you would never, and should never use those directly in your view.
The ViewModel is a composition or aggregation of data that's going into your view. For example:
If you had a product detail page, you might get the Product information from the Database, the availability of the product from a Web Service, your Shopping Cart from some Cache.
These would be composed into a ViewModel which represents the View that you're displaying. And rendered.
ViewModels should not be shared between views because if you change a ViewModel you change the meaning of the views that share that View Model.
Related
I am working on MVC and i started learning Umbraco, I didn't get how to bind the umbraco page with mvc controller get method to show the database values. can anyone suggest any url or video?
Thansk...
What you're looking for is Umbraco route hijacking.
You can read about it here.
https://our.umbraco.org/documentation/reference/routing/custom-controllers
It's easiest to demonstrate with an example : let's say you have a Document Type called 'Home'. You can create a custom locally declared controller in your MVC web project called 'HomeController' and ensure that it inherits from Umbraco.Web.Mvc.RenderMvcController and now all pages that are of document type 'Home' will be routed through your custom controller! Pretty easy right :-) OK so let's see how we can extend this concept. In order for you to run some code in your controller you'll need to override the Index Action.
So, basically, you "simply" need to create a controller named after your document type, so for example, a document type with the name "TextPage" would need a controller called "TextPageController". Now, if you read through the documentation, you'll find that your "TextPageController" will need to inherit from the RenderMvcController. Here's an example how to achieve this.
public class TextPageController : RenderMvcController
{
public ActionResult Index()
{
return View("~/Views/TextPage.cshtml");
}
}
This forum link may help you:
https://our.umbraco.org/forum/developers/razor/38242-Umbraco-MVC4111-Surface-controller-using-an-AJAX-form
I'm using Attribute Routing in WebAPI. My question is more on creating sub-folders under controllers in WebAPI (not in MVC, I'm using Areas for that)
I searched what kind of impact it would cause to the existing routing pattern and mostly they referred like adding custom routing template in WebAPIConfig.cs. But since I'm using AttributeRouting, is it really required to create custom template??
I tested my code and it seems to be working fine without any custom templates and I'm also able to achieve modularization by creating sub-folders under Controllers folder but would like to know the best practice and solution.
No - as you've found you don't need to create custom templates if you're using Attribute Routing.
The underlying method (MapAttributeRoutes) calls into the Controller factory to find all classes that inherit from Controller and then checks those for a Route attribute - so where they sit in the namespace hierarchy shouldn't matter.
If you are trying to mix Attribute and Convention routing and have sub-folders for convention based routes then you will need to define a custom template.
FYI: There is one small 'catcha' that you need to be aware off when (re)organizing your controllers in subfolders using attribute routing. Make sure your controller class has a unique name! Otherwise attribute routing gets confused and will not work. To illustrate:
// File: ~/Controllers/Customers/DetailsController.cs
namespace MyProject.Controllers.Customerss
{
[RoutePrefix("~/api/customers/{id}")]
public class DetailsController: ApiController {
[HttpGet]
public IHttpMessageResult GetItem(int id) {...}
}
}
and
// File: ~/Controllers/Orders/DetailsController.cs
namespace MyProject.Controllers.Orders
{
[RoutePrefix("~/api/orders/{id}")]
public class DetailsController: ApiController {
[HttpGet]
public IHttpMessageResult GetItem(int id) {...}
}
}
Although, cleary having different routes and certainly pointing to different controller classes it will throw off the attribute routing. By changing the controller classes to CustomerDetailsControlller and OrderDetailsController the routing issue resolved itself.
I am new to MVC. In my application the view page created using razor by designing it from another html page designer. I have doubt that how to access the html controls from the corresponding controller. For example, i create a controller named Home and and corresponding view. Added a text box into it.
<input id="name" type="text" name="txtName"/>
Now i want to get and set the value in text box from controller without using script.
Just like
txtName.text="...."
Is that possible..?
It sounds like you are thinking of things from a Web Forms perspective, e.g. controls, setting properties server-side.
MVC allows much better separation of concerns, that is, each piece should play its part without being tightly coupled to other parts. Having a controller set a property of a textbox in a view means that there must always be a textbox in that view and would tightly couple the controller to that particular view. It is not directly possible and it would be a bad idea even if it was.
That's where view models come in:
// M - model
public sealed class MyViewModel
{
public string Name { get; set; }
}
// V - view
#model MyViewModel
// (usually code to begin a form goes here)
#Html.TextBoxFor( o => o.Name )
// C - controller
public ActionResult MyActionMethod()
{
var model = new MyViewModel { Name = "Hello" };
return View( model );
}
It may seem like an extra step (it is) but it is cleaner, far more flexible, and far more test-friendly.
It would only be possible with another request to the server (e.g. POST, GET) because the Controller code can only run server-side. After processing another request, you could use a ViewModel to populate your HTML text-box while rendering it, but I doubt that is what you are looking for.
If you are familiar with desktop programming (e.g. Window's Forms) and you are looking to immediately change and process fields on an HTML page, you will need to use JavaScript. If you are unfamiliar with web-programming, or even just new to the MVC paradigm, I suggest you try out a few MSDN tutorials.
I'm writing a site for our poker league. In the _Layout page I would like to include some database information like the next game date and how many games of the season are remaining. I presume _Layout is the best page as I would like this information on ALL pages.
How can I get this entity framework data there? I presume a controller is not the way as _Layout is only a template for other views that use their own controllers.
Any information or resources would really be appreciated.
Thanks in advance,
Paul.
You should create a base controller from which all your controllers inherit.
There you can overwrite the method OnActionExecuting() and load that data from the DB, the cache or whereever and pass it to the Viewbag:
public class ControllerBase {
protected override void OnActionExecuting(ActionExecutingContext ctx) {
Viewbag.LayoutPageData = ...;
}
}
Or you can use a base class for all your Viewmodels and pass the data with the model to the view.
Your Layout page is a view also, so you can strongly type it with a viewmodel class.
You can also use Html.Action like in this sample
http://kazimanzurrashid.com/posts/viewdata-or-viewbag-avoid-dependency-pollution-in-asp-dot-net-mvc-controller
you can display your database information in a partial page exemple "_NextGameDate.cshtml"
then you have to include it in _Layout.cshtml page by :
#Html.Partial("_NextGameDate.cshtml");
I'm really looking more for validation here of my understanding of MVP before I approach the project lead about refactoring major pieces of our application...
We presently have an expanded MVP pattern where we have the following projects:
Entity (Defines POCOs)
Model (Defines data layer configurations (EF code first - not that it matters here))
Task (all business logic in a well ordered grouping)
Presenter (page (or page type) specific, calls tasks, defines and works with all View interfaces)
View (in the form of different websites (internal, external))
Currently in the View layer I frequently see code that works directly with the Entities, so an ASPX page (could be php, whatever) which has to display a list of entries does so like this:
public interface IEntityList
{
ICollection<Entity> MyEntities {get;set;}
event EventHandler OnReportRunning;
}
public class EntityList : IEntityList
{
public ICollection<Entity> MyEntities {get;set;}
private void RenderEntities()
{
OnReportRunning(this, null);
if (MyEntities != null)
{
ArrayList entityList= new ArrayList();
foreach (var entity in Myentities.OrderBy(e=>e.Field))
{
var formatedEntity = new {FullName = String.Format("{0}, {1}",
entity.LastName, entity.FirstName), UserEmail = entity.Email};
entityList.Add(formatedEntity);
}
ddlEntities.DataSource = entityList;
ddlEntities.DataBind();
}
}
}
I'm of the opinion that this violates the intent of the presenter layer. I think the view should expose the DropDownList (ddlEntities) or whatever other controls it has, and the presenter should be the point at which ALL knowledge of the Entity layer stops.
And thus my question - SHOULD the View (V) layer of an MVP (perhaps it should be MPV) architecture have any knowledge of the model (M)? Or am I right in thinking that the only work the View layer should do is direct reactions to events from the controls, and that all real presentation work (binding, formatting involving entities, etc) should be done in the presenter layer, and that the Presenter layer is SUPPOSED to be strongly aware of the actual View layer (IIS vs. Apache vs Mobile etc)?
What you are suggesting with the "only events" on the view is Passive View flavor of the MVP, I prefer the Supervising Controller, where you do everything except the data binding in the presenter. I usually have something like view.BindData() in which view asks presenter for data and bind it (but of course, the presenter controls when the BindData() will be called, so it ensures that there is some data to bind before the call is made).
I also think that event communication instead of directly calling presenter methods is a overkill in 95% of cases.