Wednesday, May 4, 2011

Extending ObservableCollection to notify when an Item has changed.

By Miguel Juárez

There are several times that we would like that our collection would have the ability to notify not only when an element is added or removed from the collection itself (like the ObservableCollection does), but also to notify when any of the items’ property changes (when the items themselves are already implementing the INotifyPropertyChanged interface). Here I propose a solution for this problem.

What I’ll basically do is to extend ObservableCollection to provide for such capabilities. I will also define a new EventHandler (with a new EventArgs type) which the consumer can subscribe to get information from the PropertyChanged, such as the Property Name, or the Item’s Index in the collection.

public class NotifyCollectionChangeEventArgs : PropertyChangedEventArgs

{

public int Index { get; set; }

public NotifyCollectionChangeEventArgs(int index, string propertyName)

: base(propertyName)

{

Index = index;

}

}

public class NotifiableCollection: ObservableCollection where T: class, INotifyPropertyChanged

{

public event EventHandler<NotifyCollectionChangeEventArgs> ItemChanged;

protected override void ClearItems()

{

foreach (var item in this.Items)

{

item.PropertyChanged -= ItemPropertyChanged;

}

base.ClearItems();

}

protected override void SetItem(int index, T item)

{

this.Items[index].PropertyChanged -= ItemPropertyChanged;

base.SetItem(index, item);

this.Items[index].PropertyChanged += ItemPropertyChanged;

}

protected override void RemoveItem(int index)

{

this.Items[index].PropertyChanged -= ItemPropertyChanged;

base.RemoveItem(index);

}

protected override void InsertItem(int index, T item)

{

base.InsertItem(index, item);

item.PropertyChanged += ItemPropertyChanged;

}

private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)

{

T changedItem = sender as T;

OnItemChanged(this.IndexOf(changedItem), e.PropertyName);

}

private void OnItemChanged(int index, string propertyName)

{

if (ItemChanged != null)

{

this.ItemChanged(this, new NotifyCollectionChangeEventArgs(index, propertyName));

}

}

}

The Importance of building a correct social media strategy for IT companies

Nowadays, many IT companies have realized the importance of using social media to promote their products and services. However, most of these companies do not have a structured plan for making this strategy work properly.

There are IT companies who believe that developing a social media strategy consists only of creating a Twitter and a Facebook account, hoping that costumers will instantly arrive and start following.

However like any other marketing plan, there is a process that must be followed in order to develop a proper social media strategy. First of all it is important to identify the market that the company wishes to send the final message, in other words, you need to identify which is your target market.

Some questions you can do to identify your target market are:


1. Who are they?
2. What solutions are looking for?
3. Which websites they visit frequently?
4. Which products they have purchased?
5. What language do they use?

Once you have identified your target market it is necessary that all the information you offer in the social networks be focused on those people and their needs. It is important not to jump directly to start trying to sell your services using social media, you need first to try to inform and help people that are possibly going to buy your products.

A great way to do this is by creating a company blog and sharing your articles or news related to the technology industry. By doing this you build trust and automatically positioned as a credible company in the industry.

As you could see, is of great importance to create a proper social media strategy to promote and supply the products of technology companies today. Remember that the most important aspect is to provide solutions and great content that will help your target market; sales and leads will come on their own.

negocios por internet

WCF service in IIS with multiple host-headers

By Alejandro Villarreal

Hosting WCF services in IIS is usually a very straightforward process with no weird configuration settings or obscure errors. You create a site in IIS, publish your service in the site’s folder, and you’re ready to go.

However, things start to get a bit complicated in more advanced scenarios like the one I encountered some days ago: if your site in IIS answers to multiple host-headers, then when you try to access the service through a web browser, instead of seeing the usual page with the service description you will receive a screen indicating a Runtime Error, and you should be able to find an Error entry in Window’s Event Viewer (under “Windows Logs”/Application) whose Source is System.ServiceModel 3.0.0.0 (or whatever version you happen to be using), that says something like this:

Exception: System.ServiceModel.ServiceActivationException: The service '/YourService.svc' cannot be activated due to an exception during compilation. The exception message is: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.

