Which method of re-use is better in this case - ascx or other - asp.net

I've got an ASP.NET application that shows grades for different kinds of students. Some students have a self-paced course that doesn't include late penalties and quizzes, and others have a standard classroom course that does.
So, when displaying a student's grade, I determine which category that student falls in, and then render the grade appropriately.
Right now I do this with conditional statements, but I thought about making each case into an ascx file (i.e. one ascx with a gridView for self-paced, and one with a gridView for classroom, each of which calls data population methods in my data access class).
I may need to re-use this functionality elsewhere in the app, to show grades on different pages, so some kind of custom control seems warranted.
Is this approach feasible?

This approach sounds good to me - controls are designed to help you reuse code. I think a set of UserControls would work just fine here.

This approach is definitely feasible, and it makes it easy to change if you want to modify the way the HTML is displayed at a later time (new styles, etc.). I would say ASCX is a good approach.

Make sure you are adequately separating your calculation logic from the display. I would use a class to actually determine the grades (perhaps multiple classes with a nice inheritance tree) to actually do the match, and the just render appropriately in your user control.
If you have multiple classes (or some property for determining what type a particular isntance is) you could also then easily create a factory to instantiate user controls for you where you will get the correct user control type, based on the calculation passed.

Here's how I understand your app:
You have students that are registered for courses.
Students can be standard or self-paced.
The grading method per course is different for different types of students.
You need a way to display the correct grade based on the student's type.
I would think you could get by with a single control for displaying grades but would definitely make sure to separate your logic. Maybe something like:
public class Student{
public GradingType Type {get;set;}
public List<Course> RegisteredCourses{get;set;}
//etc...
}
public class Course{
//etc...
}
public static class GradeCalculator{
public static CalculateStudentGrade(Student student, Course course){
//grade logic...
}
}

Related

ViewModel classes VS defining an Exclude Bind list on the domain class

I have a model class named Server, it contains many navigation properties and properties, which I want to prevent users from binding it. So I find two approaches of doing so to avoid over-posting attacks.
The first approach is to go to each model class and define an Exclude Bind list , with all the properties and navigating properties that should not be bind by users , as follow:-
[MetadataType(typeof(TMSServer_Validation))]
[Bind(Exclude = "Technology,IT360SiteID, VirtualMachines, TMSServer1,DataCenter,OperatingSystem,Rack,ServerModel,TechnologyBackUpStatu,TechnologyRole,TechnologyStatu ")]
public partial class Server {
}
}
The second approach is to create a view model class , with only the properties that can be modified by users as follow:-
public class ServerViewModel
{
public int ServerSize { get; set; }
[Required]
public String OperatingSystem { get; set; }
public String Commnet { get; set; }
}
I find that the first approach is faster to implement , as I only need to define the Exclude list, while the second approach will require me to create view-model class for each of the domain classes. So which approach is recommended to use and why ?
Thanks
Over-posting occurs due to the default model binder not knowing which fields you actually included in the form.
It will try to map all values in the request to object. Attackers can use your form to add additional fields to
query strings/form post data and add properties as part of the request. The default model binder won't
know the difference. Your Server class will deactivate once the mapping is complete and the update is processed.
To prevent over-posting, set the annotation to include fields in the binding, or create a ViewModel like you mentioned in your code.
So which approach is recommended to use and why ?
Both annotation and ViewModel allow binding only on specified fields, but when you use ViewModel you will not bind against business objects or entities, and you will only have properties available for the input you expected.
Once the model is validated, you can then move values from the input model to the object you used in the next layer.
k. Soctt Allen has a good article about which approach is better, you can take a look at by the following link:
http://odetocode.com/blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx
It's difficult to tell without seeing the rest of your code, but in general I'd say using the ViewModel is probably a better approach for the following reasons:
You separate your view from your business logic
It is safer. If in the future someone adds a property on Server and forgets the Bind-exclude, you're exposed to over-binding without knowing it. If you use the ViewModel-approach you have to explicity add new properties
Maybe this question is a little bit ambiguous because the answers are going to be based on opinions or something. But I'll try to answer it the best I can and indeed is kind of my opinion. So this is the way I see it:
First approach (Bind attribute): Is faster to implement because you only need to add on your class the name of the property you don't want to expose, but the problems comes when you want your class to exclude some properties for one feature and other properties for another feature, and you can't add fields and sometimes in MVC, the views need more fields that the ones provided by the model class and then you're gonna need to use ViewBag or something else. This approach is very handy for fast and smalls projects, but I still don't like to use ViewBag (For aesthetics reasons)
Second approach (ViewModels): Is more work, and more time but at the end (again in my opinion) you get a cleaner and ordered code and you don't need to use the ViewBag, because you can have the perfect object to send to the view depending on what this View needs, so if you a have an object with different views, again depending on the needs, they could share the same ViewModel or they could have a ViewModel for each one. If you have a solution or a big web project, this approach is going to be very handy to keep an ordered code.
Let me know.

