Dailycode.info

Short solution for short problems

GAC vs BIN (What dll version will be loaded?)

Global assembly cache versus BIN folder.
If you are frequently updating the Assembly, then you always better to deploy it in BIN.  Since, Assembly will be reloaded automatically just after the updating.    But when you update the Assembly in GAC, you have to restart the IIS (IISRESET) to grab the new version. The reason is GAC keeps the assembly in Cache. You can use different versions of the same DLL across applications, but not the same dll with different versions in the same BIN.
When you deploy your Assembly on GAC then you can access the Assembly from any web application. But when you deploy Assembly in web application’s BIN folder, then it can only access from the given web application. Anyway, if you have all-purpose web part, you better to deploy it in GAC and avoid the multiple Assembly deployments in BIN.
If you have multiple versions of same Assembly used in 1 application, then you have to deploy it in GAC. Because the GAC manages the multiple version of given Assembly, but BIN doesn’t.
I found this information here.
Next question is what order will the assemblies be used. I’ve read something like .Net will look for the highest version in the BIN and GAC and use that one, or others say the BIN has priority over the GAC.
So I did the test.
First I deployed a simple website that has a textbox and a button. When you click the button you will get the assembly version of a referenced class library. I placed a version 1.2.0.0 of the dll in theGAC.
  
 I tested 4 scenarios:
1: The class library referenced is of version 1.0.0.0 and the dll is located in the bin folder
2: The class library referenced is of version 1.1.0.0 and the dll is located in the bin folder
3: The class library referenced is of version 1.1.0.0 and the dll is NOT located in the bin folder
4: The class library referenced is of version 1.2.0.0 and the dll is NOT located in the bin folder
So the result is that the BIN folder has priority over the GAC. In example 1 we will retrieve the 1.0.0.0 version of the dll.  
 
In the second example we will see the 1.1.0.0 version of the dll that is in the BIN folder.
 
Then we will get an error, since the project is build against the 1.1.0.0 and the GAC version is 1.2.0.0.
 
And the fourth example shows the GAC version. 
There are methods to force your web application to use certain versions of dll. Adding the required version to your config file can do the trick.

Click once deployment configuration. (Tutorial)

Setting up your VS project (WPF, Win and Console) for click once deployment.
 
Before you deploy the Windows application, you set properties for Security and Publish from the application's Properties window.
 The Security property sets the permissions for your application. By default, the ClickOnce deployment has a limited subset of permissions. You can set the permissions to deploy only to client machines on the Intranet or Internet, or to allow full permissions.
 The Publish property sets the deployment location to a Web Site URL, an FTP server, or a file path. Also, this property sets necessary prerequisites and updates to the deployed application.

 To set the ClickOnce Deployment Options.

1.       In the Solution Explorer, right-click the bold project name, and click Properties.
2.       Click on the Security tab.
3.       Select Enable ClickOnce Security Settings.
By default, the ClickOnce security permission is set to: This is a full trust application.
   
4.       Click on the Publish tab, and then click Prerequisites.
5.       Here you can set any prerequisites for theprogram.
Note   Encourage your clients to install the .NET Framework or any other runtime before you deploy the Windows application, because installation time increases significantly if you use ClickOnce to install the prerequisites.
6.       Click OK.
7.       On the Publish tab, click Updates. From the Application Updates dialog box, ensure the following options are selected:
a.       Select: The application should check for updates.
b.      In the Choose when the application should check for updates list, select: Before the application starts.
  
8.       Click OK to close the dialog box.
9.       From the File menu, click Save All.
 
 
 

To publish a Windows application.

1.       In the Solution Explorer, right-click the bold project name, and click Publish.
2.       Choose where to publish the application.
  
3.       Choose the location where the users will install the application from (Use the same location but provide the UCN path name (Do not use mapped drive names-see example below)).
  
4.       Choose the first option that the application is available offline.  
 
5.       Click finish
  
 

Installing the application on a client.

1.       Go to the installation directory and click on the setup.exe.
  
2.       Click run
  
3.       Click on install.
  
4.       The application is automatically opened.
  
 

Deploying a new version

1.       Raise the assembly version.
2.       Republish the files (Same flow as described in previous chapter).
3.       Open the program on the client
4.       Choose whether to update to the new version or keep working with the current version.
  
5.       If you click skip, the next time you open the program, it will not ask to be updated again until a newer version is deployed or a republish is done of the current version. You can configure a minimum version, if the client version is below the minimum version, the update will occur without asking the client to Skip or press OK.
  
6.       If you click OK then the new version is installed and opened.
  
 

Uninstalling the application

1.       Remove the application using the windows program management
  
  
2.       You can also restore the application to a previous version. 

WCF: Which protocol to use? HTTP or TCP?

My overall conclusion of reading information and using both protocols is that you have to consider these to topics before choosing the protocol to use!

  • Are the services used internally or will they be used by external applications?
  • Is it an internet application?

When you answer yes to one of the previous questions, using the HTPP protocol will be the best choice. But when you develop a client server application for use within the company, use TCP.  TCP is in my opinion the best protocol to use when client and server use WCF and the application is running on a local network. The services can also be accessed by other applications running on this network and using WCF. So I believe that in many cases people just tend to HTTP without really looking why. Next I list a part from a Microsoft article, which explains this for you clear and brief:

