Many ascx-to-one ascx.cs bug in VS2008 - asp.net

I'm developing second language support for the site. So I made duplicate .ascx and .aspx files for existing ascx.cs and aspx.cs
Most of the time everything works fine.. but suddenly I'm getting:
Type 'ctrl_xxx' exists both in 'c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\d072cc72\b9d5698b\App_Web_xdmblegv.dll', and in 'c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\d072cc72\b9d5698b\App_Web_gkptrzo2.dll' (translated from russian)
ctrl_xxx ctrl = (ctrl_xxx) LoadControl("xxx.ascx");
I have few such strings of code... and same error occurs with one of them. But WITHOUT any changes from me with those files. To fix thaat bug for some time I need to delete solution and website folder and reget them from SS. Maybe there is an issue with solution? Solution was converted from vs2005.

You shouldn't localize an asp.net site by duplicating pages or controls. You use, for example, language specific resource files that are referenced in the one page or control. Have a look at this for a start on how to localize asp.net websites.

I agree with #Joe R, copying code is not a good way to localize. You may feel like you have gone too far down this road to change your approach, but in the long run you will be much happier and more productive with a different solution.
At the minimum I would switch to a different approach for the rest of the localization, finish the project, and then go back later and convert what you have already done to the new method.
Take a look at the following:
Globalization and localization
demystified in ASP.NET 2.0
How
do you localize a database driven
website

If you need a quick fix for your problem, you'll need to give new names to all of the pages and controls you copied. The error comes from having two user controls with the same name (just like it says).
However, everyone else is correct in that you are going about this the wrong way. What happens when you need to change some code? It will cause extra maintenance because you need to make changes in two places. More than likely, you will forget one, and you'll end up wasting a lot of time. If you invest in using language resource files now, you'll save on headaches later. And, I'm not even mentioning the possibility of needing to add an additional language down the road.
Edit
Try the following if you still don't want to use language resource files.
Put the non-language specific code into a separate .cs file. Make sure it inherits from System.Web.UI.UserControl
In ASCX 1, make sure its ascx.cs class inherits from your class you created in step 1.
In ASCX 2, make sure its ascx.cs class inherits from your class you created in step 2.

Related

Best Practices for ASP.NET Webforms Project structure

When using ASP.NET webforms, I see two main ways to structure a project:
1) Have a lot of .aspx files (including code behind files) and maybe some .ascx files (with code behind files.
2) Rely on a lot of .cs files (class files), and have the classes construct everything with Controls.Add(), etc.
The first method above results in a lot of aspx and ascx files and very few .cs files. The second method above results in a lot of .cs files, but very fewer aspx and ascx files.
Is there a "best practices" way to structure project? Does Microsoft recommend one of these techniques? Is there any information on which of the two styles is used more commonly?
I would stick with the first approach. Some controls are extremely tedious (or difficult) to be created progamatically.
Take the GridView or ListView for example, create an *.aspx page with a GridView which has custom templates with template columns. Then run your application, find the *.dll in the ASP.NET temp directory, decompile the class and look how messy and complicated is the code. It would be very difficult to maintain it over time and/or make changes.
On the other hand, having some declarative code isn't bad as long as you try to maintain the balance.
If you haven't done so, check out ASP.NET MVC. If you cannot opt for MVC you can implement MVP pattern with ASP.NET WebForms. These two patterns provide good way to separate presentation, model and routing.
There is nothing wrong with either approach. Which one you use depends on personal preference, feasibility, and requirements.
One issue you may face is that fewer developers will be able to pick up your project and run with it if you use the second approach, or will take much longer to get up to speed with it. You will find a lot more developers that can easily pick up the first approach and go.
Use approach one as much as possible and only resort to approach two when the out of the box controls do not give you the functionality you require - you can create a custom control by inheriting from an existing control in this case. This is not an "either/or" scenario - you should use both approaches judiciously.

Making changes to a precompiled website

