By david on December 06, 2011

 

In ASP .NET MVC, using ModelState object for server side validation is quite simple.

In the controller method:

if (string.IsNullOrEmpty(model.FirstName))
    ModelState.AddModelError("FirstName", "Please enter the First Name");

 

And in the view:

@Html.TextBoxFor(m => m.FirstName)
@Html.ValidationMessageFor(m => m.FirstName)

How do you add validation error for collection property? It ought to be simple as well, but searching the Internet, I could not seem to find any example. So, I thought posting it here that it might useful for others.

In the controller method:

for (int i=0; i< model.Cars.Count; i++)
{
    if (String.IsNullOrWhitespace(model.Cars[i].Make))
    {
        ModelState.AddModelError(String.Format("Cars[{0}].Make", i), "Please enter the car's make/model.");
    }
}

And in the view:

@for (int i = 0; i < Model.Drugs.Count; i++)
{
    <!-- some other fields... -->
    <input name="Cars[@i].Make" type="text" value="@Model.Cars[i].Make" />
    @Html.ValidationMessageFor(m => m.Cars[i].Make)    
}

The key is that the key we pass to the ModelState’s error collection dictionary matches the rendered tag for identifying the Html element to put the validation message. In above case, the @Html.ValidationMessageFor(m => m.Cars[i].Make) – render to this in my browser:

<span class="field-validation-valid" data-valmsg-for="Cars[0].Make" data-valmsg-replace="true"></span>

 

In this case, the data-valmsg-for matches the key we pass in the ModelState’s error collection dictionary above (e.g. “Cars[i].Make”).

By david on November 11, 2011

 

In Entity Framework 4 – by default Lazy Loading is disabled when creating Object Context. However, if we use the Entity Framework tool to create new model and the corresponding generated class, Lazy Loading is enabled in the object context’s constructor.

Hence, if we want to disable Lazy Loading by default, it would be quite painful every time we update the Model and regenerate the Entity Framework classes, because we would need to go back to the generated Object Context class and reset the LazyLoadingEnabled property to false.

Fortunately, we can instead edit the .edmx file so that the generated Object Context class would have LazyLoadingEnabled property to set to false by default. This option is not available in the Designer UI.

Open the .edmx file as XML file, and edit the following:

<EntityContainer Name="EntitiesContainerName" annotation:LazyLoadingEnabled="false">

Next time you regenerate the classes, the generated Object Context will have by default set LazyLoadingEnabled to false in its constructors.

By justin on October 14, 2011

Sometimes in a ms test project, I have unit tests still being worked on, so they have an [Ignore] attribute applied. When I remove that attribute the test isn’t immediately recognized by visual studio 2010 as enabled. In the past I had to close visual studio and when it is re-opened they are recognized as enabled. Not this time though….

I found a quicker solution keying from this article: http://msdn.microsoft.com/en-us/library/ms182457.aspx

From the test list editor, select the test. Then in the properties window, change the “Test Enabled” property to true.

tests

By david on September 27, 2011

Recently we are working on a project that process and generate EDI document. We are using XSLT to transform internal data format to the EDI Trading Partner’s format. One feature in XSLT that makes live easier is the ability to use extension to write custom logic in code. We use this to do lookup function, conversion (date and time format), etc. during the mapping. Since we are using .NET, we are using the msxsl:script extension.

Below is a code snippet of an XSLT that uses msxsl:script to embed code in the XSLT document.

<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:var="http://schemas.palador.com/Edi/var" version="1.0"
                xmlns:converter="urn:converter">
  <xsl:output omit-xml-declaration="yes" version="1.0" method="xml" />
  <xsl:template match="/FR8Invoice">
    <Interchange>
      <!-- ommitted for clarity -->
      <N1>
        <xsl:variable name="var:v48" select="converter:CustomerType(string(./Type))" />
        <N101>
          <xsl:value-of select="$var:v48" />
        </N101>
      </N1>
      <!-- ommitted for clarity -->
    </Interchange>
  </xsl:template>
  <msxsl:script language="C#" implements-prefix="converter">
    <![CDATA[
    public string CustomerType(string input){
      string customerType = "  ";
 
      switch (input)
      {
          case "Shipper":
              customerType = "SH";
              break;
          case "Consignee":
              customerType = "CN";
              break;
          case "Invoicee":
              customerType = "BT";
        break;
    }
    return customerType;
}
]]>
  </msxsl:script>
</xsl:stylesheet>
By Joe Beernink on July 19, 2011

A coworker and I were in the process of migrating a client’s web server from old hardware to new hardware last week, and we needed to be able to test the system before turning it on to live traffic. The web applications called web services, and the configuration of the web app included the URL for the web services.