Comment system design

Here is my current comment system design:
I'm developing it for a website that has lots of areas, blogs, tutorials, manuals etc etc. As supposed to developing a separate comment table for each (tblBlogComments, tblTutorialComments) etc etc, I'm trying to go for a one structure fits all approach.
This way, I can turn the comment system into a web control, and just drop it on any page that I want comments for. It means I only have one set of rules, one set of code files to maintain.
The only problem is, is coming up with a 'nice' way to determine which section (blog/tutorial/manual) belongs to.
For example, one solution would be:
tblComment
-------------
Section (int)
SectionIdentifier (int)
Where 'Section' maps to a unique to each part of the site, EG:
Blog = 1
Articles = 2
Tutorials = 3
...
A SectionIdentifier is some sort of unique ID for that page, eg:
ViewBlog.aspx?ID=5
This would be section 1, identifier 5. So now, a comment with Section = 1, SectionIdentifier = 5 means it's a comment for blog entry number 5.
This works great, but at the cost of maintainability, and a solid structure, as the SectionIdentifier is anonymous and no relationships can be built.
Is this design OK, or is there a better solution (IE some sort of parent table for a comment?)
In Codd's original designed for the Relational Model, a foreign key could reference multiple primary keys in different tables, and the referential integrity was valid if any one table contained the value.
Unfortunately, SQL is a pale reflection of that original vision, since it does not provide this ability, as you have noted.
One standard work-around is to create a new relation that holds the keys to all of the others. But that's not a very good solution in this case, since it creates a point of contention if lots of inserts are happening at once.
The way I would handle this is to create a value—let’s call it a Comment-Anchor—that you can put into every table that is to have comments. This value (unlike all the other keys in a well-designed database) should be a GUID. Then each comment can have a Comment-Anchor that indicates which value it is in reference to.
By making it a GUID, you can always insert unique values in your blog or tutorial or whatever, without contention. You do not have to maintain a master-list of Comment-Anchors anywhere, and no section contends with or is blocked by any other section.
This will work well for the normal use-case of finding all the comments for a single blog entry, for example. To go the other way, from comment to the thing that is being commented on, you could put a flag in the comment table identifying which table is being refrenced, but I wouldn't do that. I would just search all the tables, maybe with a view or something. The reverse query would be rare enough, that I don't see much point in maintaining infrastructure for it, and the flag would be redundant data, which is the bane of RDBMSs.
One additional benifit of this system is that it is easily extensible. If you create a new type of data, or decide to add comments to an existing type of data, then you need only add the Comment-Anchor column to the table. No additional work must be done on the database side. And even the middleware portion that handles the comments does not need to be modified in any way, since it has no knowledge of what sorts of things take comments.
For a table design, I would model it as closely as possible to what the class structure seems to be in this case. From what you have said, this is what it looks like (roughly):
Section <- Post <- Comment
So, you'd have:
a Section table (eg. blog, articles, tutorials, etc.)
a Post table (for the individual posts in each section)
a Comment table (for the comments on each post)
Each post would have a reference to it's section, and each comment would have a reference to it's post. The DB could have the references as nice, clean foreign keys, and the classes could have lists on one or both sides of the relationships as your app needs them.
To me, that seems like a nice, simple, flexible structure that doesn't complicate things and still allows you to hang extra bits like edits and votes off of it.
I would steer clear of creating an id column that defines a different relationship depending on another column in the same table. For instance, in your example SectionIdentifier could represent any number of foreign key references depending on the value of Section. That skeeves me out on general principle. It also leaves several benefits of modern RDBMS platforms on the table since it's not supported.
How is your general architecture for these different sections layed out? I've worked with a few CMS's that would require each of your sections to share a common base entity, calling it a "module" or "plug in". Each instance of a given module then has it's own id, which is used to map to any content required by that specific instance.
If this is a viable architecture direction for you, you could also use that ModuleInstanceID as the foreign key for your comments. You'd just have to decide how you register a given type of module/plug in as being a valid target for comments.
Anyway, can you shed a little light on how your sections are put together under the hood?
It seems that. Your comment system consists of many kind of comment (tblBlogComments, tblTutorialComments..... etc). I would like to suggest you to adopt strategy design pattern.
Let's say. You have a IComment interface. And All kind of comment class implements IComment interface.
interface IComment
{
int ID {get; set; }
int Section {get; set; }
....
}
class BlogComment : IComment
{
....
}
class TutorialComment : IComment
{
....
}
And a WebControl which only knows how to deal with IComment
class WebControl
{
IComment _comment = null;
public WebControl(IComment comment)
{
_comment = comment;
}
}
Of course you need a CommentCreater to loads comment data from database and builds the comment object.
public static void main()
{
var creater = new CommentCreater();
IComment comment1 = creater.CreateBlogComment()
WebControl webcontrol = new WebControl(comment1);
......
IComment comment2 = creater.CreateTutorialComment()
webcontrol = new WebControl(comment2);
........
}
That way your web control can just treats all kind of comment in the same way. No matter exactly what kind of comment it is. and you can also just maintain the CommentCreater to build each kind of comment class correctly.