This message was certainly more obscure than the errors I was used to when dealing with IIS-hosted WCF Services, and it didn’t make much sense until I found the solution and understood what the error was talking about. In summary, when the WCF Service is hosted in an IIS site, IIS passes all the host-headers to which the site answers as base addresses for the service when it instantiates it, and it in turn complains because it only expects 1 base address of a particular type. Several host-headers imply several base addresses for http, and thus the error.

A code-based solution is to create a custom class than inherits from ServiceHostFactory and filters out the unwanted addresses, and then tell IIS to use that class to instantiate your service. The class is nothing special:

1

Instead of returning the first address that was passed in (baseAddresses[0]) –which could impact your service if it depends heavily on this address, and the order of the host-headers changes in IIS– you can implement your own custom logic to determine which address the service is going to use.

Then you must tell IIS to actually use this class, which is achieved by modifying the .svc file that was generated when publishing your service, so it looks like this (notice the second line):

<%@ ServiceHost Service="Your.Namespace.YourService"

Factory="Your.Namespace.CustomHostFactory" %>

“CustomHostFactory” is just the name of the class you created, so it will depend on the actual name you give to it.

And that’s it! If you try to access your service through the web browser again, you should get the .NET generated help page. According to the site linked earlier, there is also a way to make this happen purely by editing the configuration file, but I haven’t tested it. However, feel free to go ahead and try it!

Have a nice day!

Quirks of Distributed Transactions (MSDTC) and SQL Server

By Alejandro Villarreal

Distributed transactions can be of great help when dealing with complex operations that must be atomic across servers, but then again for their very nature –distributed– they can be hard to debug when something fails. A good example of this is an error I encountered recently. Here’s a bit of background:

We have a Web Application hosted in Server01 sending messages to a WCF Service through an MSMQ endpoint (we’re using transactional queues to leverage their reliability), and this Service saves the content of the messages it receives in a SQL Server database hosted in a remote server (Server02). The queue in Server01 plus the database in Server02 make this a distributed transaction, and that’s why we need MSDTC in the first place.

The whole setup worked perfectly… until suddenly it just didn’t anymore. The WCF Service started throwing the following error:

System.Data.SqlClient.SqlException: Warning: Fatal error 8510 occurred at May 21 2010 9:50AM. Note the error and time, and contact your system administrator.

A severe error occurred on the current command. The results, if any, should be discarded.

Fatal error with almost no description? Out of nowhere? We didn’t deploy a new version (nor redeployed the same one, for that matter); we didn’t change anything in the configuration files; we didn’t install OS updates. Then why could it possibly start to fail out of nothing? Both servers had gigs of free disk space, and plenty of RAM, so that couldn’t be the problem. I checked the SQL Server logs, and found this:

1

The full message is “Enlist operation failed: 0x8004d01c(XACT_E_CONNECTION_DOWN). SQL Server could not register with Microsoft Distributed Transaction Coordinator MS DTC) as a resource manager for this transaction. The transaction may have been stopped by the client or the resource manager.”

Accompanied by a second message: “Error: 8510, Severity: 20, State: 3.”

Ok, that gave us some clue about what was happening, but didn’t shed any insight on why. After quite some time looking for the cause of this issue, I finally reached this article, which doesn’t clearly state why did their solution solve the problem but references this other article, which again, doesn’t quite pose a solution to the problem, but is very close. The key information I obtained from that article is

“As MSTC [sic] is the core Transaction Service, its restarting will cause other Transaction depended [sic] services stop working normally, such as SQL server”.

The core idea is pretty clear. And combining this with a comment from the first article I mentioned (“Restarting services on the sql server that could not initiate distributed transactions resolved the problem”), I imagined that the MSDTC and the SQL Server windows services must be started in that order for everything to work.

Back to our setup, I recalled that I did restart the MSDTC service at some point, so I obviously tried restarting SQL Server, and…

Another error! It seemed the user we had been using all along to connect to the database didn’t have permissions anymore. Oh, but wait! There isn’t only 1 database server, there are 2, configured for mirroring, and a third one that acts as witness to allow for automatic failover. Restarting SQL Server in the first database server triggered the failover, so when it came back up, it wasn’t the primary anymore, but the mirror. And since you cannot connect to a mirror, the error makes sense. Whew! I started a manual failover back to this server, and surely enough, distributed transactions started working again!