We needed to be careful what we were doing here, because the web services were also migrating to a new server, and on this new server, were pointing to a new database server as well. We didn’t want to change all the configuration settings on the new servers, and we couldn’t change the public DNS entry.

I’ve done this before, but not everyone knows about the following trick, so here it is:

On Windows, if you go into your %WinDir%\System32\drivers\etc directory, you’ll find a file called hosts, often referred to as “etc\hosts” or “Etsy Hosts”. Open this file with notepad running as administrator on your machine. The instructions for changing this file are right in there, and it’s pretty easy. We added a new line to file on the new server, (and on the test client) like:

127.0.0.1       www.palador.com

We saved our changes, and then restarted IIS on the box. And presto…

But it didn’t work.

We reset IIS again, and did an ipconfig /flushdns from the command prompt.

And it still pointed to the old domain.

We went back to the Hosts file and everything looked fine. I scratched my head. Then I realized that we had forgotten to put a carriage return after the new line. We added the hard-return, restarted IIS and flushed DNS, and now everything worked.

I’m pretty sure I had run into this exact same issue a few years ago, and that’s why I knew to look for it. Hopefully this will help someone else avoid this issue.

By justin on July 08, 2011

I recently tried to execute some REST queries against a list on our sharepoint server. I received an error saying: Could not load type ‘System.Data.Services.Providers.IDataServiceUpdateProvider’ from assembly ‘System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′.

Some quick googling point to possible issue with the version of ADO.NET data services that ships with Sharepoint. A hotfix is available at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=2343 (for server 2008 R2). This did the trick.

By david on June 15, 2011

 

It is quite common to add an existing record into a collection of another entity. For example, adding an existing Student into a Course. Prior to Entity Framework 4, using Entity Framework – would need to load the Student entity, then add it to the Course object, then save the context. In Entity Framework 4, by using stub entities, as long as we have the primary key(s) for the entity to add to, we do not need to load the entire entity anymore.

Thanks to this post and this post, here is what we come up with:

protected void T AttachToOrGet<T>(string entitySetName, T entity)        
{
    ObjectStateEntry entry;
    bool attach = false;
    if (Context.ObjectStateManager.TryGetObjectStateEntry(
            Context.CreateEntityKey(entitySetName, entity),
            out entry))
    {
        attach = entry.State == EntityState.Detached;
        entity = (T)entry.Entity;
    }
    else
    {
        attach = true;
    }
    if (attach)
    {
        Context.AttachTo(entitySetName, entity);
    }
    return entity;
}
 
public void AddStudent(int courseId, int studentId)
{
    Course course = Context.Courses.Where(c => c.CourseId == courseId).FirstOrDefault();
    if (course != null)
    {
        if (!course.Students.Any(s => s.StudentId == studentId))
        {
            Student stubStudent = AttachToOrGet("Students", new Student { StudentId = studentId });                        
            course.Students.Add(stubStudent);
            Context.SaveChanges();
        }            
    }
}

 

Also do not forget to make sure the bridge table CourseStudent (in case many-to-many relationship between Student and Course) has PKs, otherwise EntityFramework will give you this error message:

“Error from EF (need to have PK) - Unable to update the EntitySet because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.”

By Joe Beernink on June 02, 2011

During testing of an upcoming release of one of our Azure based projects, we began getting intermittent errors while uploading images (blobs) to Windows Azure storage using writable SharedAccessSignatures. I did a search on the web, and oddly enough, one of my previous posts covered a very similar intermittent 403 error. I went through my code and looked for places I might be using Uri.ToString instead of Uri.AbsoluteUri, but even after finding and fixing a couple of those, the problem didn’t go away. 

What was even more odd was that sometimes the same image would work, and sometimes it wouldn’t. What I needed was more information about exactly what was in the 403 error. I started up my trusty copy of Fiddler (and shut off TweetDeck and any other apps sending out network traffic), and started the upload process.

The upload process sends images from a WPF client app to blob storage. But it gets the SharedAccessSignature from a web service which resides on Windows Azure. The timeout on the SharedAccessSignature was set to 60 minutes, which should have been more than long enough for each one of these very small images. This seems like a horribly complicated process, but for binary files, POSTing directly to Azure Blob storage instead of going through a intermediary WCF service gave us an observed 40% speed increase. (your performance may vary).

Fiddler told me what the problem was right away:

The SharedAccessSignature maximum timeout cannot be more than 60 minutes.

What? I set it to exactly 60 minutes. How could it be more than 60? Well, I can think of two ways this could happen:

1) Here’s the code where I was setting up the SharedAccessSignature:

   1: var readPolicy = new SharedAccessPolicy
   2:  {
   3:      Permissions = SharedAccessPermissions.Read | SharedAccessPermissions.Write,
   4:      SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(SharedAccessSignatureMaxTimeout)
   5:  };

where the SharedAccessSignatureMaxTimeout = 60

DateTime.UtcNow isn’t the most accurate call in the world. Potentially, this could lead to a SharedAccessExpiryTime which was just slightly greater than the max. The ticks property of the DateTime is probably more accurate.

2) If the System Times between the Storage Host, the Service Host and the Client are slightly off (something that I would expect to be quite common), I could see the scenario where it would seem like the expiry time appeared to be greater than the one hour allotted. With the large number of files we were sending up, I suspect we just hit this issue more than someone who was uploading a single file.

The solution, in either case, is to reduce SharedAccessSignatureMaxTimeout to be well short of 60 minutes. As soon as we did this, everything worked fine.

By Joe Beernink on May 27, 2011

I’m sure you are all creating unit tests to verify the output of the code you are writing to allow constant regression testing before any check in. But one of the other really nice things about having unit tests is the ability to performance test them when things are running more slowly than you expect.

Here’s how to do it:

  1. Run your list of unit tests in VS2010
  2. View the Test Results Window
  3. Sort the unit tests by duration. If one (or more) is really slow, Right Click on the test.
  4. Click “Create Performance Session”
  5. Select your sampling method and rerun the test.
  6. You’ll need to become familiar with the performance test outputs, but the key thing to look for is the “Hot Path”. Those lines are being called a lot, or taking up the majority of the time.
  7. Fix your code, and rerun the tests to confirm that the results are still correct, and that the fix is actually faster.
By david on May 12, 2011

In the past few months we have been working on TransactVM, a replication-based disaster recovery for Hyper-V™ Virtual Machines. It is integrated with NetApp Storage Systems using the SDK that NetApp provided.

In this blog, we are going to review our experience in integrating with the NetApp Storage Systems.

The SDK comes with client API module for numerous platforms – .NET, Java, C/C++, Perl, etc. In our case, we are using the .NET client API.

The API is a simple client-server RPC-like calls using web service. There is only one main method call – InvokeElem(command). It returns the result. Both the command and the result is in xml format. It also comes with some helper methods – however, no custom types whatsoever (those we define ourselves once we understand the NetApp API model). An example will look like this:

NaServer server = new NaServer(storageAddress, 1, 0) { Style = NaServer.AUTH_STYLE.RPC };
NaElement command = new NaElement("snapmirror-get-status");
command.AddChildElement(new NaElement("location", volume));
try
{
    NaElement snapmirrorStatusXml = server.InvokeElem(command);
    if (snapmirrorStatus == null)
        return SnapmirrorState.Null;
 
    NaElement snapmirrorStatusInfo = snapmirrorStatus.GetChildByName("snapmirror-status-info");
    string state = snapmirrorStatusInfo.GetChildContent("state");
    if (String.Equals(state, "snapmirrored", StringComparison.OrdinalIgnoreCase))
        return SnapmirrorState.Snapmirrored;
    if (String.Equals(state, "broken-off", StringComparison.OrdinalIgnoreCase))
        return SnapmirrorState.BrokenOff;
    if (String.Equals(state, "uninitialized", StringComparison.OrdinalIgnoreCase))
        return SnapmirrorState.Uninitialized;
    if (String.Equals(state, "quiesced", StringComparison.OrdinalIgnoreCase))
        return SnapmirrorState.Quiesced;
    if (String.Equals(state, "source", StringComparison.OrdinalIgnoreCase))
        return SnapmirrorState.Source;
    if (String.Equals(state, "unknown", StringComparison.OrdinalIgnoreCase))
        return SnapmirrorState.Unknown;
}
catch (NaApiFailedException e)
{
    throw new NetAppException(String.Format(CultureInfo.CurrentCulture, "NaApiFailedException ErrorNo: {0}", e.ErrorNo), e);
}

 

It seem a bit cumbersome to have to format command and parse the result when calling the API. However, once we get used to it, it’s quite fun to work with.

Both NetApp Data OnTap OS and the API is quite robust. The API help file is quite extensive. The error codes and messages (along with the API help file) are quite helpful in figuring out problems when they arise.

Integration with Storage Device like NetApp is an important facet in TransactVM – it is providing the bridge between Hyper-V and the storage devices used in conjunction with - to provide replication-based disaster recovery.

We are looking forward to getting this product out the door (Beta is coming very soon)!