As seems my life at present, I have inherited yet another project that needs changing.
However this code has been precompiled (and guess what...)
I have what puports to be some of the source code, and a set of assemblies form the temp folder. However the project is moaning about missing some user controls and a master page in a sub directory.
I cannot see these anywhere in the assembiles I have, and they are not in the code I took from the website. So, where do I find the UI part of precompiled masterpages and user controls ?
You can use an IL decompiler like ilspy or reflector on the compiled website DLL and retrieve the original source code from it.
This is likely to take quite a bit of time and effort, but you should be able to reconstruct most of the missing source this way (though you will probably not have the correct variable names or exactly the same code and definitely no comments).

Why are ASP.NET pages (both forms and MVC) dynamically compiled?

There is a pattern in ASP.NET - whenever there is a piece of markup that generates code (like the .aspx/.ascx files in WebForms or .cshtml files in MVC3), these files are dynamically compiled at runtime. aspnet_compiler will produce another assembly for them, which references your code-behind assembly.
This approach seems awkward to me and I don't understand why it hasn't been discontinued already. A much better approach (in my opinion) is like in Winforms or resource files - you have your .whatever file, and then there is .whatever.desginer.cs file. This designer file is created at runtime as you type. When you compile, the compiler doesn't care about your .whatever file, it just takes the .whatever.designer.cs file and produces a single solid assembly.
This provides several benefits:
You can inherit your forms from each other, similar to windows forms;
You can always see the code that is being generated, possibly adjusting your markup to generate better code;
You can easily instantiate strongly typed instances of your forms;
The only benefit I can see from dynamic compilation is that
You can change the markup file anytime and don't need to recompile the app.
To be honest, I've often wanted for one of the first three benefits, but never for the last one. Recompiling the app to see your changes isn't that big of a deal. Especially since you have to do it anyway when working with code-behind, where the most of your time will be. And when you deliver your app to the client, you deliver it as a monolithic, precompiled block. When you update, you update everything, not just individual .aspx files - there's no point to.
So... why is it like this? What am I missing?
It sounds like you are referring to an ASP.Net Website. An ASP.Net Web Application is like an ASP.Net Website, but uses .designer.cs files and produces a single assembly.
See ASP.NET Web Site or ASP.NET Web Application?.
One thought that comes to mind is that the primary difference between winforms and webforms has to do with the common development model.
Namely, there is a whole class of developers and designers who work strictly in html/css/javascript. They use a host of tools ranging from notepad on up to competing development products to build these pages.
Further, in the case of WinForms, MS has complete and total control of what can make up a form. Any controls that can be dropped on it have to descend from their specified code.
However, with HTML they don't have this same level of control. Spec changes occur out of sync with VS releases, additional features are added that are browser specific, etc. In short, they can't guarantee that a particular element in the HTML file is a valid element at all. All they can hope for is that whatever is sent was done so on purpose and that the browser knows how to deal with it.
Now they have tried to implement a model that provides visual inheritance. It's called "master pages". However, I believe the only tools that properly work with master pages are VS and Expression. Getting the other vendors to go down this path would be nearly impossible. Also, they've added the concept of "nested master pages" such that you can get multiple levels of inheritance out of them.
The code behind model helps to implement non-visual inheritance allowing people to completely revamp page processing (hence how MVCx works).
Which leaves us with the parts that MS does know about. Obviously they do have a .designer file which backs the .aspx pages. This designer file maintains the server control list that is accessible by the code behind. You could add runat="server" to every regular element in an html page (excluding artifacts like css) but this would increase the amount of processing required for the page.
To sum up, I think they've picked the best model they could for web development given the lack of control they have over how the web works. Other vendors have tried similar paths (e.g. Adobe Contribute, previously by Macromedia). I believe some of those even predate MS's model.

ASP.NET project organization

