Extend Your .NET Namespaces for Static Methods and Simpler Code

Let's say you've gone to the trouble of creating a CustomerRepository object with a static method called GetCustomerById. Something like this, in other words:

public class CustomerRepository
{
   public static Customer GetCustomerById(int Id)
   {

   }
}

In your file where you want to use that method you've added the appropriate using statement. Something like this, for example:

using SalesOrderMgmt.Repos;

And that's all great because now you can call your method straight from the class name, like this:

Customer cust = CustomerRepository.GetCustomerById(42);

But, because you're calling a static method, you can simplify your code a little more by extending your using statement down to the class level. Just add the keyword static to your using statement and end it with the class name. In other words, I'd rewrite my previous using statement to this:

using static SalesOrderMgmt.Repos.CustomerRepository;

Now I can use static method from my CustomerRepository class without referencing the class. My call to retrieve a customer object now looks like this:

Customer cust = GetCustomerById(42);

It also works with constants like PI in Math.PI. So go ahead and add this using statement to your code:

using static System.Math;

Now, when you calculate the area of a circle you can just write

double area = radius * PI^2;

Which I think is pretty cool. I can see how the resulting code might confuse the "next developer" who isn't familiar with this -- the next developer might reasonably expect GetCustomerById or PI to be declared in the class where I'm using it. But all that developer has to do is click on the method or constant name, press F12 and be taken straight to the actual code in the class where it's defined. If you're OK with extension methods, this isn't all that different.

Posted by Peter Vogel on 11/08/2019 at 10:46 AM0 comments


Arranging Columns in Visual Studio Windows (with Sorting!)

Admittedly, the tool window I use most in Visual Studio is the Error List (I probably use it even more than I use Solution Explorer). By and large it meets my needs but it is customizable for those occasions when it does not.

For example, the default Error List display includes a Suppression State column that I hardly ever use. If you don't use it either, you can get rid of it, making more room for the columns you do want (to be more specific: the Description column). All you have to do is right-click on any of the column headers in the Error List and pick Show Columns from the pop-up menu. That will give you a menu of available columns with the currently displayed columns checked off. Clicking on any column in the menu will add the column to the display (if the column isn't currently checked) or remove the column (if it is checked). I don't find the Code column all that useful, either, so I got rid of it also, but that might just be crazy talk as far as you're concerned.

The Grouping option on the menu is also sort of interesting: It inserts headings into the error list. I've experimented with adding a heading at the file level so that all the errors and warnings for any file appear together in the Error list, right under the file name. In the end, however, I've always decided that I wasn't willing to give up the space that the heading takes up; I'd rather have more unorganized errors than fewer organized errors, apparently.

