ASP.NET MVC architecturehttp://forums.asp.net/t/1817296.aspx/1?ASP+NET+MVC+architectureThu, 28 Jun 2012 17:27:21 -040018172965037029http://forums.asp.net/p/1817296/5037029.aspx/1?ASP+NET+MVC+architectureASP.NET MVC architecture <p>Hello</p> <p>I have a question about ASP.NET MVC architecture. I don't understand some things clearly.</p> <p>For example, I have an ASP.NET MVC application with MS SQL 2008, which uses standard Membership and additional table named &quot;Users&quot; to extend information about user:</p> <p></p> <pre class="prettyprint">CREATE TABLE [dbo].[Users]( [ID] [int] IDENTITY(1,1) NOT NULL, [UserId] [uniqueidentifier] NOT NULL, [Firstname] [nvarchar](max) NULL, [Lastname] [nvarchar](max) NULL, [VoteIteration] [int] NOT NULL, [Type] [int] NOT NULL, [Image] [nvarchar](max) NULL, [TwitterLink] [nvarchar](max) NULL, [TwitterName] [nvarchar](max) NULL, [FacebookLink] [nvarchar](max) NULL, [FacebookName] [nvarchar](max) NULL, [LinkedInLink] [nvarchar](max) NULL, [LinkedInName] [nvarchar](max) NULL, [Introduction] [nvarchar](max) NULL, [SendDailyDigest] [bit] NOT NULL, CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], CONSTRAINT [IX_Users] UNIQUE NONCLUSTERED ( [UserId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[Users] WITH CHECK ADD CONSTRAINT [FK_Users_aspnet_Users] FOREIGN KEY([UserId]) REFERENCES [dbo].[aspnet_Users] ([UserId]) GO</pre> <p><br />I use Entity Framework to get this data.</p> <p>I have 3 similar pages, where should I show similar, but a little different data.</p> <p>On Page1 I should show:</p> <p>Firstname <br />Lastname <br />Email <br />Image <br />Introduction <br />LinkedInLink <br />LinkedInName <br />FacebookLink <br />FacebookName <br />TwitterLink <br />TwitterName <br />SendDailyDigest</p> <p></p> <p>On Page2 I should show approx:</p> <p></p> <p>Firstname <br />Lastname <br />Image <br />TwitterLink <br />TwitterName <br />SendDailyDigest</p> <p></p> <p>On Page3:</p> <p></p> <p>Firstname <br />Lastname <br />Email <br />Image <br />FacebookLink <br />FacebookName <br />TwitterLink <br />TwitterName <br />SendDailyDigest</p> <p></p> <p>seems, task is very easy, but.... I can't sure that I do correctly. I create 3 similar ViewModel classes:</p> <pre class="prettyprint"> public class ViewPage1 { public string Firstname { get; set; } public string Lastname { get; set; } public string Email { get; set; } public string Image { get; set; } public string Introduction { get; set; } public string LinkedInLink { get; set; } public string LinkedInName { get; set; } public string FacebookLink { get; set; } public string FacebookName { get; set; } public string TwitterLink { get; set; } public string TwitterName { get; set; } public bool SendDailyDigest { get; set; } }</pre> <pre class="prettyprint"> public class ViewPage2 { public string Firstname { get; set; } public string Lastname { get; set; } public string Image { get; set; } public string TwitterLink { get; set; } public string TwitterName { get; set; } public bool SendDailyDigest { get; set; } }</pre> <p></p> <pre class="prettyprint"> public class ViewPage3 { public string Firstname { get; set; } public string Lastname { get; set; } public string Email { get; set; } public string Image { get; set; } public string FacebookLink { get; set; } public string FacebookName { get; set; } public string TwitterLink { get; set; } public string TwitterName { get; set; } public bool SendDailyDigest { get; set; } }</pre> <p>then create 3 methods to get data from repository:</p> <p></p> <pre class="prettyprint"> public ViewPage1 UserPage1(string Username) { var query = from i in _dataContext.Users where i.aspnet_Users.UserName == Username select new UserProfile() { Firstname = i.Firstname, Lastname = i.Lastname, Email = i.aspnet_Users.aspnet_Membership.Email, Introduction = i.Introduction, FacebookLink = i.FacebookLink, FacebookName = i.FacebookName, LinkedInLink = i.LinkedInLink, LinkedInName = i.LinkedInName, Image = i.Image, SendDailyDigest = i.SendDailyDigest, TwitterLink = i.TwitterLink, TwitterName = i.TwitterName }; return query.FirstOrDefault(); }</pre> <p>and similar for rest 2. Which things I don't like in it:</p> <p>1. page1 and page2 can be very similar, for example only differences in 1 field, but need to create one more class, one more method. Of course, I can use the same class for both pages, but one field will be not used for one page</p> <p>2. names of classes/methods. They are don't have sense in it. Like ViewPage1, ViewPage2....</p> <p></p> <p>is it correct way to do it?</p> <p><br> <br> <br> </p> 2012-06-22T14:28:33-04:005037085http://forums.asp.net/p/1817296/5037085.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>rover83</h4> 2. names of classes/methods. They are don't have sense in it. Like ViewPage1, ViewPage2....</blockquote> <p></p> <p>You can call ViewModel classes anything you like. It's your application. Not mine or anyone elses. You have to maintain it. Use language that you understand.</p> <p></p> <blockquote><span class="icon-blockquote"></span> <h4>rover83</h4> 1. page1 and page2 can be very similar, for example only differences in 1 field, but need to create one more class, one more method. Of course, I can use the same class for both pages, but one field will be not used for one page</blockquote> <p></p> <p>You can use standard <a href="http://msdn.microsoft.com/en-us/library/ms173149(v=vs.100).aspx"> inheritance</a>:</p> <pre class="prettyprint">public class ViewPage2 { public string Firstname { get; set; } public string Lastname { get; set; } public string Image { get; set; } public string TwitterLink { get; set; } public string TwitterName { get; set; } public bool SendDailyDigest { get; set; } } public class ViewPage3 : ViewPage2 { public string Email { get; set; } public string FacebookLink { get; set; } public string FacebookName { get; set; } } public class ViewPage1 : ViewPage3 { public string Introduction { get; set; } public string LinkedInLink { get; set; } public string LinkedInName { get; set; } }</pre> 2012-06-22T15:07:43-04:005037134http://forums.asp.net/p/1817296/5037134.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>Mikesdotnetting</h4> You can call ViewModel classes anything you like. It's your application. Not mine or anyone elses. You have to maintain it. Use language that you understand.</blockquote> <p></p> <p>I understand it. I mean, that names don't make sense.</p> <p></p> <p>About methods to get data from DB. Is it normal to have 3 similar methods?</p> <p></p> 2012-06-22T15:37:03-04:005037198http://forums.asp.net/p/1817296/5037198.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>Mikesdotnetting</h4> You can use standard <a href="http://msdn.microsoft.com/en-us/library/ms173149(v=vs.100).aspx"> inheritance</a>:</blockquote> <p></p> <p></p> <p>why using common class is bad approach?</p> 2012-06-22T16:58:08-04:005037229http://forums.asp.net/p/1817296/5037229.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>rover83</h4> why using common class is bad approach?</blockquote> <p></p> <p>What happens if one of the subclasses needs another property or a change to an existing property? If you have just one superclass, you might have to go and make changes everywhere the superclass is referenced, even though most places do not need to know about the change.</p> <p>You could just have easily asked - why have separate tables in your database?&nbsp;</p> 2012-06-22T17:38:25-04:005037329http://forums.asp.net/p/1817296/5037329.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>Mikesdotnetting</h4> You could just have easily asked - why have separate tables in your database?&nbsp;</blockquote> <p></p> <p>because tables are fully different and mean 1 entity = 1 table (approx).</p> <p>my example with pages - model of pages are very similar, can be different only in one field. Why I think about it - there are many very similar methods to get data from DB. Each method is used only one time, have ugly name (like &quot;GetUserForPageX&quot;)...</p> 2012-06-22T19:42:44-04:005037359http://forums.asp.net/p/1817296/5037359.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p>You can create one ViewModel if you like and reuse it in a lot of pages. So long as your application works, there is no right or wrong answer - just preferences based on a blend of pragmatism and recommended approaches.</p> <p></p> 2012-06-22T20:40:56-04:005039409http://forums.asp.net/p/1817296/5039409.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>Mikesdotnetting</h4> So long as your application works, there is no right or wrong answer - just preferences based on a blend of pragmatism and recommended approaches.</blockquote> <p></p> <p>I do not agree with you. Application should be flexible to change, code should be easy to understand and easy to localize and fix bugs. Therefore architecture is major</p> <p></p> <p>Thing, which excite me - there are many similar methods to get data from Data Layer without using&nbsp;inheritance. So, if I viewmodel class I can&nbsp;inheritance from base class, but method like&nbsp;</p> <p></p> <pre class="prettyprint">public UserProfileShort UserProfileShort(string Username) { var query = from i in _dataContext.Users where i.aspnet_Users.UserName == Username select new UserProfileShort() { ID = i.ID, Firstname = i.Firstname, Lastname = i.Lastname, UserName = i.aspnet_Users.UserName, Image = i.Image }; return query.FirstOrDefault(); }</pre> <p>I can't&nbsp;inheritance and when I add new field for example I have to add changes to all similar methods<br> <br> </p> 2012-06-25T10:44:49-04:005040008http://forums.asp.net/p/1817296/5040008.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>rover83</h4> I do not agree with you. </blockquote> <p></p> <p>Obviously.</p> 2012-06-25T18:15:25-04:005045167http://forums.asp.net/p/1817296/5045167.aspx/1?Re+ASP+NET+MVC+architectureRe: ASP.NET MVC architecture <p></p> <blockquote><span class="icon-blockquote"></span> <h4>rover83</h4> my example with pages - model of pages are very similar, can be different only in one field. Why I think about it - there are many very similar methods to get data from DB. Each method is used only one time, have ugly name (like &quot;GetUserForPageX&quot;)...</blockquote> <p></p> <p>There is a tradeoff for everything. If you create a monolithic 'God' class/object (see <a href="http://en.wikipedia.org/wiki/God_object">http://en.wikipedia.org/wiki/God_object</a>) it will have the propensity to be difficult to change without affecting other code within it. Typically the idea of 'Separation of Concerns (SoC) and the&nbsp;many different methods like you eluded to that segregate functionality&nbsp;(method &quot;GetUserForPageX&quot;) are actually a good way to have an application that is more resistant to change.</p> <p>Lastly in all the years I have been working with code, adding a new field, is adding a new field. There might be some crafty ways with reflection to dynamically discover all fields at runtime, but typically the addition of a field at least involves some amount of work. The idea is to minimize it and have to do it in as few places as possible, but I am not sure overall that your idea of a 'one-size-fits-all' class or even View is the answer.</p> 2012-06-28T17:27:21-04:00