Comment system design - asp.net

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.

Related

What's the RESTful way of attaching one resource to another?

this is one of the few moments I couldn't find the same question that I have at this place so I'm trying to describe my problem and hope to get some help an ideas!
Let's say...
I want to design a RESTful API for a domain model, that might have entities/resources like the following:
class Product
{
String id;
String name;
Price price;
Set<Tag> tags;
}
class Price
{
String id;
String currency;
float amount;
}
class Tag
{
String id;
String name;
}
The API might look like:
GET /products
GET /products/<product-id>
PUT /prices/<price-id>?currency=EUR&amount=12.34
PATCH /products/<product-id>?name=updateOnlyName
When it comes to updating references:
PATCH /products/<product-id>?price=<price-id>
PATCH /products/<product-id>?price=
may set the Products' Price-reference to another existing Price, or delete this reference.
But how can I add a new reference of an existing Tag to a Product?
If I wanted to store that reference in a relational database, I needed a relationship table 'products_tags' for that many-to-many-relationship, which brings us to a clear solution:
POST /product_tags [product: <product-id>, tag: <tag-id>]
But a document-based NoSQL database (like MongoDB) could store this as a one-to-many-relationship for each Product, so I don't need to model a 'new resource' that has to be created to save a relationship.
But
POST /products/<product-id>/tags/ [name: ...]
creates a new Tag (in a Product),
PUT /products/<product-id>/tags/<tag-id>?name=
creates a new Tag with <tag-id> or replaces an existing
Tag with the same id (in a Product),
PATCH /products/<product-id>?tags=<tag-id>
sets the Tag-list and doesn't add a new Tag, and
PATCH /products/<product-id>/tags/<tag-id>?name=...
sets a certain attribute of a Tag.
So I might want to say something link this:
ATTACH /products/<product-id>?tags=<tag-id>
ATTACH /products/<product-id>/tags?tag=<tag-id>
So the point is:
I don't want to create a new resource,
I don't want to set the attribute of a resource, but
I want to ADD a resource to another resources attribute, which is a set. ^^
Since everything is about resources, one could say:
I want to ATTACH a resource to another.
My question: Which Method is the right one and how should the URL look like?
Your REST is an application state driver, not aimed to be reflection of your entity relationships.
As such, there's no 'if this was the case in the db' in REST. That said, you have pretty good URIs.
You talk about IDs. What is a tag? Isn't a tag a simple string? Why does it have an id? Why isn't its id its namestring?
Why not have PUT /products/<product-id>/tags/tag_name=?
PUT is idempotent, so you are basically asserting the existance of a tag for the product referred to by product-id. If you send this request multiple times, you'd get 201 Created the first time and 200 OK the next time.
If you are building a simple system with a single concurrent user running on a single web server with no concurrency in requests, you may stop reading now
If someone in between goes and deletes that tag, your next put request would re-create the tag. Is this what you want?
With optimistic concurrency control, you would pass along the ETag a of the document everytime, and return 409 Conflict if you have a newer version b on the server and the diff, a..b cannot be reconciled. In the case of tags, you are just using PUT and DELETE verbs; so you wouldn't have to diff/look at reconciliation.
If you are building a moderately advanced concurrent system, with first-writer-wins semantics, running on a single sever, you can stop reading now
That said, I don't think you have considered your transactional boundaries. What are you modifying? A resource? No, you are modifying value objects of the product resource; its tags. So then, according to your model of resources, you should be using PATCH. Do you care about concurrency? Well, then you have much more to think about with regards to PATCH:
How do you represent the diff of a hierarchial JSON object?
How do you know what PATCH requests that conflict in a semantic way - i.e. we may not care about DELETEs on Tags, but two other properties might interact semantically.
The RFC for HTTP PATCH says this:
With PATCH, however, the enclosed entity contains a set of
instructions describing how a resource currently residing on the
origin server should be modified to produce a new version. The PATCH
method affects the resource identified by the Request-URI, and it also
MAY have side effects on other resources; i.e., new resources may be
created, or existing ones modified, by the application of a PATCH.
PATCH is neither safe nor idempotent as defined by [RFC2616], Section
9.1.
I'm probably going to stop putting strange ideas in your head now. Comment if you want me to continue down this path a bit longer ;). Suffice to say that there are many more considerations that can be done.

