I want to put my master pages in a central library so I can use them in several projects without having the maintanance nightmare.
Everything is refactored in a generic and central way, they are all in a "shared" namespace.
But if put them in a seperate project, I can't reference them
I don't believe you can put that actual .master pages in an external library. You can place your own customer MasterPage-derived class in the library, and have your client apps derive from that, but I don't think that's what your intent is, since you're tagged with asp.net-mvc (implying very narrow views without much logic, and probably no code-behinds).
As far as I'm aware, there isn't a way to reference a master (nor, for that matter, an ASPX or ASCX) from an external library. Wish I had better news for you. (And I actually hope I'm wrong; I hope someone else here has figured out a technique for this, as I'd like to use that kind of thing myself on occasion.)
Just for reference's sake, I'll put Phil's mail here too:
Sorry for the late response. You could try using a VirtualPathProvider, but this would require full trust. Other than that, I don't know of any way to do this.
Phil
so there you go.
Related
I've recently started a new project and I'd like to expose an API. Should I put the API controller in a special area (e.g. API) or should I just put them along with the other controllers, or even mix the API action with all the other MVC actions in the controllers?
Aside from numerous answers I could give you, this is something really you can decide. What is logical in your case? What would be more readable?
For example my colleagues like to seperate blocks of code in a technical matter, whilst i like to seperate my systems on functionality.
Just think of yourself being someone that knows nothing of your project, you're going in there for the first time to fix a bug. Where would you expect your code to be placed?
In this case, you can either say okay i'm going to put API stuff in /ApiControllers and your logic for normal controllers in '/controllers'. You could even put controllers in '/controllers' and api controllers in /api/controllers. You can also do somthing like this: 'Users/controllersandUsers/controllers/api`.
This may sound like a dumb question on the surface, but why does the Hot Towel SPA Template include Breeze at all?
I've been spending the last few days learning Hot Towel and its dependencies, and as far as I can tell, nothing in the template actually uses Breeze. Perhaps that is going to change with some future release?
Sure, Breeze is a good library. But it's bound to CRUD methodology and requires you design your ApiControllers a particular way. (Metadata, SaveChanges, etc.) see here
It also guides you to Entity Framework. While this is more of a soft-dependency, since Breeze also shows a sample without it, it still guides you down a similar pattern of implementation using a modified repository pattern.
If you are using a NoSQL datastore, or CQRS patterns instead of CRUD, then Breeze becomes very difficult to use. There are alternative libraries for data access that work well in this style, such as AmplifyJS.
But the rest of Hot Towel is excellent! I especially like Durandal. So the question begs, if the template isn't actually doing any data access - why include any data access component at all? It would be better to ship it without Breeze, and if the end-user wants to use Breeze, or Amplify, or whatever - then so be it. The rest of Hot Towel would continue to shine as a great SPA implementation.
Matt - Good question. Since I created it I guess I should answer :)
When I built the template I had a focus on providing enough to get folks going with the right tools, and just enough starter code to guide the way. I did not want anyone ripping out code. I'm not a fan of templates that start you down a path and make you remove tons of files and code and change direction. Those are samples.
Samples are good. In fact, samples can be excellent (like the other templates, which I feel are more like samples). Those serve another purpose: to show how you can do things.
Back to the Hot Towel template ...if I include code that uses Breeze, I would be tempted to add a datacontext.js and a model.js on the client. They would contain data access code and code to extend the models on the client. Then I would be tempted to add a controller, some server side models, an ORM and a database. Once there, I'd want to use the data in multiple screens, which leads me to more Knockout and caching with Breeze. Then I might be tempted to add editing, which would lead to change tracking. Soon I have a full blown app. Or more conservatively, I have a sample again. While these approaches would provide more guidance on how to put these together, they would not help you "get started" with a template where you can just start building and adding your own code. If I stop short of some of these features, it's still walking down a road that requires you to change how I did it.
As it stands today, HotTowel is pretty darn close to a template in the truest sense. You create a new project and you are off and adding your own code.
You could argue (and you may be) that Breeze shouldn't be in there since I don't use it in the template. Nor do I use moment.js, BTW. However, I argue that they are both excellent libraries that I would not want to build a CRUD based SPA without them. Breeze is flexible, as you suggest, so you don't have to walk a specific path.
The best way to understand the value of Breeze is to build an app that has its features but without Breeze. Then you can see how much code that takes and how involved it is. For one such example, see my intermediate level SPA course at Pluralsight where I do exactly this: http://jpapa.me/spaps
So you ask "why Breeze?" ... because I strongly recommend it for building a SPA.
Thanks for asking and good luck !
Thanks for asking the question.
John, as author of HT, has offered an answer. I, as a principal of the Breeze project, am inclined to agree with him :)
HotTowel generates a foundation for you to build upon. It is not the building itself.
It is a foundation intended for a specific kind of application, a CRUD application based on a specific set of cooperating JavaScript and ASP.NET technologies. Breeze is a contributor ... but not the only one. Knockout, with its MVVM design and 2-way data binding, is particularly well-suited to the data-entry tasks typical of CRUD apps.
Of course there are other kinds of SPAs. There's an important class of apps that mostly present information and accept little user input. Such apps don't benefit as much from data binding and the people who write them can get pretty hostile about data binding in general and KO in particular.
My point is that HT targets a particular class of application ... one that happens to be immensely successful at least when measured by sustained popularity. It delivers the goods for people who build those apps. It may not be the right starting place for other kinds of apps.
It is true that the easy road to Breeze runs through Web API, EF, and a relational database. Take those away, and you may writing more code on the server (and a little more on the client). That may be the perfect trade-off for you.
The authors of Breeze would like to make that path easier. I don't think BreezeJS makes it harder. I don't understand your statement "Breeze becomes very difficult to use." Have you tried it?
Your client can communicate with any HTTP resource in any manner you chose. It is pretty easy to use existing Web API controllers (albeit easier with Breeze Web API controllers). You can use amplify.js if you prefer (btw, you can tell Breeze to make AJAX calls with amplify). You don't even have to use the Breeze EntityManager to query and save data if you don't want to.
The rest of BreezeJS may still have value for you. There remains plenty of work to do after you've figured out how you'll retrieve and store data and whether you prefer Entity-ChangeSet style or Command/Query style.
You'll have to find answers to these questions:
How will you shape the raw JSON data into bindable objects?
How will you hold on to these objects and share them across multiple screens without making redundant round-trips to the server?
How will you navigate from one object to a related object as you do when binding an Address to a combobox of StatesAndProvinces?
How will you track changes?
How will you validate them?
How will you store some or all of the data in local storage when the app "tombstones"?
Breeze can help with these chores even if you don't want it to query and save for you.
And if you're answer remains "I'll do all of that myself, thank you" ... well, removing Breeze from your HotTowel project is as easy as:
Uninstall-Package breeze.webapi
I asked this question over on the asp.net forums, and nobody seems to know what i'm talking about. I'm not sure why that is, but I figured I'll ask here to see if there is anyone with some insight.
Back when MVC2 was released, it included a sample AccountController that wrapped the built-in Membership and FormsAuthentication classes with testable interfaces and services. I read a lot about this, and it was considered a good thing because the Membership and FormsAuthentication classes were not easily testable.
Recently, I generated a new sample project with my up to date (SP1, MVC3, Tools Update, etc..) environment and I find that the AccountController is now much simpler. Gone are the Interfaces and MembershipService and FormsAuthenticationServices. The sample now calls the Membership and FormsAuthentication classes directly.
I'm wondering if anyone knows when this happened and why? Are the testable interfaces no longer considered correct? Was there a technical reason to change this?
The best I can figure is that this happened as a part of the change to remove a possible vulnerability when passing return url's on the open url.
Any insight?
The new model resembles EF's code first approach where the AccountModel is a POCO class. Inside the new API there are no longer abstractions but direct calls to static methods such as FormsAuthentication.SetAuthCookie making this code difficult to unit test. Not something I would recommend basing your real world application code upon.
And, yes, they have fixed a vulnerability inside the LogOn method which was not verifying if the return url is a relative url before redirecting.
Personally I would recommend you using abstractions in order to weaken the coupling between your controller logic and its dependencies. This will make the code easier to unit test.
For me passing all those domain models to views without using view models are total anti-patterns and I have never bothered with them. I simply create an empty project and do the things my way. I mean in the default project they even use ViewBag for Christ sake!
The Account Controller was changed with the MVC3 tools update (When they also included the use of jQuery via Nuget)
I am sorry for possible misleading about the title, but I have no idea for a proper title.
Feel free to edit.
Anyway, I am using ASP.NET Web Forms, and maybe this isn't how web forms is intended to be used, but I like to construct and populate HTML elements manually. It gives me more control.
I don't use DataBinding and that kind of stuff. I use SqlConnection, SqlCommand and SqlDataReader, set SQL string etc. and read the data from the DataReader.
Old school if you like. :)
I do create WebControls so that I don't have to copy-paste every time I need some control, but mostly, I need WebControls to render as HTML so I can append that HTML into some other function that renders the final output with the control inside.
I know I can render a control with control.RenderControl(writer), but this can only be done in (pre)Render or RenderContents overrides.
For example.
I have a dal.cs file where is stored all static functions and voids that communicate with the database.
Functions mostly return string so that it can be appended into some other function to render the final result.
The reason I am doing like this is that I want to separate the coding from the HTML as much as I can so that I don't do <% while (dataReader.Read()) %> in HTML and display the data. I moved this into a CodeBehind.
I also use this functions to render in the HttpHandler for AJAX response.
That works perfectly, but when I want to add a control (ASP.NET Server control (.cs extension, not .ascx)) I don't know how to do that, so I see my self writing the same control as function that returns string or another function inside that control that returns string and replaces a job that would RenderContents do, so that I can call that function when I need control to be appended into a another string.
I know this may not be a very good practice.
As I see all the tutorials/videos about the ASP.NET MVC, I think it suite my needs as with the MVC you have to construct everything (or most of it) by your self, which I am already doing right now with web forms.
After this long intro, I want to ask how can I build my controls so I can use them as I mentioned (return string) or I have to forget about server controls and build the controls as functions and used them that way?
Is that even possible with ASP.NET Server Controls (.cs extension) or am I right when I said that I am not using it right.
To be clear, I am talking about how to properly use a web forms, but to avoid data binders because I want to construct everything by my self (render HTML in Code Behind).
Someone might think that I am appending strings like "some " + "string", which I am not. I am using StringBuilder for that so there's no slowness.
Every opinion is welcome.
You need to stop thinking in terms of "controls" and webforms. MVC is a completely different way of constructing applications.
I also hate the automatic renderers in WebForms, they produce horrible html that never makes any sense. However, you dont want to be writing your html in your codebehind and passing it around as strings, thats just nasty. Your presentation code is mixed in with your logic, AND youre writing HTML in c# strings!!!
So, MVC... Instead of "widgets" that do interacty things with codebehinds and postbacks, yours view ONLY display data and contain forms to allow you to post to the controllers.
Because of this, you can strongly type your views to a Type, and then access the data you pass to it from a controller via the Model property. The equivalent to UserControls are Partial Views (ViewUserControl) which can be used to modularise your rendering code for types. For example, you might make an Address partial to which you pass your Person's Address property every time you need it rendered. This way you aren't repeating html all over the place.
P.S. A single file for all your DAL?
I hope I never ever have to work on an app you wrote in this manner. If your application is string-heavy then something is wrong.
Agree with #sliderhouserules, the way you are using MVC framework is awful. You must forgot all your "old school" techniques.
You should never use SqlCommands, SqlReaders, etc. in the code of the pages. You should pass to the view only a model (e.g. View(bar)) and it will be better if you avoid usage of
ViewData["some magic string"] = bar
Every time when you will use "old school" technique 2 mans and 2 cats will be killed :).
Also it's better to use some ORM (Object-Relational Mapper) like Linq2sql, NHibernate, SubSonic, etc.
If you need in samples of good application design please look at SharpArchitecture. It has a very good architecture and implementation and may help a lot. It has one sample (with Northwind db) and one more sample will be added soon.
Also look at CodeCampServer. It has very good architecture too.
It's better to look at the code of these projects instead of looking videos because existing videos can't demonstrate good sample of architecture, just a simple usage of functionality.
About server controls, you may use them if they can be used without 'runat="server"', like PlaceHolder. And you may create them too, but you shouldn't load any data in them directly. If you don't want to copy-paste html you should review your code and you should refactor it. Every duplicated code should be moved to MasterPages of UserControls (ascx ones).
And once more, please spend some time to look at these samples. You'll save your nerves and time in the future when you'll need to update the app or fix something. At the first look they can be hard to understand but this is only at the first look.
Hope this helps.
#lopkiju, I think that the MVC pattern would serve you much better than your current WebForms solution if you want that much control over the output HTML.
You can use Web Forms this way as you already do, but it is not designed to be used this way, so it will be a pain.
More detail
In my opinion, read some articles about the Separation of Concerns (also known as SoC) principle. If you apply it correctly, it can save you many-many headaches when you'll debug your app, and also for those people who you work with (eg. those who may have to read or modify your source code).
My other tip for you is this:
You are right that you shouldn't do things like <% while (dataReader.Read()) %> in your View code. But perhaps there are better ways to make it more elegant than your current way.
I think you should consider using some sort of ORM for these purposes. (LINQ to SQL, or even NHibernate.) If you get it, it will be much simpler. So much that you may not want to use DataReaders directly again. :-)
What I recommend for you
Simply, read the NerdDinner tutorial, and build the samle app by yourself step-by-step.
After that, try to build a similar app that serves a different purpose by yourself while applying the same rules and design that you applied to the tutorial.
I'm pretty sure you have the expertise to do it, and after actually doing something with it, you can pretty much get the feel of it.
The tutorial also explains and includes the principles I mentioned above, which will be very much use to you.
If you want the ASP.NET MVC path, you can set up controls as ASCX and they will simply be tags filled by the controller. It may not be old school enough for you, however.
You can create your full UI in code behind, if you so desire. This can include creating the HTML in routines.
But, I would recommend, if you are sticking with ASP.NET, reconsidering the bind model over the DataReader.Read() and output + loop. It is not only old style, it is highly inefficient and hard to maintain.
ASP.NET MVC does create a much looser ASPX, as it is just a view. And there is a much greater separation of code and UI. But it will not fit with the old school model either.
Have you considered using micro-templates? Dave Ward has a good example of of a client side data repeater that is uses micro-templates for layout after making a call to a page method. This sounds like this is more in the spirit of what you are trying to accomplish and can still be integrated nicely with WebForms.
The side effect will be that you will not rely on passing around HTML and can isolate your presentation from your logic.
I'm currently working on an asp.net-mvc content management system. It would be incredibly useful to be able to deploy nested applications e.g. /shop to have a separate app inside. Or even another instance of the cms.
I've found some information around talking about limiting the inheritance of the web.config but I've no idea how this maps to an MVC application. I'm hoping as its essentially the same stack it will just run. Nothing is ever that easy though.
If anyone has any experience doing this I would be really grateful. The idea of one big application to rule them all is not at all nice.
Si.
To be honest you biggest hurdle is going to be creating the routes and making sure they don't interfere with routes already in the system. After you get that working the rest is easy as pie.
The first thing you will need is an HttpModule that will be inserted in to the web.config under the . This module will be used to register and custom ViewEngines or Routes that you want to register. You do this in the same way that you do in the Global.asax but instead of putting them in the Application_Start you put them in the static constructor of the HttpModule. This is so they are only loaded once like Application_Start.
By do the above you will have created a module that is easily transportable and doesn't require the implimentor to modify their Global.asax code to get your stuff to work.
The second thing you probably want to do is create a custom configuration in the web.config to set stuff like the root path of your application. This will be prepended on to the route when you are setting it up in the HttpModule. Also you can use this to store customization information that is not appropriate for the database.
Last but not necessary is that you may want to create a custom ViewEngine that knowns and understands your folder structure. This is only necessary if you want to store the views in a different path than the default views, in order to minimize conflicts.
Check out the Grouping Controllers with ASP.NET MVC from Phil Haack.
Hope it helps,
Bruno Figueiredo
I've gone down this road before (with /blog), but found it to be doable but complicated and difficult to maintain. Instead I ended up using subdomains:
www.example.com
shop.example.com
blog.example.com
These are much easier to maintain because you can just have them work as separate websites in IIS. And, of course, you can always redirect www.example.com/shop to shop.example.com.