Instead, I've counted on sorting to put all of my "related" errors together. I typically sort by Project, File, and Line number. To get that order (or any order you want), first click on the column header for the column you want as your highest sort level (in my case, that's the Project column). Then hold down the Shift key and click on the other columns you want in the sort, moving from the highest level to the lowest level (for me, that's the File column and then the Line column). If you're not happy with a column's order (ascending or descending) just click the column header again to reverse the order. Visual Studio will remember your sort order.

Posted by Peter Vogel on 10/30/2019 at 3:09 PM0 comments


Why Rejection Prevents Zombies in ASP.NET Core

If you're looking for some interesting reading, try this article by Paulo Gomes on hacking ASP.NET (actually, try googling “Hacking ASP.NET” for a bunch of interesting articles). Paulo's article specifically discusses how an innocent Web application can be used to turn your organization's server into some hacker's puppet/zombie.

One part of the article talks about how creating a zombie requires that a malicious payload be uploaded to the ASP.NET site. As Paulo points out, there is a way to avoid this: “General advice is to reject any malformed input” ... which is where the ApiController attribute comes in.

When you create a Web service in ASP.NET Core, you have the option of applying the ApiController attribute to your service controllers. With that attribute in place, when model binding finds mismatches between the data sent to your service and the parameters passed to your service methods, ASP.NET automatically returns a 400 (Bad Request) status code and doesn't invoke your method. Therefore, there's no point inside a Web Service method to check the ModelState IsValid property because if the code inside your method is executing then IsValid will be true.

You can turn that feature off by omitting the ApiController attribute. But, as Paulo points out, you don't want to: The ApiController method is doing exactly what you want by ensuring that you only accept data that is, at least, well-formed. This won't protect you against every hack, of course, but it's a very good start.

Posted by Peter Vogel on 10/22/2019 at 11:03 AM0 comments


How to Integrate Code with Code Snippets in Visual Studio

As I've noted in an earlier post, I don't use code snippets much (i.e. “at all”). One of the reasons that I don't is that I often have existing code that I want to integrate with whatever I'm getting from the code snippets library.

Some code snippets will integrate with existing code. If I first select some code before adding a code snippet, there are some snippets that will wrap that selected code in a useful way. For example, I might have code like this:

Customer cust;
        cust = CustRepo.GetCustomerById("A123");

I could then select the second line of the code and pick the if code snippet. After adding my code snippet, I'd end up with:

if (true)
        {
          cust = CustRepo.GetCustomerById(custId);
        }

That true in the if statement will already be selected, so I can just start typing to enter my test. That might mean ending up with this code:

if (custId != null)
        {
          cust = CustRepo.GetCustomerById(custId);
        }

You have to be careful with this, though -- most snippets aren't so obliging. If you do this with the switch code snippet, for example, it will wipe out your code rather than wrap it. Maybe I should go back to that previous tip on code snippets -- it discussed how to customize existing snippets (hint: you specify where the currently selected text is to go in your snippet with ${ TM_SELECTED_TEXT}).

Posted by Peter Vogel on 10/21/2019 at 12:06 PM0 comments


Calling .NET Methods With and Without Async

Let's say that you have an asynchronous method -- a method that looks something like this one that returns a Customer object wrapped inside a Task object:

public async Task<Customer> GetCustomerById(string custId) {

You can call this method with or without the await keyword. The syntax with the await keyword looks like this:

Customer cust = await GetCustomerById("A123");

Using the await keyword launches the method (and any code that follows it in the calling method) on a separate thread. When the method finishes running, the Customer object is pulled from the Task object and, in this case, stuffed into the cust variable.

The syntax without the await keyword looks like this:

Task<Customer> cust = GetCustomerById("A123");

With this syntax, you get back the Task object that manages the GetCustomerById method ... and that's it. You can now treat this cust variable as you would any other object: pass it to other methods, return it from the method with this code, store it in a global variable, and so on. When you're ready to run the Task in the cust variable, you can do asynchronously by calling the cust variable's Start method.

This code will start the GetCustomerById method running but go right on to the next line of code following the Start method:

cust.Start();

Alternatively, you can retrieve the Customer object returned by the method synchronously by reading the cust variable's Result property.

This code will cause processing to stop dead on this line of code until the GetCustomerById method managed by the Task object returns a Customer object:

Customer custResult = cust.Result;

There's more that you can with a Task object than just call the Start method and read the Result property (in fact, you'll probably use them together). But my point is that it's worth remembering that if you want the Task object associated with your async method, you can have it.

Posted by Peter Vogel on 10/17/2019 at 1:15 PM0 comments


Upgrading to ASP.NET Core Version 3.0: Top Tips

So you got excited about ASP.NET Core and started building an application in ASP.NET Core 2.0, 2.1, or 2.2. Now you're wondering how much work is involved in migrating that application to Version 3.0 which came out in late September.

If you've got a vanilla application the answer is ... it's not that painful. For example, to upgrade to Version 3.0, you just need to go into your csproj file and strip out almost everything to leave this:

<PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

And I do mean "almost everything." For example, any Package Reference elements that you have that reference Microsoft.AspNetCore packages can probably be deleted.

In ConfigureServices, you'll replace AddMvc with one or more of these method calls, depending on what technologies your application uses:

  • AddRazorPages: If you're using Razor Pages
  • AddControllers: If you're using Web services but not Views
  • AddControllersWithView: If you're using Controllers and Views. This also supports Web services so don't use it with AddControllers

In the Startup.cs file's Configure method, you'll change the IHostingEvnvironment parameter to IWebHostingEnvironment. Inside the method, you'll replace your call to UseMvc with:

  • UseAuthorization and UseAuthorization: Assuming that you're using authentication, of course
  • UseCors: If you want to support Cross-Origin Requests
  • UseEndPoints

With UseMvc gone, you'll need to move any routes you specified in that method into UseEndPoints. That will look something like this:

app.UseEndpoints(endpoints =>
    {
      endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });

Those changes are all pretty benign because they all happen in one file. The other big change you'll probably have to make (especially if you've created a Web service) is more annoying: NewtonSoft.Json is no longer part of the base package. If you've been using NewtonSoft's JSON functionality, you can (if you're lucky) just switch to the System.Text.Json namespace. If you're unlucky, you'll have some code to track down and rewrite throughout your application.

Sorry about that.

There's more, of course, and there's a full guide from Microsoft. If you've got a relatively straightforward site, though, these changes may be all you need to do.

Posted by Peter Vogel on 10/14/2019 at 2:48 PM0 comments


How to Create New Code Snippets from Existing Ones in Visual Studio

I'm not a big user of code snippets, but I know developers who are. I've noticed those developers often don't use the default value supplied for the variable part of the snippet (What! All your connection strings aren't in a variable named "conn"?). If you're one of those people or you'd just be happier with a couple more variations on the code snippets that come with Visual Studio, here's how to make that happen.