Communication between Flex module and Application

Ok, modules in Flex are popular but I have no idea why documentation and examples on the different uses of Flex modules can be so scarce.
Anyway, for this question, I will take the classic Employee/Department example. I have a main.mxml that contains an mx:TabNavigator. Each tab is loaded by an s:ModuleLoader.
Tables: Employees {empID,empName,deptID}, Deparments {deptID,deptName}
The Tab Navigator contains only one tab (for our example) called Employee. I have an Employee.mxml module. In that module, I have a datagrid that is populated with Employee details. I use the getEmployees($deptID) function. This function, as you may guess, returns me an array of Employees who work in a particular department.
Outside the TabNavigator, I have a departmentDropDownList that is populated with departments.deptName.
My objective is to load the Employee module when I select a particular department from the DropDownList. I have a changeHandler for the DropDownList that can give me the deptID.
protected function departmentDropDownList_changeHandler(event:IndexChangeEvent):void
{
MyDeptID=departmentDropDownList.selectedItem.deptID;
//var ichild:*=employeeModule.child as IModuleInfo;
}
Now, the million dollar question is: How do I pass this deptID to the Employees module. The latter has an employee_creationCompleteHandler that calls getEmployees(deptID):
protected function EmployeesDg_creationCompleteHandler(event:FlexEvent):void
// I only need to get the deptID from the departmentDropDownList outside the Employee module.
// If I could create a global variable deptID, that would be great!
getEmployeessResult.token=employeeService.getEmployeess(deptID);
}
I have attempted to use [Bindable] variables but without success.
I would appreciate your suggestions.
You can't really guarantee that the deptID will be set when creationComplete runs--it sounds like you're waiting for a server result--so this is probably not the best way to handle it.
One of the things you need to be careful of is directly referencing the full Module Class from the main Application, because the point of modules is that you should not compile in the module Class into the main Class (to reduce file size/load times).
So what you might want to do is create an Interface. This creates a "contract" between the main application and the Module without carrying all the implementation code with it. That might look something like this
public interface IEmployeeModule {
function set deptID(value:int):void;
}
Then, your Module might have code that's something like this:
protected var _deptID:int;
public function set deptID(value:int):void {
_deptID = value;
var token:AsyncToken=employeeService.getEmployeess(deptID);
token.deptID = value;//in case department id changes, you can determine if you still care
}
Note that, though global variables seem like a wondermous idea when your project is small, they are a very bad habit to get into. It can be almost impossible to repair a project that starts out with these and then grows to the point that no one can figure out exactly which of the hundreds or thousands of Classes that have access to a variable are changing it in the wrong way at the wrong time.
You ESPECIALLY don't want to use global variables with Modules, as they can cause really bad problems when the modules start fighting over the definition.
We solved this problem with the use of Cairngorm v2. Think of it as a message bus for ActionScript, one of several. In your departmentDropDownList_changeHandler method we would create a DeptChanged event with the ID as the payload, and send it on the bus to any and all subscribers to that message type. It worked pretty well for us, and made things more event driven, which in some circles is considered a good thing in itself.
#J_A_X I haven't had good luck with using Robotlegs out of the box with Modules. It seems that something goes wonky with the security contexts, even though it shouldn't. I had to use Joel Hooks' ModuleContext to make it work right, even though my needs were fairly basic.

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
}
}

ASP.NET MVC routing based on data store values