When to Use HTTP Transport 

HTTP is a request/response protocol between clients and servers. The most common application consists of Web-browser clients that communicate with a Web server. The client sends a request to a server, which listens for client request messages. When the server receives a request, it returns a response, which contains the status of the request. If successful, optional data, such as a Web page, an error message, or other information is returned. For more information about the HTTP protocol, see HTTP - Hypertext Transfer Protocol.

The HTTP protocol is not connection-based—once the response is sent, no state is maintained. To handle multiple-page transactions, the application must persist any necessary state.

In WCF, the HTTP transport binding is optimized for interoperability with legacy non-WCF systems. If all communicating parties are using WCF, the TCP-based or named pipes-based bindings are faster. For more information, see NetTcpBinding and NetNamedPipeBinding.

When to Use the TCP Transport 

TCP is a connection-based, stream-oriented delivery service with end-to-end error detection and correction. Connection-based means that a communication session between hosts is established before exchanging data. A host is any device on a TCP/IP network identified by a logical IP address.

TCP provides reliable data delivery and ease of use. Specifically, TCP notifies the sender of packet delivery, guarantees that packets are delivered in the same order in which they are sent, retransmits lost packets, and ensures that data packets are not duplicated. Note that this reliable delivery applies between two TCP/IP nodes, and is not the same thing as WS-ReliableMessaging, which applies between endpoints, no matter how many intermediate nodes they may include.

The WCF TCP transport is optimized for the scenario where both ends of the communication are using WCF. This binding is the fastest WCF binding for scenarios that involve communicating between different machines. The message exchanges use the BinaryMessageEncodingBindingElement for optimized message transfer. TCP provides duplex communication and so can be used to implement duplex contracts, even if the client is behind network address translation (NAT).

 

Fast way to test your service is to open the visual studio command prompt and type in WCFTESTCLIENT This will open the WCFTestclient.exe and there you can test your endpoints.


Combining 2 or more columns in a listview using CellTemplate in stead of DisplayMemberBinding

Combining 2 or more columns in a listview is really simple actually. Using the DisplayMemberBinding

Property won’t get you there. This only allows 1 column to be bound. But using the CellTemplate property, you have unlimited possibilities. Just define the data template in a resource for example and bind it to the CellTemplate property. Here’s a simple example:

 

<GridViewColumn

Header="Country"

DisplayMemberBinding="{Binding Path=Country.CountryName}"

/> 

<GridViewColumn

Header="Farmer"

CellTemplate="{StaticResource FarmerTemplate}"

/>

 

 

The data template is defined in a resource file and looks like this:

 

<DataTemplate x:Key="FarmerTemplate">

    <DockPanel>

        <TextBlock HorizontalAlignment="Left">

            <TextBlock.Text>

            <Binding Path="Farmer.LastName"/>

            </TextBlock.Text>

        </TextBlock>

        <TextBlock Text=" "></TextBlock>

        <TextBlock HorizontalAlignment="Left">

            <TextBlock.Text>

            <Binding Path="Farmer.FirstName"/>

            </TextBlock.Text>

        </TextBlock>

    </DockPanel>

</DataTemplate>

 

The result:

 


Adding record with linked record in entity framework using self tracking entities.

It could happen that you get an unexpected primary key violation using the entity framework. When you add a record you need to setup your identity insert correct or just pass the ID from code. Or in my case use GUID’s generated in the code. That works fine once you get it running. But today I got a nasty error: (BTW I’m using state tracking entities, WCF, MVVM and WPF)

Violation of PRIMARY KEY constraint 'PK_TableName'. Cannot insert duplicate key in object 'dbo.TableName'.

The statement has been terminated.

What I was doing was adding a farmer record and this farmer had a country record linked. When I added the farmer with a selected country, the entity framework tried to add the country also to the country table. Off course he generates a primary key constraint. My code looked like this:

FarmerRecord.Country = SelectedCountry;

FarmerRecord = srv.NewFarmer(FarmerRecord);

 

The service function looked like this:

 

public Farmer NewFarmer(Farmer newFarmer)

{

    newFarmer.Guid = Guid.NewGuid();

    ents.Farmer.AddObject(newFarmer);

    ents.SaveChanges();

    return newFarmer;

}

 

So I created a new farmer record and set the country to the country selected in the GUI. The state of the farmer was added and the state of the country was unchanged. Still he tries to add the country to the country table.

If found several workarounds, the first was this: Just fill in the CountryGuid and leave the Country record null. So this changed my code to this:

 

FarmerRecord.CountryGuid = SelectedCountry.Guid;

FarmerRecord = srv.NewFarmer(FarmerRecord);

FarmerRecord.Country = SelectedCountry;

 

Or you also could map the country record to the country record coming from the context. This is done on service level then:

 

public Farmer NewFarmer(Farmer newFarmer)

{

    newFarmer.Guid = Guid.NewGuid();

    Country country = ents.Country.First(d => d.Guid == newFarmer.CountryGuid);

    newFarmer.Country = country;

    ents.Farmer.AddObject(newFarmer);

    ents.SaveChanges();

    return newFarmer;

}

 

So apparently when you map it to the corresponding country record from the context, it doesn’t add the country.