I currently have a website, whose code behind references some functions within another project within the same solution. I have been tasked with pulling out this website and its existing functionality and putting it into its own solution.
Currently the code behind looks similar to this:
using BusinessObjectsProject;
namespace BatchProject.Web
{
public partial class AutoShoppingCart : System.Web.UI.Page
{
[WebMethod]
public static BatchProject LoadProjectDetails(string projectId)
{
return BusinessObjectsProject.BatchBo.ReadBatchProject(ConvertHelper.SafeConvertInt32(projectId));
}
}
}
However there are many (more than 20) functions that make use of the BusinessObjectsProject reference.
Is there a simple way to list the BusinessObjectsProject functions in the AutoShoppingCart class? I want to ensure that I copy over everything to ensure existing functionality.
If you're using Visual Studio, simply right click BusinessObjectsProject and select Find All References (or press Shift + F12).
The solution suggested by Blorgbeard is also useful, just remove/rename the class and see what breaks.
Related
I have a background in C++ and recently I started working in C#.
I have written following pieces of code (in Visual Studio):
var list_Loads = database.GetData<Load>().ToList();
var test_list = list_Loads.Where(o => (o.Name.Substring(0, 3) == "123")).ToList();
When I run the program and I move my mouse over both lists, first I get the count, which is very useful, but when I ask for the entries, this is what I get:
0 : namespace.Load
1 : namespace.Load
2 : namespace.Load
...
Not very useful, as you can imagine :-)
So my question: how can I show the Name attributes of those objects?
I thought: no problem. I have a background in native visualisers, so it should be rather easy to turn this into useful information, but then it comes:
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Then I found another solution, which comes down to: "Write an entire C# project, debug, test and install it and it might work" (see documentation on "Custom visualisers of data" on the Microsoft website).
I almost choked in my coffee: writing an entire project, just for altering the view of an object??? (While, in C++, you just create a simple .natvis file, mention the classname and some configuration, launch .nvload and that's it.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
By the way, when I try to load a natvis file in Visual Studio immediate window, this is what I get:
.nvload "C:\Temp_Folder\test.natvis"
error CS1525: Invalid expression term '.'
What am I doing wrong?
Thanks in advance
OP (my emphasis):
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
If you just want to specify [DebuggerDisplay] on a type, you don't have to have access to the source code. You can make use of [assembly:DebuggerDisplay()] and control how a type appears in the debugger. The only downside is that [assembly:DebuggerDisplay()] naturally only affects the current assembly whose code your mouse is hovering over. If you wish to use the customised display in other assemblies that you own, then you must repeat the [assembly:DebuggerDisplay()] definition.
Here's an easy before-and-after example with DateTime. I picked DateTime because we generally don't have access to the source code and it has some interesting properties:
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
...which on my machine defaults to:
Maybe I'm fussy and I just want to see:
Day of the week and
Day of the year
...I can do that via:
using System.Diagnostics;
[assembly: DebuggerDisplay("{DayOfWeek} {DayOfYear}", Target = typeof(DateTime))]
...which results in:
Example:
namespace DebuggerDisplayTests
{
public class DebuggerDisplayTests
{
public DebuggerDisplayTests()
{
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
}
}
.
.
.
}
Overrides
[assembly:DebuggerDisplay()] can also be used as a means to override pre-existing [DebuggerDisplay] on a 3-rd party type. Don't like what style they have chosen? Is the type showing far too much information? Change it with [assembly:DebuggerDisplay()].
I seem to be running into a weird issue and after hours of head scratching, I seem to have narrowed the issue down to a combination of partial classes and virtual properties. When I override a property that's in a partial class, sitting in a separate file, MVC duplicates the fields on my view. I am using Visual Studio 2013 and the issue can be duplicated by following these steps:
Open Visual Studio and create a new Project. Choose Web under the categories, then choose "ASP.NET Web Application". I am targeting .NET 4.5.
Choose "Empty" from the template selection, then check the MVC checkbox so it adds the core folders and references.
Once the project is created, right-click on the Models folder and create a new class called MyModel.cs.
Add these lines to the new file:
public abstract partial class MyOriginalModel
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
public partial class MyModel : MyOriginalModel
{
}
Now right click on the Models folder again and create another new class called MyModelCustom.cs.
Add these lines to the file:
public partial class MyModel
{
[System.ComponentModel.DisplayName("First Name")]
[System.ComponentModel.DataAnnotations.Required]
public override string FirstName
{
get
{
return base.FirstName;
}
set
{
base.FirstName = value;
}
}
[System.ComponentModel.DisplayName("Last Name")]
[System.ComponentModel.DataAnnotations.Required]
public override string LastName
{
get
{
return base.LastName;
}
set
{
base.LastName = value;
}
}
}
Now build the project, then right click on the Controllers folder and add a new controller. Choose "MVC 5 Controller with read/write actions" and call it NamesController. Right click on the Create method and go to "Add View". Under the template dropdown, choose Create and for the Model Class dropdown, choose MyModel.
Once MVC creates the template, you will see that it adds First Name and Last Name twice. The issue seems to be related to partial classes because if I move the contents of MyModelCustom.cs into MyModel.cs, everything works fine. However, its not just partial classes. If I create a new property (versus overloading one) in the partial class, it does not duplicate that property. So it seems to be a combination of partial classes and overriding virtual properties.
Can someone please confirm if this is a bug or if I am doing something wrong?
It is a bit of both. Bug or not, if MVC is scaffolding incorrectly, you will either have to constantly fight the framework or change your approach to the problem.
As a general rule, I've found that when you have to fight the MVC framework to make it behave the way you want, then it is far easier to change your approach to the problem. Otherwise, you will end up fighting that particular battle repeatedly until you eventually comply. Take it from someone who's learned that lesson the hard way.
With easier approaches in mind, here are a few things you could try instead:
If you are overwriting a lot of properties, create separate classes with common names for properties (FirstName, LastName). Then use Best way to clone properties of disparate objects to marshall the data between objects.
You could also use Fody PropertyChange listeners to handle whatever logic is needed when these values are changed thereby eliminating the need for the partial overrides entirely.
A final option would be to override the scaffolding templates to skip overridden properties. Not sure how you would detect that though.
Take a look at CodePlex source for MvcScaffolding EnvDTETypeLocator.cs
/// <summary>
/// Out of a set of CodeType instances, some of them may be different partials of the same class.
/// This method filters down such a set so that you get only one partial per class.
/// </summary>
private static List<CodeType> PickArbitraryRepresentativeOfPartialClasses(IEnumerable<CodeType> codeTypes)
{
var representatives = new List<CodeType>();
foreach (var codeType in codeTypes) {
var codeClass2 = codeType as CodeClass2;
if (codeClass2 != null) {
var matchesExistingRepresentative = (from candidate in representatives.OfType<CodeClass2>()
let candidatePartials = candidate.PartialClasses.OfType<CodeClass2>()
where candidatePartials.Contains(codeClass2)
select candidate).Any();
if (!matchesExistingRepresentative)
representatives.Add(codeType);
} else {
// Can't have partials because it's not a CodeClass2, so it can't clash with others
representatives.Add(codeType);
}
}
return representatives;
}
}
:
:
1) PickArbitraryRepresentativeOfPartialClasses, the method uses Linq any() to confirm that the codeType as CodeClass2 has members.
CodeClass2 is the partial class type of EnvDTE, Visual Studio's core Automation library responsible for IDE code generation (Design Time Reflection).
2) If the class cast as CodeClass2 does have members, the class is added to the representatives
3) When the partial class is evaluated, each file will be visited within a distinct context (often leading to a consolidation of elements that should be overridden)
An interesting distinction between Run Time Reflection and Design Time Reflection: sic
An ASP.NET control has two distinct sets of functionality for when it is executed at run-time inside a page or used at design-time inside a host designer. Run-time capabilities determine, based on configuration, the markup that is output by the control. The design-time capabilities, instead, benefit of a visual designer such as Microsoft Visual Studio 2005. Design-time capabilities let the page author configure the control for run-time in a declarative and WYSIWYG (what-you-see-is-what-you-get) manner.
Conclusion:
MVC Scaffolding does use reflection, but it is the much less reliable Design Time Reflection.
Design Time Reflection is not the same as Run Time reflection. A fully compiled Class is a final result of inheritance resolves and partials combined and priority resolved. Design Time Reflection makes best guesses about how to work with complex, multi-part types.
If you want to rely on Scaffolding, better not to push it's limits. When you get errors like this, try simplifying your ViewModels:
Try consolidating your partial classes
Try removing your abstracts / virtuals
So I'm working on a practice project using Visual Studio 2012, MVC 4, and Entity Framework 5.0. I create an MVC 4 project using the "Basic" template. I add a simple Home/Index controller and view just to make sure everything is working. It is.
I add an edmx data model to my project under the models folder. (Connection strings are tested and good). I generate this model from a fairly simple SQL Express database. Here's some details about the model (generic names substituted):
Model edmx file structure looks like this in Solution Explorer:
[edmxFile] MyProjectModel.edmx
[SubFile] MyProjectModel.Context.cs
[Class] MyProjectEntities
[Method] MyProjectEntities()
[Method] OnModelCreating()
[Property] EntityAs: DbSet<EntityA>
[Property] EntityBs: DbSet<EntityB>
[Property] EntityCs: DbSet<EntityC>
etc...
[SubFile] MyProjectModel.Designer.cs
[SubFile] MyProjectModel.edmx.diagram
[SubFile] MyProjectModel.tt
[ClassFile] EntityA.cs
[ClassFile] EntityB.cs
[ClassFile] EntityC.cs
etc...
[ClassFile] MyProjectModel.cs
So I Rebuild my solution, then right click the "Controllers" folder and choose "Add"->"Controller" and choose the following options:
Controller name: "EntityAsController".
Scaffolding options:
Template: MVC controller with read/write actions and views, using Entity Framework
Model class: EntityA (MyProject.Models)
Data context class: MyProjectEntities (MyProject.Models)
Views: Razor (CSHTML)
Then I click "Add". I get the following error (again, generic names substituted):
'MyProject.Models.EntityA' is not part of the specified 'MyProject.Models.MyProjectEntities' class, and the 'MyProject.Models.MyProjectEntities' class could not be modified to add a 'DbSet<MyProject.Models.EntityA>' property to it. (For example, the 'MyProject.Models.MyProjectEntities' class might be in a compiled assembly.)
I originally got this error when I tried putting the edmx in a data layer project of its own and referencing that project from the main project. To solve,
I tried moving it to the main project. No luck.
I tried recreating the entire solution from scratch and creating it in the main project from the start. Same error.
I read and tried monkeying around with just about every solution or suggestion in this question/answer(s)/comment(s): Entity Framework MVC Controller no success.
I tried extending MyProjectEntities with a partial class and adding a wrapper property in order to FORCE it to have the desired "EntityA" property, like so:
public DbSet<EntityA> EntityA {
get { return this.EntityAs; }
set { this.EntityAs = value; }
}
All that did was give me an even more unhelpful error:
There was an error generating 'MyProject.Models.MyProjectEntities'. Try rebuilding your project.
I tried rebuilding the project. Same error.
Does anyone have any idea what's going on?
I found a solution to my own problem. It's a bit hacky, but it works.
The first error message above complains about "...class could not be modified to add a 'DbSet<MyProject.Models.EntityA>' property to it...". So I left my partial class for extending MyProject.Models.MyProjectEntities empty, like so:
public partial class MyProjectEntities : DbContext
{
}
Now, when I create the controller, MVC is of course still to stupid to see that the auto generated MyProjectEntities already contains the property it wants, BUT it now has a file for that class that it can modify to add a duplicate declaration of that property, modifying my code to look like this:
public partial class MyProjectEntities : DbContext
{
public DbSet<EntityA> EntityAs { get; set; }
}
It is happy, and makes my controller and views for me. Now, I just manually delete what it added to my code, so that there isn't an ambiguity error at build time. I build the project, start it, fire up my browser and go to "[siteUrl]/EntityAs", and TADA! It Works!
I hope that helps someone who has this problem. If anyone knows why MVC 4 and VS 2012 behave in this buggy way and require this hack solution, please comment or add another answer. It still bugs me a bit, and I'd love to hear more about it.
I want to run my project, and I have one class that makes errors - I will fix it later ,but now I want to run the project without reference to the class that makes errors.
How can I do it?
You can do right click on that file and select exclude from project for now.
It is something like Image bleow.
Other way is to comment the logic that is not desired and continue working on without excluding.
You need to comment your class and all usages of this class. It can be done by selecting code block that you need to comment and pressing Ctrl+K, Ctrl+C.
If you need to uncomment - Ctrl+K, Ctrl+U on selected commented block.
Also you need to note that commenting your class usages in project also might produce new errors.
Comment out its inner code. This way you can still reference that class from your code but it will no longer show errors unless you are refering to method or property of this class which is commented out.
public ProblemClass
{
// public string Name { get; set; }
// ...
// ...
}
Our system complexity has risen to the point that we need to make permission names tied to the client from the database more specific. In the client, permissions are referenced from a static class since a lot of client functionality is dependent on the permissions each user has and the roles have a ton of variety. I've referenced this post as an example, but I'm looking for a more specific use case. Take for instance this reference, where PermissionAlpha would be a const string:
return HasPermission(PermissionNames.PermissionAlpha);
Which is great, except now that things are growing more complex the classes are being structured like this:
public static class PermissionNames
{
public static class PermissionAlpha
{
public const string SubPermission = "PermissionAlpha.SubPermission";
}
}
I'm trying to find an easy way to reference PermissionAlpha in this new setup that will act similar to the first declaration above. Would the only way to do this be to resort to pulling the value of the class name like in the example below? I'm trying to keep all the names in one place that can be reference anywhere in the application.
public static class PermissionAlpha
{
public static string Name { get { return typeof(PermissionAlpha).Name; } }
}
** Edit ** - Added missing permission name.
Maybe this would be too big of a change for you with the size of your project, but we have all of our business objects split into partial classes. One is for manual changes and one gets generated. During code-generation, we write the permission keys into the generated side of the partial classes from our "single source of truth". We're using a set of classes as our source of truth and CodeDom to generate, but you could also use a database as your source and use T4, CodeSmith, or others to generate.
Why not create reflectable attribute(s) on the classes in question? That way one can add all the extra information required. I provide a way of divining attributes on my blog article entitled:
C# Using Extended Attribute Information on Objects
HTH