How would you tackle this problem:
I have data in my data store. Each item has information about:
URL = an arbitrary number of first route segments that will be used with requests
some item type = display will be related to this type (read on)
title = used for example in navigation around my application
etc.
Since each item can have an arbitrary number of segments, I created a custom route, that allows me to handle these kind of requests without using the default route and having a single greedy route parameter.
Item type will actually define in what way should content of a particular item be displayed to the client. I was thinking of creating just as many controllers to not have too much code in a single controller action.
So how would you do this in ASP.NET MVC or what would you suggest would be the most feasible way of doing this?
Edit: A few more details
My items are stored in a database. Since they can have very different types (not inheritable) I thought of creating just as many controllers. But questions arise:
How should I create these controllers on each request since they are related to some dynamic data? I could create my own Controller factory or Route handler or possibly some other extension points as well, but which one would be best?
I want to use MVC basic functionality of using things like Html.ActionLink(action, controller, linkText) or make my own extension like Html.ActionLink(itemType, linkText) to make it even more flexible, so Action link should create correct routes based on Route data (because that's what's going on in the background - it goes through routes top down and see which one returns a resulting URL).
I was thinking of having a configuration of relation between itemType and route values (controller, action, defaults). Defaults setting may be tricky since defaults should be deserialized from a configuration string into an object (that may as well be complex). So I thought of maybe even having a configurable relation between itemType and class type that implements a certain interface like written in the example below.
My routes can be changed (or some new ones added) in the data store. But new types should not be added. Configuration would provide these scenarios, because they would link types with route defaults.
Example:
Interface definition:
public interface IRouteDefaults
{
object GetRouteDefaults();
}
Interface implementation example:
public class DefaultType : IRouteDefaults
{
public object GetRouteDefaults()
{
return new {
controller = "Default",
action = "Show",
itemComplex = new Person {
Name = "John Doe",
IsAdmin = true
}
}
}
Configuration example:
<customRoutes>
<route name="Cars" type="TypeEnum.Car" defaults="MyApp.Routing.Defaults.Car, MyApp.Routing" />
<route name="Fruits" type="TypeEnum.Fruit" defaults="MyApp.Routing.Defaults.Fruit, MyApp.Routing" />
<route name="Shoes" type="TypeEnum.Shoe" defaults="MyApp.Routing.Defaults.Shoe, MyApp.Routing" />
...
<route name="Others" type="TypeEnum.Other" defaults="MyApp.Routing.Defaults.DefaultType, MyApp.Routing" />
</customRoutes>
To address performance hit I can cache my items and work with in-memory data and avoid accessing the database on each request. These items tend to not change too often. I could cache them for like 60 minutes without degrading application experience.
There is no significant performance issue if you define a complex routing dictionary, or just have one generic routing entry and handle all the cases yourself. Code is code
Even if your data types are not inheritable, most likely you have common display patterns. e.g.
List of titles and summary text
item display, with title, image, description
etc
If you can breakdown your site into a finite number of display patterns, then you only need to make those finite controllers and views
You them provide a services layer which is selected by the routing parameter than uses a data transfer object (DTO) pattern to take the case data and move it into the standard data structure for the view
The general concept you mention is not at all uncommon and there are a few things to consider:
The moment I hear about URL routing taking a dependency on data coming from a database, the first thing I think about is performance. One way to alleviate potentialy performance concerns is to use the built in Route class and have a very generic pattern, such as "somethingStatic/{*everythingElse}". This way if the URL doesn't start with "somethingStatic" it will immediately fail to match and routing will continue to the next route. Then you'll get all the interesting data as the catch-all "everythingElse" parameter.
You can then associate this route with a custom route handler that derives from MvcRouteHandler and overrides GetHttpHandler to go to the database, make sense of the "everythingElse" value, and perhaps dynamically determine which controller and action should be used to handle this request. You can get/set the routing values by accessing requestContext.RouteData.Values.
Whether to use one controller and one action or many of one or many of each is a discussion unto itself. The question boils down to how many different types of data do you have? Are they mostly similar (they're all books, but some are hardcover and some are softcover)? Completely different (some are cars, some are books, and some are houses)? The answer to this should be the same answer you'd have if this were a computer programming class and you had to decide from an OOP perspective whether they all have a base class and their own derives types, or whether they could be easily represented by one common type. If they're all different types then I'd recommend different controllers - especially if each requires a distinct set of actions. For example, for a house you might want to see an inspection report. But for a book you might want to preview the first five pages and read a book review. These items have nothing in common: The actions for one would never be used for the other.
The problem described in #3 can also occur in reverse, though: What if you have 1,000 different object types? Do you want 1,000 different controllers? Without having any more information, I'd say for this scenario 1,000 controllers is a bit too much.
Hopefully these thoughts help guide you to the right solution. If you can provide more information about some of the specific scenarios you have (such as what kind of objects these are and what actions can apply to them) then the answer can be refined as well.

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

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...
}
}

Resources