Where to put Model-specific code when using .dbml designer? - asp.net-mvc

I'm building an asp.net mvc application for users to enter an essay contest. I have an Essay table in sql server 2005. I created my domain models by dragging over the tables in the server explorer and saving the layout as, what I've named DAL.dbml.
I'm now trying to implement input field validation in the business layer using methods mentioned in Chapter 11 of Pro ASP.NET MVC Framework by Steven Sanderson. But, the author didn't create his models like I am, so I'm at a loss as to where to put my model-specific code.
I considered putting it into the auto-generated DAL.designer.cs file, but that seems problematic.
I also tried creating a new class, EssayRequired.cs, where I made EssayRequired extend Essay. This almost worked.
It successfully showed all of the validation errors.
But when it comes time to actually save the record:
EssayTable.Context.Refresh(RefreshMode.KeepCurrentValues, essay);
EssayTable.Context.SubmitChanges();
I'm getting this error:
The type 'DomainModel.Entities.EssayRequired' is not mapped as a Table.
Any ideas as to what I should do now? Is there a better place to put domain-specific code that won't get wiped out if the db table changes and I have to delete and re-drag the table over?
Or is there a way to tell the app that the EssayRequired object should land in the Essay table.?
Thanks, Scott

You can create a partial Essay class in the same namespace as the dbml file.
public partial class Essay
{
partial void OnCreated()
{
// handle additional stuff on creation, for instance.
}
}

Related

In asp.net-mvc, Is it wrong to move my "EditViewModel" classes outside my MVC web project?

