The C# Scopes for Privileged Inheritance

You can't really combine the various scopes that you can apply to a C# member because, I suspect, they wouldn't make sense (what's the scope of a public private method, for example?). However, you can combine internal with private and protected like this:

public class CustomerBase
{
  protected internal void DeleteCustomer() {

or

public class CustomerBase
{
  private protected void DeleteCustomer() {

In my first example, because of its internal scope, DeleteCustomer can be used by code that instantiates CustomerBase but only if that code is in the same project as CustomerBase. Because of the protected declaration, however, code in other projects can access DeleteCustomer through a class that inherits from CustomerBase.

Code in other projects that instantiate CustomerBase directly won't see DeleteCustomer. Essentially, code in the same project as CustomerBase has a privilege denied to code in other projects (the ability to delete customers, in this case).

The scope private protected goes even further and is probably more useful. This scope prevents DeleteCustomer from being accessed except through classes that derive from CustomerBase and only if those derived classes are in the same project as CustomerBase.

Code in some other project in a class that inherits from CustomerBase won't be able to access DeleteCustomer. This allows you to create derived classes in the same project as CustomerBase that have privileges denied to classes in other projects that inherit from CustomerBase.

Posted by Peter Vogel on 02/21/2018 at 6:47 AM0 comments


Getting Data from the Request Object in ASP.NET MVC

Most of the time in ASP.NET MVC I can count on model binding to fill in the values for the parameters to my Action methods. Every once in a while, though, model binding doesn't do what I expect. You can create your own custom modelbinder to solve this problem (I've even discussed how to do that for the ASP.NET Web API). However, that may be overkill.

Often you can solve your problem by accessing one (or all) of the collections in ASP.NET's Request object (available in your controller through its Request property). There are a number of collections you can use to access data sent from the browser and their names do a pretty good job of describing what data they hold:

  • Cookies
  • Files
  • Form
  • Headers
  • QueryString
  • ServerVariables

You can also use the Params collection (which combines the values from Cookies, Form, QueryString, and ServerVariables) but you'd be safer with one of the more specific collections. The problem with the Params collection is that you can have the same data stored under the same name in multiple collections (Cookies and QueryString, for example). If you use Params you can't be sure which of those collections your data will come from.

Posted by Peter Vogel on 02/20/2018 at 5:52 AM0 comments


Paste JSON and XML as a Class

I don't use Visual Studio's Edit menu enough, obviously: For some time there's been a Paste Special option on that menu that I didn't know about. It has up to two choices depending on what kind of file you're editing: Paste XML as Classes and Paste JSON as Classes. Using the Paste JSON as Classes option, I can copy some JSON in my JavaScript code and create a corresponding C# or Visual Basic class in my server-side code just by picking a menu the appropriate menu choice.

However, I'd rather be able to use this functionality without having to drag my mouse to the Edit menu. To support that, I added a keystroke combination for the underlying commands related to these menu choices.

If you want to do the same, first go to Tools | Options | Environment | Keyboard. To grab the commands, in the "Show commands containing" textbox, type in AsClasses and select one. Then, from the "Use new shortcut in" dropdown list, pick your language's editor (for example, CSharp Editor or Microsoft Visual Basic Editor). Now you can click in the "Press shortcut keys" textbox to select your shortcut key(s): Just press the keys you want to use. Finally, click the Assign button. Lots of people forget that step and just click the OK button at the bottom of the dialog (by "lots of people" I mean: me).

You probably don't want to override any existing shortcut keys so I'd recommend picking a "chord": two or more keys pressed sequentially while holding down one of the control keys (the dialog box will tell you if you pick a shortcut that's already in use). I picked Ctrl+K, J for pasting JSON and Ctrl+K, M for pasting XML (Ctrl+K, X was already taken for inserting snippets and, who knows, I might start using that some day).

My life would be complete if there was a Paste Class as JSON when I was in a TypeScript or JavaScript file. In the meantime, I'm settling for Edit | Insert File as Text and doing some editing or using Nha Bui Doc's TypeScriptSyntaxPaste.

Posted by Peter Vogel on 02/16/2018 at 6:16 AM0 comments


Manipulating URLs on the Server

There's nothing stopping you from working with URLs in code using standard string functions. If you want to create a URL, you should use the URL object. On the other hand, if you want to analyze a URL -- or, more properly, a URI -- you should use the Uri class.

To use the Uri class, you just instantiate it, passing a URI. Once you've done that, you can check whether the URI's scheme name (ftp, http and so on) is valid, that the host name is a valid DNS name, or even dismantle the URI to get its individual components (to get, for example, the port or host name).

You can even use the Uri object to compare two URLs to see if they are significantly different (the Uri object is smart enough to recognize that two URLs are identical if one URL omits a port number while the other one specifies the default).

Posted by Peter Vogel on 02/13/2018 at 10:27 AM0 comments


Best Practice: Declare Variables as Constants

In the bad old days, I only used constants as a way to assign names to values. Things like this, for example:

Private Const DaysInWeek As Integer = 7

However, these days most of my variables are holding objects; Some of my other variables are holding things like collections or delegates. That changes what we mean by "constant."

When a variable is declared as a constant, it doesn't mean that the object it's holding is immutable. You can, for example, still change values in the properties of an object held in a constant or add items to a collection held in a constant. It just means that you can't replace the object (or collection) that was assigned when the variable was initialized.

Especially in TypeScript (where many of my variables are holding functions), I'm switching to declaring my variables as constants. A subset of these variables are fields (class-level variables) that are set precisely once, in an object's constructor, and I'm taking the time to mark as those read only also.

If I want an actual immutable object I'll declare the object's properties as read only or use one of .NET's read only collections.

In part, I'm doing this because I'm thinking more in terms of value objects (an important concept in Domain Driven Design). However, there are other benefits. I'm told, for example, it makes life easier for the compiler. But it's also because this practice sends a clear message to the next developer (either using my code or modifying it) about how I think that the object should be used.

Posted by Peter Vogel on 02/12/2018 at 7:20 AM0 comments


Pasting Into a Command Window

I amazed a client recently who was looking over my shoulder when I copied a file path from the address in Windows Explorer.

Actually, it wasn't copying the path that impressed him -- it was when I pasted that text into a command window. I clicked in the command window, clicked on the icon at the right-hand end of the command window's title bar and, from the dropdown menu, selected Edit | Paste.

As the file path appeared in the window, he said "Now, that's cool."

This is how you get a reputation as wizard, kids. (I didn't say it was hard to do.)

Posted by Peter Vogel on 02/09/2018 at 6:20 AM0 comments


Load TypeScript Modules as You Need Them

In the bad old days you put all your JavaScript code into a single file and loaded that file on every page that needed any of your code. As the amount of JavaScript code increased, you started organizing your code into files and loading just the files you needed.

Currently, you can organize your code into modules and, for any particular module, specify what other modules it needs. Using a module loader, those other modules will automatically be loaded for you.

In the current version of TypeScript you can now load a module only if you actually need it. If you have a section of code that isn't always executed but requires some additional module support when it is used, then you can load that support dynamically at run time.

All you need to use is the import method, passing the relative path name to the file containing the module you need.

Of course, it will take a while for that file to be fetched and the module it contains made available. To handle that you can use the async and await keywords to make sure that you don't use that support until it's ready.

Typical code might look like this:

async function doSomethingAdHoc(): Promise<void> {
  if (userRequestedASpecialFunction) {
   await import('...relative path to JavaScript file...');
   ...do something...
  }
}

Posted by Peter Vogel on 02/08/2018 at 6:34 AM0 comments


Check That Your Config Files Are Transformed Correctly

Having a process to manage the settings in your application's Web.config file as you move from release to production is essential to ensuring your production Web site works correctly.

One way to handle that is to set up a Web.release.config file with transformation rules to convert your development config file to your production version whenever you compile in Release mode.

In Visual Studio, you can check to see if that transformation is doing what you want by right-clicking on the Web.release.config file in Solution Explorer and then selecting Preview Transformation from the popup menu. Selecting Preview Transformation will open a window with two panes; the pane on the left shows your original file, while the pane on the right shows your transformed version.

Any lines that are modified, added or deleted are automatically highlighted in both panes, making it easy to see what changes will be made. You don't even have to go looking for the changes, either: There's a bar down the right side of the window, flagging where in your config file you'll find your changed lines.

Do be careful, though: It's possible to write your transformation so it doesn't find the part of your config file it's supposed to transform and, as a result, no transformation is made. Other than the absence of a change (something that's hard to notice), there's nothing in the preview to flag that your transformation has failed.

Posted by Peter Vogel on 01/05/2018 at 10:04 AM0 comments


Get Back to the Visual Studio Editor Window Without the Mouse

So your mouse is in some tool pane in Visual Studio and you want to get back to the editor window. You don't have to reach for the mouse -- just press the Escape key. You may have to press the key multiple times but sooner or later, your cursor will probably end up in the editor window. I have to say "probably" because, every once in a while, using Escape won't get you back to the editor window.

To make up for that uncertainty, here's another tip: Once you're back in the editor window, if the current document isn't the one you want, you still don't have to reach for the mouse -- just press Ctrl+F6 to cycle through the currently open documents.

Posted by Peter Vogel on 11/18/2016 at 12:33 PM0 comments


Add a Shortcut to Frequently Visited Code

I had an application with one section I had to work on every couple of months over several years (the client kept changing its collective minds about how it wanted part of the UI -- a search page -- to work). Eventually, I created a shortcut to the section of code I kept having to change so that I could get there quickly. Adding a shortcut is just one step: Click on a line and type Ctrl+K+H.

Returning to that line requires two steps: First, in any version of Visual Studio, you select Task List from the View menu. After that, though, getting to the list of shortcuts depends on which version of Visual Studio you're using. On some versions, you have a dropdown list underneath the title bar in the Task List -- selecting Shortcuts from that dropdown list lets you see your shortcuts.

If, on the other hand, there is no dropdown list, shortcuts appear mixed in with other Task List items. Either way, once you have the list displayed, you navigate to your selected area by double-clicking on its shortcut in the Task List.

As with any other Task List item, you can't delete a shortcut from within the Task List. If you don't want to keep that shortcut around anymore then you'll need to go to that line of code, click somewhere in it and use Ctrl+K+H again to remove the shortcut.

Posted by Peter Vogel on 10/07/2016 at 1:27 PM0 comments


Suppress Columns in Entity Framework Code-First

I'm not a big fan of what I call "aggressive code-first," where your table design is derived from your object design. And, to tell you the truth, I'm not sure I have a good reason for my skepticism. With the one client I worked for who used this process, everything worked out fine (by which I mean that the table design we ended up with was exactly the one I would have recommended).

One issue I have with deriving my table design from my object model is that my object model frequently includes properties that I don't want to have appear as columns in my database. The most obvious example of this are read-only properties whose values are calculated internally (typically, from other properties on the object). Entity Framework is smart enough that it will skip most of these properties but, every once in a while, EF will want to add a column to a table based on a property that I'd prefer EF ignored.

To get EF to ignore the property, just decorate the property with the NotMapped attribute. In this code, for example:

Public Class Customer
  Public Property Status As String
  Public Property Rating As String
  <NotMapped>
  Public Property CreditRating As String
End Class

the Customer class' Status and Rating properties will generate columns in the Customer table but the CreditRating property will not.

Posted by Peter Vogel on 09/30/2016 at 2:18 PM0 comments


Label Your Breakpoints

With more recent versions of Visual Studio, breakpoints you set in your code are saved from one editing session to another. Because you might not always want to stop on those breakpoints, however, you will want to selectively enable and disable them. To facilitate that, from the Debug | Windows menu choice, open the Breakpoints window to view (and manage) all of your breakpoints. From this window you can, for example, double-click on any of the listed breakpoints to be taken to its position in your source code.

The only problem is that, in the Breakpoints window, all breakpoints look very much alike. Fortunately, once you're in that window, you'll also find that you can right-click on any breakpoint and assign it a label that's displayed right beside the breakpoint in the window (you can also right-click on the breakpoint in your source code and assign a label right there). If you're clever about adopting a naming convention you can then sort your breakpoints into groups that you can enable and disable with a single click just by selecting multiple breakpoints in the window. There's no reason, for example, that you can't assign one label to a set of related breakpoints.

There's more you can do in this window. You can assign a condition specifying when the breakpoint should be honored or have the breakpoint write a message to the output window instead of stopping on the breakpoint. You should start thinking of your breakpoints as a resource that lasts the life of your code.

Posted by Peter Vogel on 09/26/2016 at 11:52 PM0 comments


Most   Popular
Upcoming Events

.NET Insight

Sign up for our newsletter.

Terms and Privacy Policy consent

I agree to this site's Privacy Policy.