The first step is to open the Code Snippets Manager (it's on the Tools menu). The next step -- and the hardest part -- is finding the code snippet you want to change. Once you find that snippet in the manager, click on it and then look at the top of the dialog. There's a Location textbox there and in it you'll see the file path to the file that holds the code snippet. Copy that file path (sadly, Ctrl_A won't work but clicking at the start of the path and using Shift_End will).

Once you've copied the path, close the Code Snippets Manager and, from the File menu, select Open > File. Paste the file path you copied into the File Name textbox and hit the <Enter> key. You'll be looking at your code snippet in a Visual Studio editor tab.

Before you make any changes, from the File Menu select the Save ... As menu choice. It's hard to see that choice because the file name -- which is very long -- is inserted into the middle of the menu choice name. If it's any help, the Save ... As choice is the second of the two choices that begin with "Save." Once you've found it, save your file under a new name. Now, if you render the snippet inoperable, you'll still have the original to fall back on and can try again.

You will, of course, want to change the code in the snippet (otherwise why are you reading this?). But make sure that you also change two things in the XML headers at the top of the file. First, change the shortcut to (a) something you'll remember to type when you want this snippet, and (b) something that no other snippet is using. Second, change the snippet's title element to something you'll recognize in the Code Snippet Manager. If you're a decent human being, you'll also change the author tag to your name.

Posted by Peter Vogel on 10/10/2019 at 10:33 AM0 comments


How to Efficiently Validate Against Cross-Site Request Forgery Attacks in ASP.NET Core

If you're worried about CSRF (Cross-Site Request Forgery) attacks (and you probably should be), then you've already added the code to your Views that adds an anti-forgery token to the data that the browser sends back to the server. If you're using HTML Helpers, that code looks like this:

@Html.AntiForgeryToken()

If you're working in ASP.NET Core and have enabled Tag Helpers, then you don't even need to use that code -- the <form> element has a tag helper associated with it that adds the field automatically.

The issue is that, in your HttpPost methods, you need to check that you get that token back. That is easy to do in both ASP.NET MVC and ASP.NET Core: You just add the ValidateAntiForgeryToken attribute to your methods. There was always, of course, the danger that you'd miss adding it to one of your HttpPost methods, which would be ... unfortunate. It would be easier just to add the attribute to your controller class. The problem with that solution is that you'd be incurring the cost of checking for the token with every request, not just with the HttpPost methods.