Adding and removing items dynamically in one View with Entity Framework and MVC

I've been at this same question in different forms now for a while (see e.g. Entity Framework and MVC 3: The relationship could not be changed because one or more of the foreign-key properties is non-nullable ), and it's still bugging me, so I thought I'd put it a little more generically:
I feel this can't be a very unusual problem:
You have an entity object (using Entity Framework), say User. The User has some simple properties such as FirstName, LastName, etc. But it also has some object property lists, take the proverbial example Emails, to make this simple. Email is often designed as a list of objects so that you can add to that object properties like Address and Type (Home, Work, etc). I'm using this as an example to keep it generic, but it could be anything, the point is, you want the user to be able to add an arbitrary number of these items. You should also be able to delete items (old address, or whatever).
Now, in a normal web page you would expect to be able to add these items in the same View. But MVC as it seems designed only makes it easy to do this if you call up an entirely new View just to add the address. (In the template for an Index View you get the "Create New" link e.g.).
I've come across a couple of examples that do something close to what I mean here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
and
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
The problem is, although the sample projects on these sites work fine, with mock model objects, and simply lists (not an object with a child list), it's a different thing if you actually want to do something with the posted information - in my case save to database through the Entity Framework model. To adapt these cases to that, all of a sudden I'm in a maze of intricate and definitely not DRY code... Juggling objects with AutoMapper and whatnot, and the Entity Framework won't let you save and so on (see above link if you're interested in the details).
What I want to get at is, is it really possible that this is such an uncommon thing to want to do? Update a child collection in the same View as the parent object (such as the email addresses in this case)? It seems to me it can't be uncommon at all, and there must be a standard way of handling this sort of scenario, and I'm just missing it (and no one here so far has been able to point me to a straighforward solution, perhaps because I made it too abstract with my own application examples).
So if there is a simple solution to what should in my view be a simple problem (since the design is so common), please tell me.
Have you tried updating the project at your link to Steven Anderson's blog to bind to a complex object? Create a class in models called Sack and give it a single property and see if you can get it to work.
public class Sack
{
public IEnumberable<Gift> Gifts { get; set; }
}
It only took me a minute to get it up and running as I think you intend. The improvement I would have made next would be to add an HtmlHelper extension that is essentially the same as Html.EditorFor(m => m.SomeProperty), only call it something more meaningful and have it interface with the prefix scope extensions provided in the project.
public static class HtmlExtensions
{
public static IHtmlString CollectionEditorFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
{
if (/* type of expression value is not a collection */) throw new FailureToFollowTheRulesException("id10t");
// your implementation
}
}

How do you decide on the means of passing model data from asp.net mvc controllers to views?