I have an asp.net-mvc site that pretty much is a CRUD app but I also do some adds & updates outside the webview (upload from spreadsheets, etc). Based on this article, I am trying to get as much of the logic outside the MVC project into a seperate shared project so i can reuse the same code in all scenarios and I am trying to isolate and seperate my "read" viewModels that are binding to UIs for display from the "edit" viewModels that represent what is being posted to the server on a form post.
I have a number of projects in the solution (domainobjects, importexport,etc) that are shared with other solution plus the MVC project has the following directories in the MVC project
Controllers
Views
ViewModels
Scripts
EditViewModels
My ViewModels folder represents the objects that I am binding to my views (a container object that usually includes:
A domain object and
A bunch of IEnumerable of SelectListItem to populate UI dropdowns, etc
something like this:
public class OrderViewModel
{
public Order MyOrder {get;set;}
public IEnumerable<SelectListItem> OrderTypes {get;set;}
public IEnumerable<SelectListItem> Sizes {get;set;}
}
My EditViewModels folder represents the objects that i am posting from forms to the server so they are usually simpler flat objects with just primatives that i then populate a domain object with before adding or updating my database like this:
public class OrderEditViewModel
{
public int Id {get;set;}
public int OrderTypeId {get;set;}
public int SizeId {get;set;}
}
My main question is when i have a method in my Controller class that usually looks like this (simplified):
public ActionResult Update(OrderEditViewModel order)
{
var existingOrder = _repository.GetOrder(order.Id);
existingOrder.Name = order.Name;
existingOrder.Size = _repository.GetSize(order.SizeId);
existingOrder.Price = order.Price;
_repository.Save(existingOrder);
return Json( Result = "Success");
}
I am trying to figure out how to get as much code as possible outside the MVC project but that forces me to move all of my classes in the EditViewModel outside of the MVC project so those objects can be reused.
Does anyone see anything wrong with having these "Post" data structure classed outside the MVC projecdt. Given its a "viewmodel" class it feels wrong to move it away from the view but I don't see any other way to share this code outside of the MVC project. Maybe the "viewModel" name here is just wrong possibly?
Your View Models are specific to your views, and should not be relevant to anything else. They contain things which nothing else should care about, such as your select lists. As such, they should stay in your UI.
The article appears to me to be creating a situation in which the business logic depends on the UI (or at least the UI Model.. ie View Model), and I think that is the wrong approach. The UI should be able to consume the business logic without the business logic being aware what the UI is. It could be a web site, a fat client, a mobile client, a web service, etc... By making this logic depend on your view models, you now are making any future services that are not web based depend on those.
This is, however, a simple CRUD app, and in simple CRUD apps you can often take a lot of shortcuts because it's just not worth the extra engineering effort. I wouldn't normally pass a domain object to the view directly in the View Model. But in this case it's probably the best choice.
If you want to do it "right", however, then you need to create more separation of concerns. Your domain and ui layers need more separation. You create separate view and domain models, and then map between them. This prevents the business layer from knowing anything about the UI.
I would probably create a service layer that handles your logic. For instance:
_orderService.UpdateOrder(order.Id, order.Name, order.Price);
In my case, i make a difference between read(view-)models and write-models.
Read models are very specific to the view, they can contain select lists and formatted and localized content. You should not move this models outside of your ui-project. Of course you can make a separate assembly with your models, or you can make one assembly per module, but you should never consume these models from your domain layer.
Write models - in my opinion - are not that specific to your UI. Instead they represent the data that is required by the command (e.g. SaveUserCommand). They can contain validation attributes, so your domain layer can validate them easily and they can be shared by domain layer and UI. In my project I have one class per command (e.g. SaveUserCommand, EditUserCommand, DeleteUserCommand) and related models (SaveUserModel, EditUserModel). Somebody will comment, that the they also contain some UI-specific code (e.g. the IClientValidateable itnerface for attributes or the attributes itself) and at least the IClientValidateable interface is a problem that I am willing to ignore to reduce the number of models. My experience with this approach (I also tried others) shows, that these models are very easy and it very easy to bind to these models.
Sometimes you will also have the problem, that you want to show some additional information in the edit-view. Instead of adding all this information to the viewbag, I will have another model, for example:
class UserEditModel
{
string Password;
}
UserEditViewModel
{
DateTime Modified;
UserEditModel Edit;
}
So my advice:
Create write-models that have all the data and validation logic that is specific to your use cases.
Create view models that contain all data you want to display and try not to use the ViewBag.
If you have a form, add the write-model to your view model. The write-model has all the data that will be sent back to your server via POST and then directly to your domain layer.
I use four "layers" in two assemblies
{application}.app assembly with three namespaces, just a regular class library project.
1) {application}.model for domain model
2) {application}.data for data using repository pattern
3) {application}.services for all business logic
{application}.WebUI assembly for the UI, this is the MVC project
Controllers only call services and services get and update data through the repositories.
There is an services API for every operation your app has to do, i.e.
OrderServices.Update (existingOrder)
OrderServices.Approve (existingOrder)
Services layer only know domain models, and controllers just assemble the viewmodels, using the domain models gotten from services, to send them to the views and prepare the domain models using the viewmodels gotten from the views to send them to the appropiate service.
This way you can eventually create an {application}.WebAPI or whatever that uses the same {application}.app assembly reusing all of the buissiness logic and keeping viwemodels where they belong (the WebUI project)
Hope this helps.
Best regards.
You could use a service architecture of your project , where all function and db queries are in this files and which you could using just by adding this code
IOrderService<Order> service = new OrderEntityService();
and use it like
service.Create(Order) or service.Update();
Whats strange to me is you're taking care and effort to layer out your app as much as possible, but you're still letting your MVC controller contain a lot of your logic. You're trying to share the objects and models, but the logic to add a new OrderEditViewModel is not shared, its stuck within that controller.
What I try and do is create a "helper" or "logic" class for each of my controllers. That logic or helper class is then injected into my controllers and wrapped in an interface. My controller can save, edit and remove items through my helper class, but has no knowledge of how its actually doing that.
I have then shared these logic classes along with the models to other projects, allowing a lot of code re-use. The problem is just ensuring that none of the "HTTP'ness" of the controllers sneaks into your logic classes, as these must be usable in a console or winforms application. So you have to be pretty strict and wrap a lot of things like HTTPSession or HTTPContext into interfaces that can then have non HTTP implementations..
Well, I understand your situation and also tends to a DDD (Domain Driven Design) solution as #MystereMan suggests.
I have an approach that sepparates the "Models" in 3 categories:
ViewModels: Have all the information necessary to display content data in the UI
RequestModels: Have all the information necesssary to send data, post/get/etc.)
AutoBindModels: Have all the information that is injected my MVC binding model (cookies, sessions, etc..)
And the most important, for all that classes I use as DTO/POCO's, actually they have no UI dependent code just properties/calculated properties and could be easily in any other project to be referenced by an UI project.
You could also create a Controller class that act as a Service outside ASP.MVC project and extend or inject it in your MVC controller.
Hope it helps...
I never reuse (Edit)ViewModels objects (this is not entirely true, I often share one EditViewModel between Create and Update but not always).
I design my ViewModels for specific Views. Therefore, I don't have to compromise my ViewModels when the UI changes (it changes all the time).
I take this as far as creating two distinct ViewModels even if they are identical. I'm done refactoring shared ViewModels..
I would answer yes to your question.
Hope it helps.
OrderEditViewModel and OrderViewModel are both 'ViewModels' end of the day. IMO, they may stay together in the same project even in your same 'ViewModels' folder. You may though create a sub folder under ViewModels for your 'EditViewModels'.
Now as you want to clean/tidy up the controller actions, you may want to use AutoMapper or ValueInjecter. You are mapping domain entity and view models manually. That is a tiresome job. With AutoMapper you can do something like:
var customerInfo = Mapper.Map<CustomerViewModel, CustomerInfo>(customerViewModel);

