Best vb.net questions in February 2011

Is it possible, in MVC3, to have the same controller name in different areas ?

8 votes

In MVC3, I have the following areas:

  • Mobile
  • Sandbox

Then i route maps like this:

    context.MapRoute(
        "Sandbox_default",
        "Sandbox/{controller}/{action}/{id}",
        new { controller = "SandboxHome", action = "Index", id = UrlParameter.Optional }

and

    context.MapRoute(
        "Mobile_default",
        "Mobile/{controller}/{action}/{id}",
        new { controller = "MobileHome", action = "Index", id = UrlParameter.Optional }
    );

The problem is this gives urls like:

http://localhost:58784/Mobile/MobileHome

and

http://localhost:58784/Sandbox/SandboxHome

But I want it like this:

http://localhost:58784/Mobile/Home
http://localhost:58784/Sandbox/Home

The problem is when I rename the SandboxHome-Controller to Home, and the MobileHome-Controller to Home, which would give the desired URLs, it won't compile, saying it has two classes for HomeController.

How can I have the same controller name in different areas ?

Yes.

As explained by this blog post: http://haacked.com/archive/2010/01/12/ambiguous-controller-names.aspx

You need to specify the namespace on the default route in global ASAX to prevent conflicts.

//Map routes for the main site. This specifies a namespace so that areas can have controllers with the same name
routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        new[]{"MyProject.Web.Controllers"}
 );

As long as you keep the Area controllers within their own namespaces. This will work.

What are the advantages to wrapping system objects (File, ServiceController, etc) using the Adapter pattern vs. detouring for unit testing?

7 votes

Consider the following method that stops a service:

Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean

    Try
        Dim service As New ServiceController(serviceName)
        Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)

        service.[Stop]()

        If timeoutMilliseconds <= 0 Then
            service.WaitForStatus(ServiceControllerStatus.Stopped)
        Else
            service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
        End If

        Return service.Status = ServiceControllerStatus.Stopped

    Catch ex As Win32Exception
        'error occured when accessing a system API'
        Return False
    Catch ex As TimeoutException
        Return False
    End Try

End Function

In order to unit test the the method I basically have two options:

  1. Use the Adapter pattern to wrap the ServiceController class's methods I need into an interface I can control. This interface can then be injected into the service class (a.k.a Inversion of Control). This way I have a loosely coupled code and can use the traditional mocking frameworks to test.
  2. Keep the class as is and use Microsoft Moles (or any other code detouring framework) to intercept the calls to ServiceController to return canned results for testing purposes.

I agree that for domain model code that using the "traditional" unit testing approach makes the most sense as this would lead to a design that is easiest to maintain. However, for code that deals with the .net implementation of Windows API related stuff (file system, services, etc), is there really an advantage to going thru the extra work to get "traditionally" testable code?

It's hard for me to see the disadvantages of using Microsoft Moles for things such as ServiceController (or the File object). I really don't see any advantage of doing the traditional approach in this case. Am I missing anything?

Great question btw.. Just had a look at MS Moles video right now. Although I'm skeptical of MS Unit-testing tools, I must say this one looks interesting. My comparison stands at:

Adapter/Facade

  • Pro: allows you to extract a meaningful role with intention revealing methods. e.g. ServiceManager.StartService(name) could abstract the details {1. ServiceController.GetServices(), 2. handle case where ServiceController.Status != Stopped, 3. ServiceController.Start()}. The mock/fake approach here would involve less work than setting up 3 delegates. Here this approach is an opportunity to improve your design by coming up with meaningful contracts/interfaces (also allows you to hide stuff that you don't care about -- e.g. Winapi semantics, constants, etc)
  • Pro: Mocking frameworks would give you better diagnostics for argument checks, number of times called, expectations not called etc.

Interceptor

  • Pro: Less work if you're just interested in stubbing out a problematic call on a dependency
  • Pro: definitely a good tool in your toolbox when dealing with legacy code (where the fear of change is overwhelming)
  • Con: does it have a MSTest dependency? Initial searches seem to indicate that you need some plugins or extensions if you're not using MSTest.

Reading Guitar Pro files

6 votes

I was wondering if anybody had heard of a library, preferably a .NET assembly, but Java will do as wel, that allows you to read the data in a Guitar Pro file (.gp3-gp4-gp5)

I have this gigantor of a folder with about 50.000 song files, and would really love to write something that can actually archive all these files, for easier searching. And basic information like the tuning of the instruments in the song would be very useful parameters to retrieve from the file and add to the database.

I have searched the web but have yet to find anything like this, or a file definition for writing my own parser.

Thank you in advance for any information on the subject.

TuxGuitar is an open source Java application that includes classes that read Guitar Pro files. If should be probably more that sufficient for reading basic metadata.

Your other option is using reverse-engineered file format documentation - there's one from DGuitar project.

Your third option is trying to re-use some code from KGuitar project, that also include Guitar Pro 3/4/5 files importing clasess, but it's in C++ and Qt.

How To Do a Server To Server File Transfer without any user interaction?

6 votes

In my scenario, users are able to upload zip files to a.example.com

I would love to create a "daemon" which in specified time intervals will move-transfer any zip files uploaded by the users from a.example.com to b.example.com

From the info i gathered so far,

  1. The daemon will be an .ashx generic handler.
  2. The daemon will be triggered at the specified time intervals via a plesk cron job
  3. The daemon (thanks to SLaks) will consist of two FtpWebRequest's (One for reading and one for writing).

So the question is how could i implement step 3?

  • Do i have to read into to a memory() array the whole file and try to write that in b.example.com ?
  • How could i write the info i read to b.example.com?
  • Could i perform reading and writing of the file at the same time?

No i am not asking for the full code, i just can figure out, how could i perform reading and writing on the fly, without user interaction.

I mean i could download the file locally from a.example.com and upload it at b.example.com but that is not the point.

To answer your questions - yes you can read and write the files at the same time.

You can open an FTPWebRequest to ServerA and a FTPWebRequest to ServerB. On the FTPWebRequest to serverA you would request the file, and get the ResponseStream. Once you have the ResponseStream, you would read a chunk of bytes at a time, and write that chunck of bytes to the serverB RequestStream.

The only memory you would be using would be the byte[] buffer in your read/write loop. Just keep in mind though that the underlying implementation of FTPWebRequest will download the complete FTP file before returning the response stream.

Similarly, you cannot send your FTPWebRequest to upload the new file until all bytes have been written. In effect, the operations will happen synchronously. You will call GetResponse which won't return until the full file is available, and only then can you 'upload' the new file.

References:

FTPWebRequest

Stubbing ASP.NET Page.Form for unit tests

6 votes

Fo unit testing ASP.NET controls I need a stubbed Page.

I can create an ASP.NET Page object in my unit tests by subclassing System.Web.UI.Page. However, I cannot find a way to set Page.Form. Adding a form with attribute (runat,server) does not work. Overloading the form in my Subclass does not give the required functionality.

Context: I try to unit test some homemade ASP.NET controls. These control require Page and Page.Form not to be null.

Any suggestions?

Try defining an IPage and IForm interface that implement the needed methods and properties and create classes that implements those interfaces and wraps a Page or Form class. This way you can test the logic in those controls, without calling into the ASP.NET framework during unit testing.

UPDATE:

Overriding the page property will be brittle and is not advisable. Instead, you should try to minimize the amount of untestable code, by extracting logic in methods that don't depend on any ASP.NET specific (hard to test) parts. Take a look at the following example:

public class MyLabel : Label
{
    protected override override void RenderContents(HtmlTextWriter writer)
    {
        IPage page = new PageWrapper(this.Page);
        this.MethodToTest(page);

        base.RenderContents(writer);
    }

    internal void MethodToTest(IPage page)
    {
        // Work with IPage interface.
        if (page.IsPostBack)
        {
            this.Text = string.Empty;
        }
    }
}

By extracting the logic out of methods that are hard to test, you can call those extracted methods directly in your tests. For instance:

[TestMethod]
public void MethodToTest_ScenarioToTest_ExpectedBehavior()
{
    // Arrange
    var label = new MyLabel();

    var page = new TestPage()
    {
        IsPostBack = true
    };

    // Act
    label.MethodToTest(page);

    // Assert
    Assert.IsTrue(string.Empty, label.Text);
}

It would be even better if you would be able to extract the code under test to it's own class and call it from your WebControl. This is however, not always possible.

I hope this makes sense.

Event parameter; "sender as Object", or "sender as T"?

5 votes

When I write public events for my business objects, I've adapted the habit of always passing the instance as "sender as Object", in addition to additional specific parameters. I just asked myself now why am I not specifying the class?

So for you with more experience; Do you ever pass the distinct class as sender in an event? And if so, what are your decision criteria for when this is ok/not ok?

Don't be extreme. EventHandler(object sender, EventArgs e) has an object sender so that we can use it in many circumstances. But it doesn't mean a strongly-typed sender is evil. A strongly-typed sender is useful when this delegate is not going to be widely used(like EventHandler) e.g.

public delegate void SaveHandler(Controller sender, EventArgs e);

Now other developers(or someone using your library) can recogonize that the sender have to be a Controller, and they will be glad not to code like this:

public void MySaveHandler(object sender, EventArgs arg)
{
   var controller = sender as Controller;
   if (controller != null)
   {
       //do something
   }
   else
   {
       //throw an exception at runtime? 
       //It can be avoided if sender is strongly-typed
   }
}

And you can even make it generic:

public delegate void SaveHandler<T>(T sender, EventArgs args) 
                                              where T: IController;

It's pure legal and good practice in C#. You should make clear what you want to do, and then choose the better way. Either of them is evil/bad.

Disable multiple network connections, only allow one simultaneously

5 votes

Hi,

We are looking to design a security application that does the following on laptops:

  • If the ethernet adapter is used (cable plugged in) disable/block all other network connections (wireless WIFI, mobile broadband (PPP), virtual VPN adapters etc)
  • When ethernet adapter is not being used again, all connections allowed.

Does anyone have any good suggestion on how to accomplish this?

We have looked in the WMI a lot but there are no good ways of doing this. Only disabling the network connection is not secure enough because most mobile broadband applications try to re-establish the connection. This should be an application that works on all laptop vendors without any user interaction (such as choosing interfaces etc..).

So any suggestions on how to accomplish this would be much appreciated.

There are different ways of doing this. As stated by others in this question it needs to be done on a lower level than what the WMI allows. There are some C++ examples around that addresses this issue. Check out the library NETCONLib by Microsoft.

How can I quickly up-cast object[,] into double[,]?

5 votes

I using Microsoft.Office.Interop.Excel I get returned a 2D array of type object[,] which contains double for elements. Note that the index lower bound is 1 instead of the default 0, but I can deal with that easily.

How can nicely convert the array into double[,] using .NET 3.5. (by nicely I mean concise, or compact).

Note that

double[] values_2 = values.Cast<double>().ToArray();

does work, but it flattens by array into a 1D structure.

object[,] src = new object[2, 3];

// Initialize src with test doubles.
src[0, 0] = 1.0;
src[0, 1] = 2.0;
src[0, 2] = 3.0;
src[1, 0] = 4.0;
src[1, 1] = 5.0;
src[1, 2] = 6.0;

double[,] dst = new double[src.GetLength(0), src.GetLength(1)];
Array.Copy(src, dst, src.Length);

Is there something like "global::" for VB.NET?

4 votes

I am writing a code-generator that will need to output some miniscule portions of VB.NET code, and since this is a code generator that will add user-provider code, I'd like to try to avoid type name conflicts with types or names in the user-provided code.

In C#, I can prefix types with global:: to make sure they're matched from the global type namespace hierarchy, rather than some local name, but is there a similar system for VB.NET?

ie. this:

global::System.String

It's simply the Global keyword:

Dim n As Global.System.Int32

SocketException : No such host is known

4 votes

Hi. I want to connect to mysql database from my asp page.So for that as per what my hosting providers told i used the connection string where server is given as "localhost:3309"

Dim myConnection As MySqlConnection = New MySqlConnection("server=localhost:3309; user id=TID; password=TPWD; database=TDB; pooling=false;")

Dim strSQL As String = "SELECT * from Device_Data"

Dim myDataAdapter As MySqlDataAdapter = New MySqlDataAdapter(strSQL, myConnection)
Dim myDataSet As DataSet = New DataSet()
myDataAdapter.Fill(myDataSet, "Device_Data")

MySQLDataGrid.DataSource = myDataSet
MySQLDataGrid.DataBind()

But when i run this page i got this error

[SocketException (0x2af9): No such host is known]
System.Net.Dns.GetAddrInfo(String name) +6134386
System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6) +136
System.Net.Dns.GetHostEntry(String hostNameOrAddress) +109
MySql.Data.Common.StreamCreator.GetDnsHostEntry(String hostname) +123

