I have a solution with 2 projects
SharePoint.Project
WebPart
Elements.xml
WebPart.webpart
Web.Project
WebParts
WebPart.cs (NameSpace = Web.Project.WebParts)
SharePoint.Project includes a reference to Web.Project. The SharePoint.Project packages the output from Web.Project and deploys it to the GAC. After the solution is deployed both SharePoint.Project.DLL and Web.Project.DLL exist in the GAC and the web.config of my sharepoint site include a SafeControl that identifies the FullName of the assembly "Web.Project.DLL", the Namespace "Web.Project.WebParts", and the Type "*".
The Problem
Attempt to add the webpart to a page in sharepoint site gives me the error below
A Web Part or Web Form Control on this Page cannot be displayed or imported.
The type could not be found or it is not registered as safe.
You should check version number and publickeytoken of safe control dll. These property must be similar to dll deployed in GAC.
There might be another solution to this problem but what I ended up doing was create a WebPart.cs file in SharePoint.Project and having it derive from the WebPart.cs from Web.Project, and changing the Elements.xml and WebPart.webpart files to reference the WebPart.cs in SharePoint.Project
Related
I'm trying to build a redistributable assembly containing several custom controls (CommonControls).
My environment: MSVC 2010, ASP.NET (WebForms) .NET 2.0/3.0/3.5
The problem: Compiling everything with a Web Deployment Project won't work if I localize CommonControls via App_GlobalResources.
Here is how I build the CommonControls assembly:
I use a WebSite containing the .ascx and .ascx.cs files:
and a Web Deployment Project with the following settings:
This will create "CommonControls.dll".
That assembly is to be used in a different ASP.NET WebApplication as follows:
web.config:
First (minor) problem: Adding CommonControls as a dependency will not automatically copy the satellite assemblies for the languages. Copying them manually to the correct output path seems to work though (for DEBUGGING).
Main problem: The Main web application is also localized via App_GlobalResources and built with a Web Deployment Project:
That build process will fail with
ASPNETCOMPILER : error ASPRUNTIME: Object reference not set to an
instance of an object.
Both deployment projects create a file named "bin\App_GlobalResources.compiled" and I guess those 2 files cannot coexist peacefully within the same output-project.
Is there any elegant solution to localize both CommonContols AND Main using ASP.NET built-in localization?
Note: The project I'm working on has to be compatible with Apache+Mono, so my project-settings (screenshots above) must be exactly like this to work correctly (already tested all other variations).
I fixed it. It was (probably) caused by outdated assemblies in the Bin folder used by the WDP (seems to be a good idea to manually clean that folder from time to time).
I also copied files from "CommonControls\Bin" to the final output (via pre-build event) which is not necessary and causes everything to break (satellite assemblies for translations are automatically copied by MSVC).
While my problem+solution might not be that helpful to others, it's at least a tutorial how to build a re-distributable assembly with some custom-controls out of a bunch of user-controls.
Notes:
All outputs of the custom-control assembly must be merged. Otherwise we will end up with 2 "App_GlobalResources.dll" files (won't work)
It only works with a "Web-site project", not "Web application"
User-controls must use the "CodeFile/Inherit" tags, not the deprecated "CodeBehind" tag (get rid of all those ".designer.cs" files!)
User-controls must have a "ClassName" tag that differs from the control's name (I appended "Internal" and renamed the class(es) in code-behind)
Embedded resources (images, scripts...) are not directly supported in a "Web-site project". I use an additional LIB for that
In a dynamically compiled ASP.NET Website project, can the assembly for the App_Code folder be explicitly named?
For example, under regular circumstances when I run an ASP.NET website the assembly name generated into the Temporary ASP.NET Files\ folder is partially randomized like App_Code.neizakfo.dll where neizakfo is the portion that can differ. Can I explicitly provide a name for the assembly like App_Code_Web1.dll?
Clarification
By business requirements, the website cannot be precompiled/deployed. Therefore I'm seeking a solution in context of the Temporary ASP.NET Files folder and dynamically compiled assemblies as noted above.
Background:
I came across this question while looking for a way to perform dynamic type instantiation on a class in the App_Code folder of a website using an assembly-qualified name stored in configuration, but instantiated from the web page, thus crossing an assembly boundary. Because the web page and app_code code are compiled into two different assemblies by default, the Type.GetType(..) method's default behaviour of searching for the Type name either in the current executing assembly (the web page) or in mscorlib doesn't suffice for picking any Type from the App_Code assembly. Being randomized, the app_code assembly name is not known for me to include in the assembly-qualified string.
I can put the data Type in a class library (because that does have an predefined/exact name) to get rid of this problem, however I'd like to know how to do this inside the website itself without creating a class library project for the purpose.
You can sort of do this in a WebSite project.
There's an MSDN article on using the -fixednames flag when compiling the project.
This effectively creates an assembly for each page - default.aspx.dll. However, this is only marginally more useful to you as you still need to know the name of the control or page you are looking for when you are loading - so you have to ensure your types and naming is consistent. It should, however, respect the name of the classes in app_code so this may work for you.
One other thing you could do is move all of the code in app_code out into it's own assembly, and then add that as a project reference. That would also simplify this problem.
Lastly, you could enumerate all of the dll's in the bin directory, and search each one for the type you are looking for. As this is fairly expensive, do it once, and cache the result somewhere so you don't keep doing it everytime you look that type up. This is probably the worst solution.
This is trivial to do in a WebApplication project, but I assume you are stuck with the WebSite one?
EDIT: As an update for the comments; if I use the Publish Web Tool, then all of the code in app_code goes in the bin directory in a dll called App_Code.dll - this behaviour does not change even if I use fixed naming (all fixed naming effects the naming of the dll's for each page, usercontrol). If I use ILSpy on this file, I can see my classes in there. So I know the name of the assembly, and it's location - I should be able to get at the types in it with minimal effort. I wonder why I'm seeing different behavior to you!
I created a simple class called "Person" with an Id and Name, put it in App_Code, compiled the site, and then ran the following code:
Type myType = Assembly.LoadFrom(Server.MapPath("~/bin/App_Code.dll")).GetType("Person", true);
Response.Write(myType.ToString());
It wrote out "Person", as expected.
Further Edit
The penny drops! If I then do:
object myObject= Activator.CreateInstance("App_Code.dll", "Person");
And try to cast myObject to person, I get the following message:
The type 'Person' exists in both 'App_Code.dll' and 'App_Code.jydjsaaa.dll'
So it's time to be devious.
in Global.asax, on Application_OnStart, do the following:
Application["App_Code_Assembly"] = Assembly.GetAssembly(typeof(Person));
In my test default page, I then did:
Assembly app_Code = Application["App_Code_Assembly"] as Assembly;
Response.Write(app_Code.FullName);
Which gave me the randomly named app_code it is actually running with in Temporary ASP.Net Files.
This is why I hate Web Site Projects ;-)
I have inherited a Web Application project (3 files per aspx page), along with a second solution which contains the business and datalayers as a class library. I created an empty solution, added the class library project to it, along with the Web Application. I then added a reference to the class library from the Web Application. When I try to debug the site, I get a parser error:
Parser Error Message: The type 'Electro_Spec.Masters.MasterPage' is ambiguous: it could come from assembly 'C:\projects\esWOT3\WebSite\bin\Electro-Spec.DLL' or from assembly 'C:\projects\esWOT3\WebSite\bin\WebSite.DLL'. Please specify the assembly explicitly in the type name.
Why would this be? And how do I fix it?
EDIT the only reference to Electo_Spec.dll is from the Web Application "refrences", the class library was added to the site via the add reference to existing project dialogue. If I remove it, the site won't compile. Additionally the name of the web application is WebSite . . . thus the "Website.dll" . . . i believe, as I am new to web applicaitons (versus .net websites). Oh and this was all built in an empty solution. Additionally I have tried renaming the MasterPage to MasterPage1 to no avail.
The Electro_Spec.Masters.MasterPage class is defined in both projects.
Remove the Electro_Spec.Masters.MasterPage from one of the two projects or change the namespace for one of the two MasterPage classes.
Well, there's a type with the same name (Type.FullName) in those two assemblies. Are you sure those assemblies are not the same? If they are, delete one. If they are not, add the assembly name to the Inherits attribute, like: Inherits="Electro_Spec.Masters.MasterPage, Electro-Spec"
I have converted my old VS2008 Website to Web Application, now everything was working before I tried to convert it. But now I don't seem to be able to reference my Classes? For example I have a BasePage class that every .aspx page inherits like so
public partial class SomePageName : BasePage
{
}
But now I get this message? And the same for all the other classes?
The type or namespace name 'BasePage' could not be found (are you missing a using directive or an assembly reference?)
How do I find out which 'using' directive I am missing and whats an assembly reference?
The conversion namespaced your classes. Perhaps it should be NewlyAddedNamespace.BasePage?
Locate the class BasePage in your project using the object explorer.
In object explorer you will be able to see the complete name Something.Somethingelse.BasepAge
Do mass search and replace to the complete name.
In Solution Explorer (available on the View menu if you can't see it), you will see that your web application contains a node marked "References". Right click on this and choose "Add reference", and when the dialog box appears, on the Project tab you be able to add a reference to the other project which defines this BasePage class. This then becomes an assembly reference when compiled.
You probably already have the using statement you need from before. Previously, this would have been picked up by the presence of the necessary DLL in the bin folder of the web project. It works differently for a web application.
How to convert in a Web Site Project - will get you started - it is for VS2005 but will still be applicable for Visual Studio 2008.
You might want to take a look at the difference between the 2 types of projects. That said, website projects generally are not created with namespaces, I would guess that "BasePage" was in you appCode folder and has now been converted into a different namespace. You just need to line you your namespaces and everything should work correctly.
What you could try is "Convert to Web Application" in Visual Studio. It is available in the context menu of the new Web Application project in Visual Studio.
There's another possible issue. You might need to set the "Build Action" to "Compile instead of Content. Right-click the .cs file, bring up the properties and make sure the Build Action is compile.
I have an ASP.NET 3.5 Website (visual studio lingo), but the site continues to grow and is looking rather cowboyish among other things. I'd like to see this get converted into a Web Application (namespaces and all).
Is this something that can be easily done in Visual Studio? If not, are there any other tools out there that could create all of the namespaces, etc. automagically?
Well, it turns out that the option "Convert to web application" does NOT exist for "websites". The option "Convert to web application" does exist only for "web applications" !!!!
[emphasis mine]
So, here's the deal, to do the
conversion, you need to:
Add a new "Web Application" to your VS 2008 solution (File->Add->New
Project->C#->Web->ASP.NET Web
Application).
Afterwards, you copy all the files in the old "website" to your newly
created "web application", and
override any files created in it by
default
The next step is the most ugly, you need to "manually" add the references
in your "website" to the new "web
application". I thought the VS 2008
PowerCommands toy would do this for me
as it does copy references from other
project types, but it didn't. You have
to do it by yourself, manually, and
you have to be cautious in this step
if you have multiple versions of the
same assembly (like AJAXToolkit in my
case) or assemblies that have both GAC
and local versions or so.
Keep repeating the last step and trying to build the "web application".
You'll keep getting errors like "
'....' is unknown namespace. Are you
missing an assembly reference? ". Make
sure you have none of those except the
ones where '....' is replaced by the
IDs of the server controls you use. In
other words, keep adding references
and building the project until only
the errors that exist because of
missing .DESIGNER.CS or .DESIGNER.VB
files.
Afterwards, go to the "web application" root project node in VS
2008 solution explorer, and right
click it, then you WILL find the
option "Convert to web application".
What this option does is actually
making small changes to the "#Page"
and "#Control" directives of pages and
controls, and creating the required
.DESIGNER.CS or .DESIGNER.VB files.
Try building the "web application" again. If you get errors, see what
references may be missing and/or go
click the "Convert to web application"
again. Sometimes, if there's any error
other than those caused of missing
DESIGNER files, not all the
pages/controls will have those
DESIGNER files created for them.
Fixing the non DESIGNER problem and
clicking "Convert to web application"
again should do the job for this.
Once you are done successful VS build, you should be ready to go.
Start testing your web application.
Optionally, you can right click the
"web application" root project node in
VS 2008 Solution Explorer and click
"Properties" then go to the tab "Web"
to set the "web application" to a
virtual folder in IIS (you can create
new virtual directory from there in
VS). If you want to use the IIS
virtual directory that the old
"website" used, you need to remove
that from IIS first.
Update: When testing your pages, pay MOST ATTENTION to classes in
"App_Code" folder, especially those
with NO NAMESPACE. Those can be a big
trap. We had a problem with two
extension method overloads in the same
static class that had no namespace,one
extends DateTime? (Nullable)
and calls another overload that
extends DateTime itself. Calling the
other overload as extension method
passed VS 2008 compilation and gave us
a compilation error ONLY IN RUNTIME
(With IIS). Changing the call to the
other overload from calling it as
extension method to calling it as
normal static method (only changing
the call in the same class, calls from
other classes remained extension
method calls) did solve this one, but
clearly, it's not as safe as it used
to be in VS 2005. Especially with
classes with no namespaces.
Update2: During the conversion, VS 2008 renames your "App_Code" to
"Old_App_Code". This new name sounds
ugly, but DO NOT RENAME IT BACK. In
the "web application" model, all code
will be in one assembly. In runtime,
the web server does not know what web
project type you are using. It does
take all code in "App_Code" folder and
create a new assembly for it. This
way, if you have code in folder named
"App_Code", you'll end up with RUNTIME
compilation errors that the same types
exist in two assemblies, the one
created by VS, and the one created by
IIS / ASP.NET Development Server. To
avoid that. leave the "Old_App_Code"
with the same name, or rename it to
ANYTHING EXCEPT: "App_Code". Do not
place any code in such "App_Code"
folder and prefereably do NOT have a
folder with such name in your "web
application" at all.
I know this since before but forgot it
now as I have not used "website" model
for long :(.
Walkthrough: Converting a Web Site Project to a Web Application Project in Visual Studio at MSDN
If your website application grows.. it's better to split it into several projects. Conversion from Web Site project to Web Application project won't help much.
If you're having problems getting your new Web Application Project to build check the File Properties in Visual Studio of all 'helper' classes. For a project I was converting the Build Action was set to Content whereas it should have been Compile.
I've now successfully migrated one Website project to a web application and there is quiet a few gotchas to look out for.
Having ReSharper at your disposal helps a lot in refactoring the aspx files.
Set up your solution and create an empty WebApplication
Copy all file over
aspx files in website projects don't have a namspace. Wrap your classes in the appropriate namespaces
During copying, all my pages in subfolders got renamed to my project name and the foldername, so I got 40ish public partial class FolderName_Projectname : Page If neccessary rename all files using Resharper or manually.
If you encounter multiple errors like "There is already a member Page_Load() defined", this is most likely due to incorrect class names und duplication
After adding a namespace
Replace CodeFile in all aspx pages with Codebehind and especially pay attention to files i your subfolder. Make sure Inhertis="" doesn't contain the relative path. Your namespaces take care of everything. So the correct format is Inherits="Namespace.classname".
If your class has a namespace NaSpa and a filename foo.cs it would be Inherits="NaSpa.foo"
After you have prepared all your files (don't forget your master pages), run "Convert to web application". If you encounter errors afterwards, rinse and repeat.
If you encounter errors of the sort "TextBoxName can't be found are you missing a reference", make sure you did not forget to sanitize your aspx pages. A good indicator is to check the automatically generated designer files. If TextBoxName does not appear in there, the conversion did not succeed completely.
Resolve any missing dependencies.
Build
Create a New Web Application in VS 2010.
1. Using Windows Explorer copy all your files into you project folder.
2. In VS 2010 solution explorer show all files.
3. Select the files and folders - right click include in project.
4. Right click the project solution explorer and select Convert to Web Application.
There are quite a few small differences, such as the App_Code folder will get renamed to old_app_code - that surprisingly doesn't cause any errors. The TypeName on your object data sources and the inherits on the #Page tag might need the [ProjectName]. prefix appended globally. For example if your type name was "BusinessLogic.OrderManager" and your project name is InventorySystem you would need to change it to InventorySystem.BusinessLogic.OrderManager. Also a few display changes, such as required field validators don't default to red font anymore, they default to black.
I was facing the same problems initially. After following the Wrox Professional ASP.NET 4.0 book, I found the following solution for my case.
I first created a new web application. Copied all the website files into the web application folder. Right click on the application, and click conver to web application.
You might ask why you need to convert a web app into a web app. The answer is, that when you create a website, you simply code the .cs file where-ever required.
A web application, however declares .design.cs (or .vb) and a .cs file for the code and design section automatically.
NEXT: Remove all manual references, like 'Inherits' attribute in the PAGE directive, to other files in your website, since name spaces WILL take care of referencing the classes centrally.
I also faced a problem, since I had not included OBJ and BIN folder in my project.
If you think you are missing your BIN and OBJ folders, simply click the 'Show All Files' icon in the Solution Explorer and then right click on the missing folders and add to project. (to make sure they compile with the project.)
UPDATE:
As #deadlychambers points out in the comments: You can search everywhere by doing a "Ctrl + Shift + F" and then search for Inherits="(.*?)". This will find all occurrences and probably save you some time!
the default ASP name space does not seem to work anymore. So I cannot seem to call my User Controls.ascx pages from outside the page. Giving them a namespace and changing the default from ASP to my namespace seemed to work.