How to I find out what namespace a missing identifier belongs to? - c#

When I compile my c# project in visual studio, I get the error ...
Error 1 The name 'FilterConfig' does not exist in the current context ...
I guess I need to add a 'using' statement or add a package or something. In general, whats the best ways to try and figure out what package/namespace missing things might belong to? E.g is there a way to search all common packages to find a member?
I've searched on msdn but cant seem to find it.....
http://social.msdn.microsoft.com/Search/en-US?query=filterconfig&emptyWatermark=true&searchButtonTooltip=Search%20MSDN&ac=4#refinementChanges=33,26,59&pageNumber=1&showMore=false
Update: This particular example is for MVC4, however I am interested for a general solution (or multiple solutions) as I work on console apps also.
I've often come across this problem when using incomplete tutorials I've found on the web. So the references may not be present at all. Usually they turn out to be for Microsoft.

General Troubleshooting Steps
Right-click on the identifier. In the context menu, you should see Resolveā€¦ ▹. In the sub menu you should see two lists which contain all of the namespaces in all the project's loaded references which contain a symbol with that name.
Selecting an item from the first list will add a using directive to the current file. Selecting an item from the second list will modify that use of the identifier to be globally qualified. Just select the option you want to use.
If the identifier cannot be found in any of the loaded references (either you are missing a reference, or it's a typo), then you won't see this list. In that case, you should make sure all the references are loaded correctly (there will typically be an exclamation mark next to it could not be loaded) and check the spelling of the identifier.
If all the references are correctly loaded, and your sure the identifier is spelled correctly, it's likely the symbol was renamed, or removed entirely from the project. Using the Renameā€¦ tool (also found by right-clicking on an identifier) can help to avoid this in the future. It's also possible the code snippet in question was taken out of a project where that symbol was defined and you need to include more code from that project to make the code functional. Finally, it may simply be that you're just missing a necessary reference. If this is the case you should investigate where this code came from and what libraries it uses, either by asking the original developer, or if it came from an online source, review the source to see if any more details are provided.
Regarding This Specific Issue
That's about it for general troubleshooting. However, for your specific issue, these steps may only get you so far, and you need to know more about where this exact class comes from in order to resolve it. Microsoft's MVC4 project template includes a number files in the App_Start folder. You typically start out with something like this (NOTE: not every MVC4 project template will contain the same files):
And these will typically be referenced in your Global.asax file like this:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
}
If this is where you're seeing the issue, it's likely that somehow the project was broken in some way. Either the FilterConfig class was renamed or removed entirely (as I stated above). It's also possible that the project started out life as an MVC3 template (which I believe didn't include the FilterConfig class) or perhaps a pre-release version of MVC4, and in migrating to full MVC4 template, this was left out. In any case, I would recommend you create a brand new MVC4 project and see what's different between the your project and the new one.
Now, if for any reason the new project doesn't compile and run like it should, then the template itself is probably damaged somehow. In this case, I'd recommend you uninstall MVC4 and re-install it from the official source.

Additionally to what p.s.w.g said (which you should normally do): I guess that you're using ASP.NET MVC or ASP.NET Web API and that the FilterConfig class is located in the *App_Start* folder. If so, you should remove the *App_Start* from the end of the namespace. After doing so you can call it without a problem in the Global.asax file.
Like said, normally you should use the solution provided by p.s.w.g, but for startup tasks this is the way Microsoft does it in its templates.

Related

How do I set common values (abstract) for a C# solution in Visual Studio with multiple sub projects?