If this worries you (and you're using ASP.NET Core), then you can add the AutoAntiForgeryToken to your controller classes, like this:

[AutoAntiForgeryToken]
public class TodoListController: Controller
{

This attribute checks only the dangerous methods (that is, only methods that aren't a GET or one of the other methods you never use: TRACE, OPTIONS and HEAD). You'll get all the protection you need and none that you don't.

Posted by Peter Vogel on 09/17/2019 at 8:57 AM0 comments


How to Handle Multiple HttpClients in the Same ASP.NET Core Application

It's not impossible that you're accessing several different methods from the same Web Service in your application. If so, and if you're using the HttpClientFactory (and you should be), you have an opportunity to centralize some of your code.

In your Startup class, you should be calling the AddHttpClient method, which, despite its name, actually adds an HttpClientFactory to your application's services collection. As part of that method, you can pass the AddHttpClient method a string and a lambda expression. In the lambda expression you can provide the code to configure the HttpClient objects created by the factory. When it comes time to create an HttpClient object, you can use the string you provided to get the configuration you specified.

This code, for example, passes the AddHttpClient method the name "phvis" and specifies how the BaseAddress on the HttpClient should be set when this factory is used:

services.AddHttpClient("phvis", hc =>
{
    hc.BaseAddress = new Uri("https://phvis.com/");
});

Now, when you go to create an HttpClient, you can use "phvis" to get a client that's configured for my site. As an example, this code retrieves an HttpClient configured for phvis.com (see my earlier tip on how to retrieve the factory from the services collection so that you can use it here):

var client = factory.CreateClient("phvis");

Because the client has its BaseAddress property already set, you only have to specify the back part of the service's URL when making a request. This example joins a relative URL passed to the GetAsync method with my earlier BaseAddress to send a request to https://phvis.com/Customer/A123:

var response = await Client.GetAsync("/Customer/A123");

And, if you're accessing multiple Web Services, there's nothing stopping you from setting up multiple named clients, each with their BaseAddress set for the various services you're using.

Posted by Peter Vogel on 09/16/2019 at 11:04 AM0 comments


You're Using HttpClient Wrong

There's a very good chance that, every time you need to access a Web Service, you've been creating an HttpClient object and then throwing it away. Unfortunately, that's bad for your application because you can run out of WebSockets (yes, even if you call the object's Dispose method before discarding it). Though, I have to admit, you'll only have this problem if you use the HttpClient a lot. Still, it's a bad idea to keep creating and destroying it.

In the .NET Framework, the intent was for you to create the HttpClient once in your application and use it over and over. To do that you'll have to declare your HttpClient object as a global or static variable. That creates its own problems, of course.

In ASP.NET Core, however, you have a better option: the HttpClientFactory. The HttpClientFactory provides you with HttpClient objects but takes responsibility for managing the resources that the clients can use up. Think of it as "connection pooling for Web Services."

The first step in implementing this tactic is to create an HttpClientFactory object in your project's Startup class in the ConfigureServices method and add it to your application's services collection. All you need is this code (and, yes, I realize that the method's name doesn't do a good job of reflecting what it does):

services.AddHttpClient();

Then, in the constructor for any controller that needs an HttpClient, you can ask for the factory by its interface (IHttpClientFactory). This following example grabs the HttpClientFactory out of the services collection and stuffs it into a field to be used by the methods in the controller:

public class TodoListController: Controller
{
  public TodoListController(IHttpClientFactory factory, ... )
 {
  this.factory = factory;

Now, whenever you need an HttpClient object, you just get it from the factory's Create method, like this:

HttpClient hc = factory.CreateClient();

Posted by Peter Vogel on 09/12/2019 at 12:27 PM0 comments


Logging vs. Reporting Exceptions in Visual Studio

In an earlier tip I disagreed with one of Microsoft's recommendations for handling exceptions. I figure I'm on a roll, so here's another objection to some Microsoft advice on handling errors.

In Microsoft's reference documentation for the Exception object's ToString method, Microsoft recommends using Exception object's ToString method to report errors. The Remarks section of the documentation says that the exception's ToString method "returns a representation of the current exception that is intended to be understood by humans."

That's true if, I guess, by "humans," you actually mean "developers."

Let me make my point. Here's what you'll find in the DivideByZeroException object's Message property:

Attempted to divide by zero.

Here's what's returned by the ToString method:

System.DivideByZeroException: Attempted to divide by zero. at CustomerManagement.CreditManagement.CreditManagement_Load(Object sender, EventArgs e) in C:\\Users\\peter\\Source\\Repos\\Customers\\CustomerManagement\\CreditManagement.cs:line 30

Don't get me wrong: I think that the output of the ToString method is a great thing to put into your application's log file. I also think that inflicting that on a defenseless user is just mean. I think what's in the Message property is what you should give to the user.

Having said all that, however, I'm not suggesting you ignore Microsoft's advice on the Exception object's ToString method. The Remarks also say "The default implementation of ToString obtains the name of the class that threw the current exception, the message, the result of calling ToString on the inner exception, and the result of calling Environment.StackTrace." Precisely because it does make a good log file entry, I think you should be making sure that's what the ToString method does when you create your own custom exception object.

Posted by Peter Vogel on 06/03/2019 at 8:32 AM0 comments


Making Views Serve Two Roles in ASP.NET Core

I hate creating two or more Views that share a lot of HTML because it doubles my maintenance burden by forcing me to keep the two Views in sync. The usual reason I'm doing this is because I have single page that's supporting two user roles and I need to suppress or include some HTML based on the current user's authorization level.

While I try to avoid adding code to a View because I can't automate testing that code, I've been known to put code in Views to conditionally generate HTML to support multiple roles in a single View. The logic is usually pretty simple (a call to some IsInRole method), but it's mixed in and scattered through the HTML that makes up the View.

ASP.NET Core gives me a new tool to use that allows me to tailor a single View for multiple purposes while centralizing my code: The IgnoreSection method. The IgnoreSection method, in a View, allows me to tell the layout View to not pick up a specific section.

For example, I can now put all my command buttons in a section of my View, like this:

@section UpdateButtons { <input type="submit" value="Update" name="Update"/> }

Presumably, the layout View used by this View would incorporate the section into the page with a line like this:

@RenderSection("UpdateButtons", false)

But I want this View to be used both by guests (who aren't allowed to update data) and employees (who are). In ASP.NET Core, I can now suppress the section from being displayed by the layout View by passing the name of the section to the IgnoreSection method.

For example, this code in my View ensures that the UpdateButtons section won't be sent to the user if the user is in the "guest" role:

@if (User.IsInRole("guest")) {
  @IgnoreSection("UpdateButtons")
}

What I like about this is that I can put this logic in the code block at the top of my View instead of scattering it throughout my View. I can also now control what each user sees just by moving HTML in and out of the appropriate sections or by adding and removing sections in my if statement.

There's also a new IgnoreBody method that suppresses a layout View's RenderBody method, but I'm not clear when I'd want to use that. You may have a better imagination than I do, of course.

Posted by Peter Vogel on 05/31/2019 at 8:43 AM0 comments


.NET Insight

Sign up for our newsletter.

Terms and Privacy Policy consent

I agree to this site's Privacy Policy.

Upcoming Events