[Exception: Call to GetHostEntry failed after 00:00:02.2499197 while querying for hostname 'localhost:3309': SocketErrorCode=HostNotFound, ErrorCode=11001, NativeErrorCode=11001.]
MySql.Data.Common.StreamCreator.GetDnsHostEntry(String hostname) +405
MySql.Data.Common.StreamCreator.GetStream(UInt32 timeout) +457
MySql.Data.MySqlClient.NativeDriver.Open() +215

[MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.]
MySql.Data.MySqlClient.NativeDriver.Open() +283
MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings) +51
MySql.Data.MySqlClient.MySqlConnection.Open() +362
System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +123
System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +319
System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable) +92
show.form1_Load(Object sender, EventArgs e) in 
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74
System.Web.UI.Control.LoadRecursive() +146
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

So is this the server issue?? If yes then what should they do to resolve this issue? When contacted the server guys they are saying this is my coding issue.. Are they right?

The correct connection string for MySQL ADO.NET Connector is

Server=localhost;Port=3309;Database=Test;Uid=username;Pwd=password;

Good book for learning about interfaces, abstraction, etc.

4 votes

In my applications I use objects and classes, but when reading SO topics, I have the idea I don't use real OOP principles. For example, I never use inheritance or interfaces. Therefore, I am trying to learn proper OOP (in VB.NET), but I find some concepts quite hard to understand (even after reading a lot about the subjects on SO).