So, even though it is not explicitly documented anywhere (that I could find), I think it is safe to say the following, which generalizes the title of this post a bit: always make sure that any server hosting resources that make use of MSDTC, sets up its services and resources in the correct order, and be careful with restarting the MSDTC service.

I hope this saves somebody the time I spent debugging this issue.

Getting Started with PowerShell Remoting

By Irvin Gomez

As a software engineer, more often than not I find myself writing code in C#, and things tend to be pretty neat inside Visual Studio. However, when we need to deploy our new application to the servers where the application will be hosted, the number of Remote Desktop sessions we require can be overwhelming.

Here is where PowerShell Remoting comes to the rescue. Basically it allows a client machine to connect to another machine and then you can run PowerShell commands and scripts typing from the client. Think of Telnet on Unix machines.

Remoting is a feature introduced on PowerShell v2.0 and basically will let you run any PowerShell command or script (like deployment and configuration scripts) for all your farm servers from a single computer. And the sweet thing is that you will not need to start Remote Desktop connections to each server separately.

So to start working with PowerShell Remoting you need to follow these steps:

1. Log on the Host computer, the one you want to connect to, and start an elevated (run as Administrator) PowerShell session.

2. Configure the WinRM Service (Windows Remote Management) using the cmdlet:

Enable-PSRemoting

3. Configure the trusted hosts, this is, specify which other machines are allowed to connect to this one. For example if you want to allow remote connections from two machines named SERVER-2 and MYDESKTOP you will need to run the following:

set-item wsman:localhost\client\trustedhosts -value “SERVER-2,MYDESKTOP”

4. Once you have done this, you are ready to go. You can log into your computer and start a remote session to your recently configured server, suppose we are trying to start a session into SERVER-1 machine:

Enter-PSSession SERVER-1

5. Now you are ready to type PowerShell commands and they will run on SERVER-1 machine. Once you are finished, you exit the session:

Exit-PSSession

6. So far so good, but what when you have a full script that you want to run on the other machine? For instance, if you want to run myScript.ps1 you will need to use New-PSSession and Invoke-Command

$remSes = New-PSSession -ComputerName SERVER-1

$job = Invoke-Command -Session $remSes -FilePath myScript.ps1 –AsJob

This will run myScript.ps1 on SERVER-1 machine as a job from your very desktop. At first, this may seem like a lot of things to do just to be able to run scripts remotely on a single server.

But when you have several servers to manage and you have scripts that do exactly the same on all servers then PSRemoting will be handy, more if you use New-PSSession and Invoke-Command as part of a larger script that handles all your servers. Automating this type of tasks, in the long term will make your life easier and they will save you much more than a few hours, which you can use to create more PowerShell scripts to automate something else.

ASP.NET 4.0, MVC and request validation

By Alejandro Villarreal

If you’ve ever dealt with the front-end part of application development in ASP.NET, you might have encountered the following error at some point:

A potentially dangerous Request.QueryString value was detected from the client

This happens when the user submits a value (either in a form or in the query string) that the ASP.NET Framework considers dangerous, in the sense that it might be an HTML/script injection attack.

Sometimes it is necessary to turn that feature off (see here and here on how to do it). It might be the case that you expect the user to provide valid XML/HTML, and thus you don’t want the Framework to abort the request with an Exception. As explained in the links I mentioned before, this can be done by disabling this validation completely in the Web.Config file or on a per-page basis (when working with WebForms), or disabling it for a controller or specific controller actions (when working with MVC).

Since I’m currently working on an application that uses the MVC Framework, this post focuses on the problem I had while trying to disable request validation for specific controller actions.

According to this post by Stephen Walther (and several others), the only thing you need to do is to add the ValidateInput attribute to your ActionMethod, like this:

[ValidateInput(false)]
public ActionResult MyActionMethod(string myParameter)
{
// Method implementation goes here...
}

Seems simple enough… but it just wouldn’t work for me! I kept receiving the “potentially dangerous” error when making a request to the URL that triggered “MyActionMethod”, when “myParameter” included an HTML tag. The method wasn’t even being activated.