I have a solution with multiple projects each of which connects to the same DB and uses overlapping constant values that I would like to set somewhere instead of replicating manually. I have tried a variety of things online like making a custom class and linking projects to it, setting constants in a project config file (which doesn't exist like the guides claim), and so on. I've been unable to figure this out after more than an hour of searching and experimenting so if you have any ideas, let me know. The structure looks like this (the blue-underlined stuff are some of the projects in the list):
You can make another project under the solution to contain your class.
All the other projects can then reference that project, meaning the same functionality will be available in all the other projects without having to duplicate anything.
I will extend the previous correct answer with some more information.
Your solution structure is something to think very carefully as it is a combination of application design/architecture and leads to extensibillity, scalability and future maintainability.
Take for example the following article Common web application architectures.
You can see the Clean Architecture (AKA Hexagonal) which leads to specific projects withing a solution
You can see older designs where the DB access would go into a project called ..DAL
Simple projects can use the second one, more business rich ones the first or something in between.
Check this this article on shared code projects to see about net standard projects
So the above was helpful, but far more complicated than it needed to be. Apparently other answers I'd seen actually work, but it took reading a bunch of other pages to figure out the whole puzzle. The working steps are:
Create a class with public parameters for your constants
Place that class somewhere in your solution space. When I created it on the solution, it was placed in "Solution Items" in my tree (which is the root folder of the solution on the file system).
Right click each project and ADD>Existing Item and point to the class. The KEY (that was missing from most things I read) was that the "add" button" has a drop-down arrow that lets you change it to "Add as link"
In each project (after adding as link to the file), you can directly reference the values as NAMEOFCLASS.NAMEOFCONST but ONLY if you declared them as public const SOMETYPE SOMENAME. Without the const, it's not able to directly reference the value
Note that this fix is in the .sln file itself and needs to be part of the commit or it won't have any effect. It would be nice if you could use "include" or something to bring in a file a folder one level up, but here we are.

WebAPI 2 Routing/hosting mishaps

I am having a bit of a terrible time getting a WebAPI 2 setup to work. I am trying to place this within an already existing solution containing multiple projects.
The current layout is (with generalized names):
-Server.Project
-Services.Project
Right now, IIS is doing the hosting. There is an application setup in IIS called Application.
So, right now if you go to localhost/Application/service.asmx , everything spins up and does it's thing. The global.asax.cs file and most of the service classes are in Services.Project, even though Server.Project is the software's entry point.
I want to make use of WebAPI's new things.
I've defined a controller (TestAPIController) in Services.Project, and a configuration file with the default mappings (from all of the examples). The Register() function is called from Application_Start(). I've verified that it is at least being called.
If I go to:
localhost/Application/TestAPI/anything ever, it gives me a 404 error.
I tried to use the Route Debugger by installing the package and going to localhost/Application/rd (also tried /Application/TestAPI/rd). Neither work. I get a 404.
This leads me to believe I have something setup wrong so that the WebAPI stuff is not actually spinning up and hosting correctly.
I have tried doing the OWIN startup as well, but it didn't seem to help.
For that, I just added the appropriate startup class stuff to my web.config, and to my Global class in Services.Project.
I've verified that the Configuration() function for Owin is being called as well, but I still cannot hit the paths I've setup.
I think the fact that the entry point is Server.Project, but the controller/routes are defined in Services.Project might be part of the issue.
However, all of the assemblies are placed in the same bin directory. I was lead to believe this should allow everything to be loaded/found.
Am I missing something?
If anything is not clear, sorry. Let me know so I can clear it up.
Thanks.
EDIT:
So, I got a different route debugger to install and cooperate.
(install-package RouteDebugger).
If I hit my main URL: localhost/application
This route debugger launches and shows that no paths were matched, but it ALSO shows the routing paths that I defined but are not found.
...so now I am even more confused. How are they showing up and obviously known about, but are unable to be reached?
If you followed "typical" WebAPI setup tutorials, you would have defined the custom ApiController route to include "/api".
All of your urls should look like:
localhost/Application/api/TestAPI/anything
As an aside, it might be worth it to just spin up a brand new Web API project. Retrofitting an existing project might cause more headaches than it's worth.

Separating Designers from Main Assembly

Background
I am converting the TreeViewAdv(TVA) project on SourceForge to vb.net. Thus far I have successfully converted the code, successfully built it, added a reference of the dll to a new project, added the control to the toolbox, added the control to a form, and modified the controls properties. I have also coded functionality into the form prior to building that accepted the Aga.Controls namespace.
The Problem
When I go to debug the application that I have placed the TVA control in, I get the error: ''Aga' is not declared. It may be inaccessible due to its protection level.' on all calls to that namespace. So, I researched this problem on SourceForge and there is a thread here: https://sourceforge.net/p/treeviewadv/discussion/568369/thread/005e61ef/ that discusses this issue. Supposedly somebody figured out what the problem is when you are seeing behavior like this, but failed to share any details of their wisdom. The general issue is that when referencing a dll compiled in 2008 in a 2010 project 'is that VS 2010 requires you have Designers separate from the main assembly.' I tried contacting people there, but there seem to be no real activity on any thread in the forum at all. That leads me to my first question...
The Question(s)
1.) Hoping beyond hope, is there anybody on StackOverflow that has successfully done this for the treeviewadv project specifically? If so, I would really appreciate either a somewhat detailed description of what was done, or a short description with the final resulting code/fix. While I understand this is highly unlikely, I thought I would ask before asking more general questions on 'how to'?
2.) Barring anybody that fits the bill for number 1, is there anybody that has knowledge of this general process and at least enough knowledge of the TVA project and desire to work with me on this endeavor?
2.) Barring 1 and 2, is there anybody that has done this with any project and can either describe the general process in relative detail, and/or point to example code?
3.) Barring 1, 2 and 3, is there a particularly good resource that I can access that outlines how to update a VS2008 project in the manner described above?
Disclaimer
I understand that this process might be too involved to discuss here, so am willing to take the discussion/effort elsewhere if needed. If someone of category 1 or 2 can (answer my question/work with me on this) and you feel the discussion should be taken elsewhere please inform me as to how we can contact each other as there seems to be no formal mechanism on S.O.. I am still interested in posting (or linking) the results here for all to share if an answer can be found.
Here is a bit more info addressing the general issue of a Designer in a different assembly. There are some caveats: first I (we?) are not sure that the core problem as to do with a UI Designer. Given the project appears to be a custom TreeView, it seems likely to be the case, but the term 'Designer' could be used in a more generic fashion for this control. A second caveat is that all I have to go on is the description above and havent seen the code for the control.
That said, I am just finishing a drop in UnDo Manager component (ie it inherits from Component and sits in the form tray). Part of what it needed was a way for the dev to select controls on the form to be subject to UnDo. The layout/construction is this:
Imports Plutonix.UIDesigners
Namespace Plutonix.UnDoMgr
Public Class UndoManager
Inherits Component
Implements ISupportInitialize
Private _TgtControls As New Collection(Of Control)
<EditorAttribute(GetType(UnDoControlCollectionUIEditor), _
GetType(System.Drawing.Design.UITypeEditor))> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public Property UnDoTargets() As Collection(Of Control)
Get
Return _TgtControls
End Get
Set(ByVal value As Collection(Of Control))
If value IsNot Nothing Then
_TgtControls = value
Else
_TgtControls.Clear()
End If
End Set
End Property
'...
The <EditorAttribute... decoration specifies that this component uses a special designer called UnDoControlCollectionUIEditor. If the project you are converting does not have this on one or more properties, the issue may not be related to UI designers.
Later, there is the UI editor for the COntrols collection editor. This is a separate class though it is in the same file:
<System.Security.Permissions.PermissionSetAttribute( _
System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Public Class UnDoControlCollectionUIEditor
Inherits ControlCollectionUIEditor
Public Sub New()
MyBase.bExcludeForm = True
MyBase.bExcludeSelf = True
' create a list of supported control TYPES
typeList.Add(GetType(TextBox))
'... 9 more lines adding control types to List(of System.Type)
End Sub
End Class
Nearly all the code resides in the base class ControlCollectionUIEditor which is in a different assembly (a DLL). My component though is actually using one defined locally, so as a test, I changed the editor to use to ControlCollectionUIEditor which is the base class in my designer DLL. Labels, panels, GroupBoxes etc dont have/need UnDo capability so my Designer exempts them from showing in the Designer - when I use the base class, they all show up in the designer list as expected.
ALL the standard UI Editors (String Collection Editor and the like) are in NET assemblies, so are defined in one assembly and used in another (yours/ours/the devs). A few years ago, I decided to put several different UIDesigners I had written into a UIDesigner.DLL (ie their own assembly) and they worked fine.
Beyond that, I am confused on some specifics. It sounds like you are trying to use this 2008 assembly (a DLL?) in your conversion. Is that where the designer is? If so, it is already in another assembly from your VS 2010 project, so why is there an issue? Can the whole thing be avoided by also converting whatever is in this 2008 assembly (still not clear on what is in it).
HTH
EDIT
I had a quick look at the source, and it is using at least 1 UIDesigner. TreeViewAdv.Properties.cs defines NodeControlCollectionEditor as a custom controls collection editor for the NodeControls property. The Editor is in NodeControlsCollection.cs. Coincidentally, it is doing EXACTLY what my UnDoManager does: define what control types are valid for a CollectionEditor. Your thing then calls the standard NET CollectionEditor, mine calls the CodeProject DialogForm version. There is also a StringCollectionEditor.cs file but I cant tell if that is a UI Designer or something for the user at runtime.
Since you have the code for these, you should be able to mimic something like what I did above. I would also verify that VS 2010 does indeed have the quirk mentioned. But I am also confused what is in the 2008 assembly. Is there some piece that you dont have the source for? You might also try adding the security attribute to any UI Designers in the project since the CS version does not have them and the msg quoted indicates something about 'protection level'. It seems unlikely to help, but since you are dealing with a quirk, who knows...?
Also, that is a pretty ambitious conversion project!
Cause of Problem Verified
First, I would like to point out that indeed, the issue of losing track of the namespace in the referenced dll was because of the presence of custom UI editor/designers in that dll.
The Fix
The general process of separating Custom Editors/Designers from a 'primary' class library is this:
1.) Find all custom editors/designers in the project. If you are only somewhat familiar with the project, a good way to do that is to Find (Ctrl + F) 'UITypeEditor' in the entire solution. If you are the one who designed it, then you should have no problem.
2.) Delete or comment out the entire custom editors/designers class(es). I prefer commenting out for easy documentation (just in case you need to go back).
3.) Create new project in solution. If you cannot see the solution (i.e. you can only see the project) go to tools-->options-->Projects and Solutions. There you will see a check box that says 'Always show solution'. After revealing the solution, right click and select add-->New Project... Can be named whatever, that will have little to no effect on the code.
4.) Within the new project rename Class1 to whatever is convenient. Transfer all 'using' statements at the top of the files that originally held the custom editor/designer classes. EDIT: Add using statements for any namespaces that would allow you to access the types needed from the primary project. Declare the appropriate namespace for each class. Copy and paste custom classes into correct namespaces (You can, if you want, place ALL of your custom editor/designers in this one file). Change any classes that are declared as 'internal' to 'public' (internal is only the scope of the assembly).
5.) If the new project requires any references, add those now. If your custom editor is editing custom types, you will likely need a reference to the project that defines those types. If those types are defined in your 'primary' assembly this can get a bit tricky as it could cause a circular reference issue. One way to get around this, and probably the right way, is to remove the declaration of those types from your primary assembly and create a new project/assembly just for their declaration. If they are, for some reason, inseparable from your primary assembly, set aside a successful build (dll) previously made of you primary assembly and reference that. This reduces future sustainability of code as those types may chance, but gets the job done now if that is what you want.
6.) After debugging the custom editor/designer project, build it and add that project's build (dll) as reference in the primary project/assembly.
7.) Debug internally, create a new project in solution and add BOTH dlls (Primary and Custom Editor) to the references. Verify controls/properties behave as they are supposed to in both design time AND run time.
8.) Finally, debug externally. Create new solution, reference both dlls, verify functionality. It may seem overkill to debug in both the native solution and externally, but I found many differences in behavior between the environments. Be thorough.
Important Note: I spent a LONG time figuring that both dlls needed to be added. You see, when adding just the primary dll to the test project, it would act as though BOTH were added. I though this was reasonable (& quite dandy) as the primary assembly references the other assembly. However, close and open Visual Studio and it does not work. Long story short add BOTH dlls.
TreeViewAdv Specifics
1.) There were two Custom UIEditors. The first is in NodeControlsCollection.cs called NodeControlCollectionEditor, which inherits the standard .NET CollectionEditor. The only functionality added was the explicit assigning of what kind of controls the editor is allowed to work with. It seems this was largely done as a workaround to allow ALL NodeControl types to be added to the collection (this required the passing of type NodeControl), but get around the fact that passing the NodeControl type causes an error because you cannot instantiate an abstract type. The second is StringCollectionEditor in StringCollectionEditor.cs. This also inherets the standard .NET CollectionEditor and adds a little functionality (Not sure of the purpose).
2 - 4.) Same as the general process.
5.) I currently had to use the latter method (setting aside a dll of Aga.Controls for my custom UIEditor to reference). Later I hope to separate some of the object declarations from the primary assembly to make the solution more reliable.
6 - 8.) The original bug (losing the aga namespace) did not occur when running the testing application inside the same solution (even if different project). Additionally, some fixes that worked externally did not run correctly internally and vise-versa. Thus, my advice for testing in both environments.
Final Request
While both the general and specifics of my question is answered here, Plutonix's help was vital in my coming to the solution. While I am marking this as the answer. I would like if people also upvote Plutonix's answer given the effort that he has put forth in helping me find the answer (in addition to the fact that his answer is also correct if less specific).
EDIT: The process outlined above worked when I was modifying the original TVA C# code. I was even able to reference and successfully use the resulting DLLs in a VB.net project. When I tried to apply the same process to the TVA code line that I had converted into VB.net, it resulted in the same problem that I started with. Everything works until I go to run the application and then it loses sight of the aga namespace.
EDIT SOLUTION: Go to properties (of project losing reference)--> Compile tab --> Advanced Compile Options button. Under target framework, change to ".NET Framework 4" if not so already. If that value is already selected, you are likely looking at a different cause.