So I'm trying to find a book or resource with good practical real-world examples. For instance, I kind of understand examples like using an interface for both Dog and Cat classes when using a EatFood method, but I find it hard to relate it to real-world cases.

Ideally these books or resources should cover explanations about: - when and why to use inheritance or interfaces or abstract classes - when and why to use private, public, protected, virtual etc. - best practices in dependency injection /inversion of control - when to use aspect oriented programming - using of constructors - solid principles - singletons - encapsulation

Perhaps it's a mix of all kinds of concepts, but I think these are all related to OOP, please correct me if I'm wrong.

I would prefer a book/resource with VB.NET examples, but this might be difficult?

Professional Design Patterns in VB.NET

http://www.amazon.com/Professional-Design-Patterns-NET-Applications/dp/1590592743

Does one still write tests with TDD when the desired code has little to no logic? Why?

3 votes

TDD is supposed to have 100% code coverage. Does this mean one is supposed to write tests for property getter and setters, and other methods that contain no real logic, such as dealing with external API functionality?

Example 1:

Below is one example method (which happens to also be the example in this other SO question which deals with how best to test it, if we are going to test it). This method doesn't do much. It's a facade of the System.ServiceProcess.ServiceController functionality of stopping a service. Currently this code was not being written using TDD, but if it was, would it be something that one should test? There is very little logic here. The test in and of itself wouldn't be that helpful.

FYI: If you'd like to answer on how best to test it (IoC & Adapter Pattern vs. Detouring) please see this other SO question.

Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean Implements IWindowsServicesService.StopService

    Try
        Dim service As New ServiceController(serviceName)
        Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)

        service.[Stop]()

        If timeoutMilliseconds <= 0 Then
            service.WaitForStatus(ServiceControllerStatus.Stopped)
        Else
            service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
        End If

        Return service.Status = ServiceControllerStatus.Stopped

    Catch ex As Win32Exception
        Return False
    Catch ex As TimeoutException
        Return False
    End Try

End Function

Example 2:

In case one argues that the code still has some logic, and therefore it needs to be tested when doing TDD, then what about the following code that has no logic:

Public Function GetProcess(ByVal serviceName As String) As Process
    Dim managementObject As New ManagementObject(String.Format("Win32_service.Name='{0}'", serviceName))
    Dim processID As Integer = CType(managementObject.GetPropertyValue("ProcessID"), Integer)
    Dim process As Process = process.GetProcessById(processID)
    Return process
End Function

TDD is not supposed to have 100% code coverage. TDD tends to have very high code coverage, as compared to other methodologies. If you don't write a line of code without a failing test, if you follow that strictly, then yes, you'll get to 100% coverage. But most of us don't follow that strictly, and perfect code coverage is not the objective of TDD. High code coverage is a nice side effect of Test-Driven Development, but it is not the point.

Most of us don't test-drive simple getters and setters specifically as part of the TDD process. But we're not creating that field which needs the getter and setter until we have a need for it - where "need" is defined as a failing test. So the getter & setter will be tested as a matter of course, because they're created as needed by methods we are test driving.

Both of your examples have enough logic in them to be worthy of tests; I would test-drive both of them.

Programmatically reset Windows XP IDLE time

3 votes

Windows resets the IDLE time every time the user touches the keyboard or the mouse. My application needs to reset the IDLE time at specific moments, but i can't figure out how to do this programmatically.

The following does NOT reset the IDLE time using VB, C# or QT4.
- Programmatic mouse movement / click.
- Programmatic keystroke.
Somehow Windows knows these actions are simulated.

How can i reset the IDLE time? Any thoughts will be greatly appreciated!

In principle SetThreadExecutionState() should do what you need. But I have found it not to work with the system required flag in some situations on some modern Windows. Sorry, I can't remember exact details.

As a fallback you can just fake some input by calling SendInput() with a null mouse move message for example. My guess is that your input faking failed because you called SendMessage or PostMessage.

Dynamic ID name in ASP.NET VB.NET

3 votes

I have about 20 asp:labels in my ASP page, all with ID="lbl#", where # ranges from 0 to 22. I want to dynamically change what they say. While I could write

lbl1.Text = "Text goes here"

for all 23 of them, I'd like to know if there is a way to loop through all of them and change their text.

I thought of creating an array with all my labels, and then just do a For Each loop, but I also have to check if the element exists with IsNothing before I change its text, so I got stuck there.

If anyone can help me, I'd really really appreciate it!

Thank you so so much for your help!!

You can dynamically look up controls on the page by using the System.Web.UI.Page.FindControl() method in your Page_Load method:

Dim startIndex As Integer = 0
Dim stopIndex As Integer = 22

For index = startIndex To stopIndex
    Dim myLabel As Label = TryCast(FindControl("lbl" + index), Label)

    If myLabel Is Nothing Then
        Continue For
    End If

    myLabel.Text = "Text goes here"
Next

VB.NET Equivalent of this code

3 votes

What would be the VB.NET equivalent of this code..

public virtual ICollection<Comment> Comments { get; set; }

VB.NET (in version 10) has automatic properties just like C#. The equivalent syntax is as follows:

Public Overridable Property Comments() As ICollection(Of Comment)

The automatic converters tend to produce syntax that is more verbose than necessary. You can expand it if you want, but it's not strictly necessary unless you're using an older version of the compiler:

Private m_Comments As ICollection(Of Comment)

Public Overridable Property Comments() As ICollection(Of Comment)
    Get
        Return m_Comments
    End Get
    Set(ByVal value As ICollection(Of Comment))
        m_Comments = value
    End Set
End Property

Converting C# Razor to VB

3 votes

I'm following the ASP.NET MVC Tutorial and having started in VB.NET I'm having trouble converting the following razor code:

enter image description here

I have got

<ul>
    @For Each g As MvcApplication1.Genre In Model
        <li> @g.Name </li>
    Next

</ul>

but getting

Attribute Sepcifier is not a complete statement

on both the <li> tags. I understand I need to use line continuation but can't figure out where. I'd be greatful if you can point out the problem.

Put an @ before the li:

<ul>
    @For Each g As MvcApplication1.Genre In Model
        @<li>@g.Name</li>
    Next
</ul>

I would recommend you the following article.