Howto: simply read SQL Server database to MVC 4 view?

I am relatively new to MVC. I am trying to just display the contents of a remote SQL Server table on a page. It is READ ONLY, and nearly everything I find online is utilizing the Entity Framework or something similar which is overkill for what I am after. I just need to print all the rows from a table out to a view.
So my questions are:
should I just hack the sqlconn and everything into the view that I want the data printing out to?
Or should I add the sql in that view's controller?
Create a model and somehow get that data back into the view?
I know step #3 is the 'correct' way to do it, however I am looking for something simple and quick. :)
Thanks everyone!
You say EF is overkill, but that's the easiest way to do this. Maybe use Linq to SQL, since that's more lightweight. This is all there is to it:
Generate the EF / L2S entity classes
Instantiate the database context in the controller, and get all records
Return the IEnumerable records to the view
In the view, use #Html.DisplayForModel()
Here's a simple example. Note that returning the database entity classes is considered bad practice, you should map / automap them to a View Model type class first.
Home Controller
public ActionResult Index()
{
MyEntityModel[] items = MyDatabaseContext.GetAllRows();
return View(items);
}
Home/Index View
#model IEnumerable<MyEntityModel>
#foreach (MyEntityModel item in Model)
{
#Html.DisplayFor(m => item)
}
Without EF / L2S it's almost as easy, but you'd have to create your own entity / wrapper class for the database records and populate them manually.
There are also scaffolding projects for MVC that will generate repository and controller classes, as well as Razor views. See for example MVC Scaffolding on NuGet.
Once you get used to forcing yourself to use Entity Framework for even your "small" applications then and only then will you truly understand that is it the simplest way.
Sure, if you come from a background of memorized ADO.NET dataset/datatable/datareaders etc.. then sure you have projects with "canned" operations that you port over and modify but it is truly just old and cost you more time in the long run.
Use EF
Use multiple projects in a solution
Use a repository pattern if you can, it pays off in dividends for reasons you will discover
Keep your controllers "skinny"
Dont' use a "ViewModel" just to use / do it.
The SOC of having View and Controller are critical, but the Models folders does not need to be used, you can wire things up without it if you want, just pay attention to where your "model" is and abiding by SOLID principle etc..

Editing only a partial model in ASP.Net MVC