After a bit of research I stumbled upon this post, which had the solution. The key was this:

So the MVC team gave us the [ValidateInput(false)] attribute to disable this annoying feature. But just setting it on an action will also fail, you still have to set one more setting at the web.config for this to work (if you are working with asp.net 4)

Oh, I am working with ASP.NET 4! So I had to add this to my Web.Config file:


...

...

As explained in the article (and originally in this whitepaper that explains the breaking changes in ASP.NET 4), previous versions of the Framework only performed request validation for ASP.NET pages (.aspx files and their class files), while version 4 performs it for all requests, before their BeginRequest phase. In my particular scenario, this means that the attributes in the controller don’t even have a chance to act, since the Framework has already decided that the request will be aborted. And that’s why reverting the validation behavior to that in version 2.0 of the Framework (through that additional line in the config file) makes everything work as expected again.

This made me think on how is it that we can prevent request validation on MVC-based applications developed under Framework 4.0 without resorting to that behavior, but couldn’t find any documentation on it. Hopefully Microsoft did think about this and we’ll soon start seeing solutions to that problem…

How to Handle the WCF Error on Silverlight

By David Espino.

When sending a call to a WCF service from a Silverlight application and the service returns an error, the Silverlight client backs up only a very generic error:

The remote server returns an error: NotFound

This message does not help to know the exact error neither for the user nor the developer. Even more, it is necessary for more security to make a division of the error information: one message for the user and one detailed message for the system administrator or developer.

The first part of the error dedicated to the application administrator consists on writing the exception that the code generates on a detailed way. There are a lot of tools that allows tomake this log of errors (Log for Net, Microsoft Enterprise Library and some other). For this example, we need to provide an easy log in to the server application log where our service would be found. This method captures two parameters: One “Entity” that indicates the business entity where the error occurred (for example the Countru, State, Employee, etc) and an action, which indicates the operation that could not be performed (Save, Select, Delete, etc). With these two parameters we can deliver a friendly message to be sent to the user.

public class ExceptionLogger

{

public static string LogAndReturnError(Exception ex, string entidad, string accion)

{

StringBuilder cadenaError = new StringBuilder();

cadenaError.Append("Ocurrió un error en el servicio de la aplicación: \n\n");

cadenaError.Append("Error: ");

cadenaError.Append(ex.Message);

cadenaError.Append("\n\nStackTrace: \n\n");

cadenaError.Append(ex.StackTrace);

EventLog.WriteEntry("NombreAplicación", cadenaError.ToString(), EventLogEntryType.Error);

cadenaError = new StringBuilder();

cadenaError.Append(string.Format("Ocurrió un error al intentar {0} {1}. Contacte al administrador del sistema.", accion, entidad));

return cadenaError.ToString();

}

}

The next step would be to generate an entity as a DataContract for the object that stores errors that occur during the service.

[DataContract]

public class ServiceError

{

[DataMember]

public string Type { get; set; }

[DataMember]

public string Message { get; set; }

}

The next thing to do is to make our service operations to return us an error object into the interface layer. We will use an output parameter in our methods of service and use the kind of login error.

public void DoWork(string Parameter1, out ServiceError errorService)

{

errorService = null;

try

{

//Operaciones a realizar

}

catch (Exception ex)

{

errorService = new ServiceError

{

Message = ExceptionLogger.LogAndReturnError(ex, "Acción", "Entidad"),

Type = "Aplicación"

};

}

Finally we need a Silverlight application to consume our service. For this, we need to add a Silverlight application and then a reference of our service. Once we call our service we are going to get the following:

MyServiceClient client = new MyServiceClient ();

client.DoWorkCompleted += new EventHandler<DoWorkCompletedEventArgs>(client_DoWorkCompleted);

client.DoWorkAsync("Hola Mundo");

void client_DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)

{

//Error propio de WCF

if (e.Error == null)

{

//Nuestro Parámetro de Error!!!

if (e.errorService == null)

{

if (e.Result != null)

{

//Manipular resultado

}

}

}

}

This is a very easy way to implement error management on Silverlight.