One of my favorite features in Visual Studio is Ctrl+- (hold down the Control key and press the minus key). Every time I press Ctrl+-, I skip back to the previous place I rested my cursor. I use this feature a lot when, after navigating through my code to investigate something, I want to get back to my start position so that I can make my actual change.
The only problem with Ctrl+- is that it keeps track of almost every place I stopped -- getting back to the point where I want to make my change can require a lot of key presses.
There is a faster way: The navigation buttons at the left-hand end of the Visual Studio toolbar. In more recent versions of Visual Studio, these are two blue circles with right and left arrows on your toolbar; in earlier versions these are square buttons (still on the toolbar) with a page icon, plus right and left arrows. If you click the little down arrow beside these icons you'll get a list of all the places you visited recently: Just click on the one you want to go back to.
Posted by Peter Vogel on 02/16/20160 comments
I recently wrote a column on how to open a dialog box in an ASP.NET MVC application. In that column, I had the HTML for the dialog box dynamically generated at runtime from a Partial View and retrieved it by issuing an AJAX call from JavaScript running in the browser that called a method in my ASP.NET MVC Controller. To actually display the dialog I used the jQueryUI dialog add-in.
A reader sensibly asked: Why not use the Backbone JavaScript library rather than jQueryUI for that final step? After all, as the reader pointed out, Backbone comes with ASP.NET MVC. Other than habit (I've been using jQueryUI for a very long time) I didn't have a good answer to that question.
So this tip is what you need to do differently if you want to use Backbone to open your dynamically generated dialog and, so, save yourself adding the jQuery library to your project. (One note: to make sense of this tip you might need to read that original column.)
Fortunately, for me, there are only two things to change in moving from jQueryUI to Backbone. First, on the server, I change the HTML I put in the Partial View that defines the dialog (or, as Backbone refers to it, the "modal"). While jQueryUI will display almost any old HTML as a dialog, Backbone prefers a specific structure that enables you, for example, to define the modal's header, body and footer.
Listing 1 show some typical HTML that I could put in a Partial View to generate a Backbone modal that has a title block, a body containing a textbox, and a footer with a button that closes the dialog. That HTML leverages both some Backbone attributes (role, data-dismiss) and some Backbone styles (modal fade, modal-dialog and so on).
Listing 1: HTML for a Backbone Modal
<div id="divModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title">Customer Name</h2>
</div>
<div class="modal-body">
<input type="text" id="CustomerNameNew" value="@Model.FirstName" />
</div>
<div class="modal-footer">
<input type="button" value="Exit" data-dismiss="modal"/>
</div>
</div>
</div>
</div>
Second, I need to change the JavaScript that actually displays the modal. If the Backbone modal's HTML is more complicated than the equivalent jQueryUI HTML, the Backbone JavaScript is much simpler (much of what I did in code with jQueryUI is handled through the HTML that defines the Backbone modal). With Backbone, I just call Backbone's modal function, referencing the div element that defines the modal.
Here's the JavaScript code to call my Controller method on the server (passing some data from the page), insert the resulting HTML retrieved from the View into a div element on the page (called divDialog here) and then display the modal:
function ShowModal() {
$.get("/Home/DialogHTML/",
{ id: $("#CustomerId").val() },
function (dialogHTML) {
$("#divDialog").html(dialogHTML)
$("#divModal").modal();});}
By the way, if you don't need to generate your modal's HTML dynamically at runtime (for example, if the dialog is nothing but static HTML) you can add Backbone's data-toggle and data-target attributes to an element so that, when that element is clicked, your modal will display. This input element will display a dialog in the same page:
<input type="button" id="showModal" value="Get Customer Name" data-toggle="modal"
data-target="#divModal"/>
without requiring any JavaScript!
Posted by Peter Vogel on 02/05/20160 comments
In your Views, you can get the BeginForm helper to not only write out the open tag for your HTML form, but to write out your form's end tag. The trick is to call BeginForm as part of a Using block. The code looks like this, in Visual Basic:
@Using Html.BeginForm(...parms...)
@Html.EditorFor(...
...rest of form...
End Using
This C# code does the same thing:
@using (Html.BeginForm(...parms...))
{
@Html.EditorFor(...
...rest of form...
}
At the end of the Using block, the compiler will automatically call the Dispose method of the class the BeginForm uses. That Dispose method will politely add the end form tag to your page, so you'll end up with something like this:
<form action="...rest of the attributes...>
<input type="text"...
...rest of form...
</form>
As you can see, the Using block also creates a structure in your View that you can slip all of your form elements inside.
Posted by Peter Vogel on 01/28/20160 comments
Believe it or not, there are times when you have a member in your class that you don't want to appear in the class's IntelliSense lists.
In a column earlier this month I talked about how to have your class work with the .NET Framework support for formatting strings (things like "{0:G}," for example). By the time I had finished implementing this feature, my sample class had a method that no developer would ever call -- the method would only be called by .NET Framework components.
Because my method will never be called by a developer, it doesn't make a lot of sense to have that method cluttering up the class's IntelliSense list. To stop that method from appearing in the class's IntelliSense list, I could decorate the method with the EditorBrowsable attribute, passing the enumerated value EditorBrowsableState.Never. Here's the method from that column with the attribute applied to it:
<EditorBrowsable(EditorBrowsableState.Never)>
Public Function ToString1(format As String, formatProvider As IFormatProvider) As...
The trouble is, other than suppressing this ToString method, I literally cannot think of any other case when I'd want to use this attribute (after all, if I wanted a developer to stop using the method, I'd decorate it with the Obsolete attribute).
I suppose you could use the two attributes together: one to hide the method so a developer won't know about it while keeping the method in the class so old code would run; the other attribute to generate compile time warnings about how existing code should stop using the method. But that sure seems like a lot of work to invest in something you don't want people to use.
Posted by Peter Vogel on 01/21/20160 comments
LINQ with Entity Framework has become so common that, when I'm looking at a client's code I'm finding some pretty scary-looking LINQ queries running against Entity Framework. Since I'm a big fan of Really Obvious Code (ROC) -- ROC Rocks! -- I hate having to parse out these queries to try and figure out what the query is doing (and what's wrong with it).
You might be tempted to write a comment to explain the query (but I don't like that, either).
The right answer is to break down your complicated query into several smaller, easily readable queries that build on each other. While this isn't a particularly complicated example, these two queries find all of the people whose last name is "Vogel" and work for PH&VIS:
Dim persVogel = From p In db.People
Where p.LastName = "Vogel"
Select p
Dim persVogelPHVIS = From pp In persVogel
Where pp.Company.Name = "PHVIS"
Select pp
While this looks inefficient, it's not. It's important to remember that a LINQ query doesn't result in any data retrieval: At this point in my sample code, my persVogel and persVogelPHVIS variables are just holding LINQ queries; the variables aren't holding the results of those LINQ queries (at least, not holding the results yet).
It isn't until you start working with the individual objects that Entity Framework will finally issue a SQL statement against your database. When that SQL query is finally issued, Entity Framework will take care of collapsing those two LINQ queries into one SQL statement for you.
One way to trigger that retrieval is to use the ToList method. If my LINQ queries were in a method, then I might finish the method with code like this:
Return persVogelPHVIS.ToList()
At this point, when the ToList method executes, Entity Framework will finally retrieve the data and create a collection of objects from that data.
Besides, those collections of objects are more generally useful than the LINQ queries. I've had numerous clients call me up to ask why they're getting messages like "Unable to cast object of type..." when passing a LINQ query to some function. The usual solution is to add a call to ToList to force Entity Framework to retrieve the data.
Posted by Peter Vogel on 01/19/20160 comments
You want to compare/view two parts of the same file at the same time. You have two choices for making this happen.
First, you can click on the divider bar at the top of the scroll bar on the right side of your editor window. Dragging that bar down divides your code window into two panes (one on top of the other), which you can scroll through independently.
However, each of these panes is now smaller than the original window. If you want to see your code in a full-size window then go to the Window menu and select New Window. You'll get a second window with the same name but with ":1" tacked on the end (for example, "Customer.cs" and "Customer.cs:1"). If you want, you can drag one of the tabs to another monitor (something you can't do with the divider bar).
Either way, changes you make in one window/pane automatically appear in the other window/pane.
If you're using Visual Studio 2010, this feature is turned off for some languages (the team ran out of time to completely test it). You'll need to make a change to your Windows Registry to turn it on.
Posted by Peter Vogel on 01/14/20160 comments
Oracle needs two NuGet packages in order to work with Entity Framework: one to use at design time and one to use at run time. You'll need to make sure both of these are installed (and it doesn't help that their names are so similar):
- ODP.NET, Managed Entity Framework Driver
- ODP.NET, Managed Driver
You'll also need to install Oracle's ODP.NET_Managed_ODAC package.
As much as I'd like to pretend that I'm all-knowing but this information comes from Yonayli Gutierrez (Hi, Yonayli!) who took one of Learning Tree's ASP.NET MVC classes.
Posted by Peter Vogel on 01/05/20160 comments
In TypeScript, you can define a function that, when passed a set of parameters, creates and returns a correctly configured object. One of the parameters passed to the function must be the class of the object being created (I'll call that the "class parameter"). Normally, that means your factory function can only create a single kind of class but, by leveraging generics and interfaces, you can create functions that will create and configure a variety of classes.
Your first step is to define an interface that specifies the properties that your factory function will configure. Here's an example of an interface that specifies two properties:
interface ICustomer
{
name: string;
age: number;
}
With that interface in place you can create a generic factory function that works with any class that implements that interface. First, when defining your factory function, follow the factory function's name with a data type marker and specify that the marker extends the interface. Second, in the factory function's parameter list, use TypeScript's new keyword along with the generic data type marker when defining the function's class parameter (you're actually specifying the type of the class' constructor).
The following code shows the declaration of a generic factory function that leverages my ICustomer interface. I first provide a type marker (c) that, using the extend keyword, ties the function to classes that implement the ICustomer interface. I then use that type marker with the new keyword to specify the return type of the function's class parameter (called cust in my example):
function CreateCustomer<c extends ICustomer>(cust:{new(): c;},
name: string, age: number): c
{
Now, inside my function, I use the class parameter to instantiate the class passed in the class parameter. Once I've done that, I can configure the object by setting the properties specified in the interface:
var newCust: c;
newCust = new cust();
newCust.name = name;
newCust.age = age;
return newCust;
}
To use this factory, I pass the class I want created (which must implement the ICustomer interface) along with the rest of the parameters required by my factory function. This example:
var cust: Customer;
cust = CreateCustomer(Customer, "Peter", 62);
uses my function to create an instance of a class called Customer.
Posted by Peter Vogel on 12/28/20150 comments
At least two or three times in my life, I've come back to old systems I'd worked on and realized that I now knew a better way of doing things. However, rather than just revise existing code, that "better way of doing things" required me to write a new method, property or class. When I released my new code out into the world, I wanted to tell other developers to stop using my old code and move to my new code. The best way to do that, I've decided, is to go back to the old code and decorate it with the Obsolete attribute.
You can add the Obsolete attribute either to a class or to members of a class. Regardless, when a developer attempts to use the item you've decorated, they'll get a warning message in their code that says the class (or the member) you've decorated with the attribute is deprecated.
Of course, developers aren't likely to stop using your class or method unless you tell them about your alternative. You can do that by passing a message to the Obsolete attribute -- that message is then tacked onto the end of the attribute's default warning message. This example will generate the message "'SampleClass' is obsolete: Use PHVIS.NewClass" when someone tries to use SampleClass:
<Obsolete("Use PHVIS.NewClass")>
Public Class SampleClass
Public Sub SampleMethod()
End Sub
End Class
By default, the Obsolete attribute just generates a warning message so it won't stop the developer's code from compiling. If you want to be more aggressive, you can pass True as the attribute's second parameter to generate a compile-time error and prevent the developer's code from compiling, as this example does:
Public Class SampleClass
<Obsolete("Use BetterMethod", True)>
Public Sub SampleMethod()
End Sub
End Class
I'd wait awhile before doing that, though.
Posted by Peter Vogel on 12/17/20150 comments
I was teaching Learning Tree's ASP.NET MVC course a few weeks back. The author of that course decided that having code lines extend past the right-hand edge of the code window wasn't a good idea if you're an instructor demoing some code. To eliminate those disappearing lines on the demo computer we use in the course, he turned on word-wrap for Visual Studio. This choice keeps all of the code on the screen by wrapping long lines of code back to the left hand margin.
If you like that idea, it's easy to turn on that option. Go to Tools | Options | Text Editor | All Languages and select the "Word wrap" choice on the right. That's all you need to do but, if you want, you can also have Visual Studio put a U-turn arrow at the end of each line that's too long to fit in the window -- just click the "Show Visual Glyphs for word wrap" option under the Word wrap choice.
Posted by Peter Vogel on 12/15/20150 comments
If you've ever wanted to create a .zip file from your application, the System.IO.Compression.GZipStream will let you do it, assuming that you're comfortable with your file being in the industry-standard .gzip format (though I'm told you can swap in other compression schemes).
For this tip, I'm assuming that the file is small enough that you can read it all in one gulp. In that scenario, my first move is to define a FileStream object for the file I want to compress, read the file into memory, and close the FileStream:
Dim unCompressedFile As FileStream
unCompressedFile = File.OpenRead("C:\GreatBigFile.txt")
Dim bytes(5000) As Byte
Dim bytesRead As Integer
bytesRead = unCompressedFile.Read(bytes, 0, 5000)
unCompressedFile.Close()
My next move is to create a FileStream object for the compressed file I want to create:
Dim CompressedFile As FileStream
CompressedFile = File.Create("C:\IttyBittyFile.gzip")
With all the files in place, I'm ready to create the GZipStream object that will do the actual compression. You have to pass two parameters when creating the GZipStream object: The first is the FileStream for the compressed file you intend to create; the second indicates that you want to compress the file.
Here's my code to create a compressed file called IttyBittyFile.gzip:
Dim zipper As GZipStream
zipper = New GZipStream(CompressedFile, CompressionMode.Compress)
Now I can use the GZipStream Write method to write out the compressed file, passing the bytes I retrieved from the original file:
zipper.Write(bytes, 0, bytesRead)
Finally, of course, I close the GZipStream object and my compressed file:
zipper.Close()
CompressedFile.Close()
As you probably suspect, if you change the CompressionMode and pass in a compressed file, you can use GZipStream to decompress a file.
Posted by Peter Vogel on 12/10/20150 comments
In my regular Practical.NET column, I showed how easy it is to create NuGet packages and discussed how it was a much better way for a developer to share anything you've created, from Entity Framework classes to JavaScript files (my example was a package that implemented an HtmlHelper consisting of a DLL and a JavaScript file). NuGet also allows you to attach searchable documentation to your package to ensure that a developer can find your package, recognize it and know what your code does.
In that article, I showed how to use a folder as a repository for NuGet packages. But if you'd like something a little more professional, you can create a NuGet Web site. It's easy to do: First, in Visual Studio, create an Empty Web Application. Once the project appears in Solution Explorer, right-click on it and select Manage NuGet Packages. In the NuGet Package Manager, do a search for the NuGet.Server package and install it.
After deploying your Website, you just need to do two things:
- Save your NuGet packages into the Packages folder in your new site.
- Tell Visual Studio about your site.
My earlier article walks through both processes. You can get the information for your site by surfing to it with your browser -- its default page provides both the file path to the folder you should save your package in and the URL you should use when telling Visual Studio about your NuGet site.
I'll put in one caveat: I only tested this on IIS 7.
Posted by Peter Vogel on 12/03/20150 comments