I'm quite new to MVC, and stumbled on a problem. I've googled a lot but couldn't find a solution.
I'm using ASP.Net Membership with roles.
Lets say I have a model of a product with attributes:
Name
Art no
Category
How can I implement this so different roles cab only be allowed to edit parts of the object?
(Let's say one role cannot change the category of a product, for example.)
Is it possible to have different Views for the same Model or different Models for the same object?
If I leave out some of the properties, they will have NULL value when I save them.
I tried using #HTML.HiddenFor(...) but then the validation for those fields failed.
A ViewModel sounds like it would do the trick. For all but the most trivial of scenarios, you will get into problems when you tightly couple the Model and the View.
If you havent used them before, a ViewModel is simply a class (model) for the specific view you are rendering. You can customize required properties and validation on the ViewModel and then bind it to the Model, so the structure is most more flexible and easy to work with.
There is a detailed intro at ViewModels http://kazimanzurrashid.com/posts/asp-dot-net-mvc-viewmodel-usage-and-pick-your-best-pattern
EDIT
You could then have a ViewModel for each of the role, although if you are only looking to protect a property from being updated by certain roles there should be other solutions such as setting the html input to disabled and then testing on the server that the category value is still in its original state (note you should always perform such a test as the Post request can be altered).

How to update Model in MVC

I'm wondering how you keep a constant value of the Model in an ASP.NET MVC framework. Like when adding something to the Model through the view. You go back to an action in the controller but where do you keep the Model? Is it a private in the controller? or is it passed back and forth from the view to the controller because if it gets big then you are passing alot of data back and forth to add/delete a single item from the Model.
Also any small examples to show this?
Thanks
What are you referring to? Are you meaning a database table loaded up into an object such as Ruby on Rails's ORM -- typically the 'Model' is a series of interfaces or domain objects that load data into objects from the database .. or more simply just the database period.
Please be more specific. There are many MVC frameworks and many different kinds of 'Models'
I think you should check out a ASP.NET MVC tuturial like NerdDinner (from "Professional ASP.NET MVC 1.0"). Scott Guthrie has posted a html version of the tutorial on his site. It's a fairly simple site that they build in the tutorial, and is a great intro to ASP.NET MVC (in my opinion).
There are also some good tutorials on the ASP.NET site.
Hope these help you with .NET MVC, it's a great framework to use!
You can pass the model to the page and you can then use UpdateModel(model name) within your controller.
Each member in the model must be a property with a getter and a setter.
On the page you can hold the data in say a hidden field if you need to maintain the value outside of state.
If you have problems using UpdateModel then you can use the following in your controller;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(int? id, FormCollection collection)
{
string commentText = collection["myFieldName"];
}
This will normally get your values from the model.
Hope this is what you were asking.
Think of the model as a data transfer object. In a list, display only or edit page, you pull it out of a data layer as a single object or a list of objects. The controller passes it along to the view and it gets displayed.
In the case of an insert, a new data transfer object is instantiated upon post back and is updated with the posted values. Then sent back to the the data layer for persistence.
In the case of an edit, it comes from the data layer on the HTTP GET request and is used to pre-populate the HTML form. Then on post back, the data transfer object gets updated with the posted values and sent back to the the data layer for persistence.
Definitely checkout NerdDinner or Stephen Walther's samples.

Problems with model using LINQ to SQL when adding a strongly typed view

I am trying to create a simple task manager solution based on the Nerd Dinner tutorial
weblogs.asp.net/scottgu/archive/2009/04/28/free-asp-net-mvc-nerddinner-tutorial-now-in-html.aspx.
EDIT: I have removed the http:// on these urls because I have not got enough rep to add links into a post.
I have built my model as shown here: nerddinnerbook.s3.amazonaws.com/Part3.htm
It is identical except that Dinner is a task and RSVP is a project.
Relationship task.projectId -> project.projectId
I have more fields in these tables but I have kept the public partial task class in the model simple so far to match the tutorial.
My question is that when I try to add a new view and in the dialog I select "strongly typed view" my model class for the task does not show up in the drop down, anyone know why??
Probably a bit vague, i am just trying to get some ideas on why this could be happening.
I thought maybe my namespace was incorrect somewhere or my class was not public but it is.
I have got a reference to my repository in my controller by doing
TaskRepository taskRepository = new TaskRepository();
and the controller has a using reference to TaskManager.Models;
All confusing me.
I don't know how the dialog picks classes (other than it requires a clean compile), but you can just choose any random class and then edit the first line of the resulting aspx to substitute the class you prefer.

Resources