This may be a broad question because part of the problem is that I actually don’t know what the question is. What I would like to know is how you commonly organise ASP.NET applications in terms of placement of pages (aspx), user controls (ascx), server controls and other support classes and utility functions etc. First, let’s assume that there is already some data layer somewhere (perhaps in a different project). This is the not issue.
The issue I frequently face is that create several pages and realize that they need to share some common rendering logic or some utility function, class etc. Another typical case is that some pages become too large so that it seems handy to split them (say into some user controls). What is the best place to put these utility classes, share classes, user controls, server control etc.? Here are several possibilities.
Don’t really care about any organisation and place all types of files next to each other. So in one directory, you may have an aspx files, some cs files etc. This is not really an option probably.
Organize files by types. Let’s say you create a directory for user controls and put all user controls there. OK, but what about server controls and other regular classes? Should they be in special directories as well? It does not sound right. What I dislike most on this is that when you work on a feature (logically related piece of code), you must hunt it all over the place. I think that features and logical sections of your applications should be also grouped on the file system level in some way.
What I would like to have is to have the pages (aspx), user controls (ascx) and handlers (ashx) basically as dummy placeholders sitting in the directory structure organized from the logically according to the point of view of the outside visitor while the actual code (page, user controls implementations, serve control and utility classes) should be placed in s different folder structured into logical namespaces (organized by the modules or features of the application). It seems to me that the only way to achieve this is to manipulate the <%# Page ... %> directive manually.
Does it sound crazy? Am I asking too much? Is there a better way? What are your best practices? Do you know some good examples?
Edit: Another idea. This does not mess up with the generated aspx, aspx.cs and aspx.designer.cs files. One on my original requirements was that I wanted to place the code driving aspx pages to my own location and put it to a custom namespace hierarchy. So what if I simply subclass the aspx classes generated by VS? Let’s say I have a project called MyApp and MyPage.aspx page in it. VS then creates MyApp.MyPage inherited from System.Web.UI.Page. I leave this class be (no code will go there), but create a subclass, say in MyApp.SomeNamespace.SomeSubNamespace.MyPage, inherited from MyApp.MyPage. This way MyApp.SomeNamespace.SomeSubNamespace.MyPage will get access to the autogenerated protected fields corresponding to the server controls of MyApp.MyPage and I’ll get an entire "private" namespace for all the support classes which are related to this page. Any major disadvantages? Another related problem which bothers me is where should this new cs file be physically placed? In web projects, there is a standard folder for it called App_Code, but I’m interested in web applications. Creating a directory in the root of the application (such as Code) does not sound right.
Remember that you can create page classes that don't actually correspond to any markup. We often create base pages that our actual UI pages inherit from. This is a simple way of organizing "base" page functionality. Then when you create your .aspx pages, make them inherit from the base page class, rather than System.Web.UI.Page.
We usually place our base page .cs files into the top level directory if it's a small project, or for slightly larger projects we'll create a "Shared" or similar directory where they live.
However, we also have a huge enterprise web project, and we simply build our webcontrols and base pages into a class library called CompanyName.Web.UI, with a couple sub-namespaces to that. All our actual web site projects import that assembly and all the code for the controls, etc. is elsewhere. This sounds like it might be a good option for you.
If you remember that your .aspx codebehinds can inherit from any class file, it should make it easier for you to organize.

Best way to encapsulate component that includes logic and webforms

I have written a data browsing library that is being used in several projects. The library or component includes some classes as well as some ASPX pages.
Until now, we copy all the files into each project to reuse it, with the obvious drawbacks and updating nightmares. I want to encapsulate all the library into a component that the projects can use.
What's the best way to do it? I know I can create a DLL, but I think it's only for the classes, don't know how to go with the ASPXs pages.
We are using Visual Studio 2008 and Framework 2.0
Thanks in advance
This is a perfect case for custom controls.
Change the pages into user controls, and embed the new user controls back into pages that have nothing in them but the reference to the user control.
Once that works, you can change the user controls into server controls, little by little. They will be composite controls, as the user control already is.
There's a trick you can use at this stage: I'm not recalling the details this late at night, but someone else will fill those in: when ASP.NET compiles a page, it first "compiles" the markup into source code, then compiles the source code. You can get ASP.NET to not delete the temporary source files. That allows you to copy into your project code that creates precisely the same HTML as the user control did.
The difference will be - it's now your code and you can refactor it as much as you like, or even include it in a custom control library.

Resources