There seem to be multiple means of passing model data from controllers in asp.net mvc to views. Its not clear to me if there's a recommended approach in the mvc v1 and v2 releases or if like most things in life, it depends. I've seen several approaches:
Option 1 - Populate the controller's ViewData dixtionary in either an icky string-based indexing way with casting in the view, or the in a strongly typed way by creating a strongly typed custom model class and passing that via ViewData.
Option 2 - Use ViewData.Model, which I'm not sure I even understand.
Option 3 - Use ViewPage.Model, in which case I'm not sure how you pass the model data from the controller.
I've seen a number of posts poo-pooing options 1 and 2 but I don't understand why. These posts seem to highly recommend 3 in most cases.
How do you approach this? Is there a standard way?
Every view 'should' have a specific model. This is sometimes more work so people use short cuts like ViewData, which works but is just not as clean and type safe in my opinion, so I prefer to have everything in the view's model.
You can then make all your views stongly typed. This is a very clean way to do so. Then in your controller you just call the view like:
YourViewModel model = new YourViewModel()
{
// initialize the data here
};
View(model);
Then in your views you can access all the data via ViewPage Model and it is all type safe and enforced from the controller as well.
EDIT from comments:
You don't need to use ViewData at all if you don't want. You can encapsulate all the data your view needs in a model. Just like the example you quoted with ProductsListViewData. It's just a model that contains all the items that were going to be stored in the ViewData. Both ways work but when you encapsulate it in a class (preferred method where everything is in the model) then all the bits and pieces are strongly typed.
ViewData is a generic container so even though you can just put anything you want into it, it is not type safe and therefore not as 'clean'. It comes down to preference and maintainability. There is only option 1 and 3. Your option 2 is misunderstood and is just option 3 in reality. There is no ViewData.Model just ViewPage.Model.
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
This might be of some help:
When is it right to use ViewData instead of ViewModels?
(I know the following answer is highly arguable, but it's just the way I like to do it)
I would say use ViewData for simple data-tasks, and use the Model for the main purpose of the View. Check out Rob Conerys ViewData helper-classes here to give them a bit more Strongly typed feel:
http://blog.wekeroad.com/2010/01/20/my-favorite-helpers-for-aspnet-mvc
Using Models for absolubtely everything will bloat your project with hundreds of models just to achieve the smallest thing. I mean if you have a User-setting page, you would normally pass a User-model into the view, but if you decide to show some related data like Customers related to this User. You're stuck with the following solutions
You might have to add a List property to the User-model in order to expose the customers to the view. This leads to the Customer-property always being applied to the User-model everywhere else in the project - or make a new simpler User-model.
Make a new action that returns a partial of customers, which you can use with Html.RenderAction.
OR
you could do ViewData["Customers"] = myRepo.GetCustomersRelatedTo(user); // or something like that.
and (if using Robs helpers) in your view:
<%= Html.RenderPartial("CustomerList", Html.ViewData("Customers")) %>
add a PartialView called CustomerList that takes IEnumerable
In my humble opinion this is a cleaner solution and sure - you end up with a magic string here and there, but I'll stick to this approach until someone shows me a project with not a single magic string.
Use the tools we have in the Framework to get the job done. and Keep it simple s... ;)

Asp.net mvc 2 custom view model: where would the validation attributes go?

I've been chugging along OK with the use of data annotations made on buddy classes so far.
When it comes to a more complex view that requires a custom view model--one that includes a few select lists, for example...would I need to then transfer my validation attributes to the view model class?
I was planning to pass the full custom view model to populate an "Edit" view, but was hoping to just receive a simple object in my "Save" action.
Where are the flaws in this plan, or is the whole thing just one big pile of fail in the first place?
Thank you.
You're still validating that data that is ultimately going back into the database. So in order to keep your application DRY, you are best off to use the Buddy Classes for the original Model.
Edit
note: this doesn't exactly have anything to do with your question
I personally prefer extend the original Model for anything "Edit" related and I prefer to use a ViewModel for "Display" only (Details pages, List pages, etc).
Example: here's my buddy class, and in it I've added a "RegionName" property that I use in the Edit Page display, but it doesn't have anything to do with the database. You can do a similar thing with custom input data that you want to validate before manipulating it into "database usable" data. I use the RegionID in the database, but I prefer to use the friendly name for the visitor instead of the ID integer
<MetadataType(GetType(UserMetaData))> _
Partial Public Class User
Public RegionName As String
End Class
Public Class UserMetaData
<DisplayName("region name")> _
<Required(ErrorMessage:="region name is required.")> _
Public Property RegionName As String
End Class
Your view model will still inherit the validation from your base model.
Don't know if this helps but I put my validation attributes against my model so that wherever i use the model i get the same validation. not ideal for some projects i realise.
actually, i put the attributes agains a partial class rather than my model because 90% of the time my model comes from a linq 2 sql file in my data repository
my controller then simply checks if the model is valid or not and the view does nothing except display data and errors really.
unsure if this is what you're asking though

Resources