using directive with whole program scope

How can I have a using directive that has a scope of the whole program instead of just the file it is in. For every module that I use I would only want to set this once. If there is no way to do this what is the workaround to get this to work.
I thought about putting them all into a header file but C sharp does not have a file include.
This is not possible. Fortunately.
Just wondering why you want to do this. This would be a bad programming habit anyway - put concerns and dependencies only when you really need them. If you add the same using directives everywhere, you also need the referenced assemblies everywhere, something you really don't want to do. Your project should rely on assemblies it needs, no more, no less.
Your argument about wasting time is a bit strange; if you loose so much time, you might have another problem in your architecture.
Note: Resharper is a tool that you may find useful.
Sorry, but what you are trying to achieve is not possible and I don't think that there are any workarounds. This is supported for example in WebForms or Razor views where you could declare common namespaces in the <namespaces> section of your web.config but unfortunately such artifact doesn't exist for standard C# files.
Having the using directives in each single .cs file allows you to take that file out of an existing project and drop it into another project, provided it has the same references.
Also, adding using directives is basically automatic at this point. My tool of choice, ReSharper. Place the cursor on whatever class isn't recognized, press Alt+Enter, and the using directive gets added automatically. If there are multiple choices, you get to pick the right one.

Restricting .DLL access

Lets say I have two .dlls, Dll1 and Dll2.
DLL1 uses or makes calls into DLL2.
Is there a way I can ensure that it is DLL1 and only DLL1 who's making the calls into DLL2?
UPDATE 1
The reason behind this is:
I have a WinForms solution, and to keep it simple, it consists of a view project and a controllers project (which generates a seperate .dll). After installing the application on a client machine, I realise it is possible to view the application .dlls in it's "Program Files" folder. Somebody could potentially add a reference to the controller's .dll. I'd like to avoid this so that it's the view project and only the view project who's making the calls.
UPDATE 2
One of the reasons I like separating controllers into a separate project is that I could potentially have many different view projects calling into and using the same controllers. I then would only need to maintain one controller project for all views. For instance a win forms application and a test project or even a web site using the same controller project. But taking this approach , I would then be faced with the security problem I mention (avoiding and controlling improper use of my dll).
So I have one approach, compiling to one .dll, by using different folders, which I believe is correct and solves my security problem, but it conditions me to only having one view.
On the other hand if I have separate projects I am faced with the security issue.
I am still dubious as to how I should go about this as I would still like to continue using different projects for the reasons I mention.
UPDATE 3
Any suggestions on using the StrongNameIdentityPermission permission demand?
http://msdn.microsoft.com/en-us/library/ff648663.aspx (see: Restrict Which Code Can Call Your Code)
http://blogs.msmvps.com/manoj/2004/10/20/tip-strongnameidentitypermission/ http://www.morganskinner.com/Articles/StrongNameIdentityPermission/
Thanks
You can make all types in DLL2 internal and use InternalsVisibleToAttribute in it set to DLL1.
To ensure that this will not be subverted, you should sign DLL1 and make sure you use its public key in the attribute.
Alternatively, as the author of both DLLs, consider combining the projects into one - set all the public methods that exist in DLL2 to internal, as before, but now only DLL1 exists and they can only be accessed by it.
Note: All the above assumes no reflection is used.
You can using Reflection to check the current callstack. Said that I probably wouldn't do it as it's costly and slow.
You can get the stacktrace this way:
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
You could merge the output into a single exe with ILMerge

Categories

Resources