Tuesday, May 22, 2012

Android development - setup DEV environment

 Note this is work in progress and I am just writing down things to maintain the list of items I had to setup for starting up development on Android.

What you need
  • Eclipse (classic recommended)
  • Android SDK
  • Andriod development tools plugin for eclipse (ADT). In some cases, a new revision of ADT will have a dependency on a specific revision of the Android SDK Tools. If such dependencies exist, you will need to update the SDK Tools package of the SDK after installing the new revision of ADT. To update the SDK Tools package, use the Android SDK Manager (explained below)

Step 1. Preparing Your Development Computer
  • First download Eclipse  - classic is recommended)
  • http://www.eclipse.org/downloads/
  • Unzip the downloaded zip folder into a folder where you want to run eclipse from. There is no installation for eclipse

Step 2. Downloading the SDK Starter Package
  • Download the Android SDK from http://developer.android.com/sdk/index.html (installer_r18 ....exe)
  • Install the downloaded file
  • Run Android SDK manager (SDK manager.exe from where you installed SDK)
  • Launching the Android SDK Manager - The Android SDK Manager is the tool that you use to install and upgrade SDK packages in your development environment. You can launch the Android SDK Manager in one of the following ways.
  • If you are developing in Eclipse and have already installed the ADT Plugin, follow these steps to access the Android SDK Manager tool:
    • Open Eclipse
    • Select Window > Android SDK Manager.
  • Launching from the SDK Manager script (Windows only)
For Windows only, the SDK includes a script that invokes the Android SDK Manager. To launch the tool using the script, double-click SDK Manager.exe at the root of the the SDK directory
Setup proxy in Tools -> Options (popup to enter user name and password will come later). Close the ADK manager and open again for it to refresh the tools required

The list will be shown what needs to be downloaded. You could choose extras if you need them. The latest version of Android will be selected by default
Click on "Install <number> packages" button

Step 3: Configuring Eclipse for Plugin
  • Open Eclipse
  • If proxy, then select menu Window -> preference
  • Select General -> Network connections
  • Select active provider = Manual
  • Edit http and https options by selecting one at a time and clicking on edit
  • Enter proxy settings and save
  • Select menu Help -> Install new software
  • Click on Add and enter https://dl-ssl.google.com/android/eclipse/ in URL

Enable windows authentication (IIS) on a Windows 2008 server

Recently, I had to setup an old VS 2005 application on a windows 2008 server. I did everything right and setup the virtual directory for the web site. But when I tried to run the web site in VS, the site would not open up. I found that this was because the virtual directory was not set to accept windows authentication.

In IIS 6, it was pretty straight forward - go to security tab in IIS and edit and enable. But here I was not able to see that option for the virtual directory. All I could see were the options anonymous access, forms authentication and asp.net impersonation.

Long story short, you have to enable that as a feature on a 2008 server.

To do that
  • open control panel and click on "add or remove windows feature"
  • Expand the node - roles->Web server (IIS)
  • right click on web server node and select "Add role services"
  • in the new window that opens up, on the right side, under "role services", select checkbox "security->windows authentication
  • Under "management tools", option, select checkbox "IIS 6 management compatibility"
  • Click on Next and then Install
  • restart server
  • go back to IIS and the virtual directory and check the "IIS authentications" available and you should see "windows authentication" as the new option

Friday, February 3, 2012

Error: Unable to update the EntitySet ' because it has a DefiningQuery and no element exists in the element to support the current operation.

If you get the error while you try to save changes to an entity "Unable to update the EntitySet '<Entity name> because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.", just check the table that the entity is mapped to.

Confirm that the table has a primary key defined.

Tuesday, November 15, 2011

Error: Delegate System.Func <> does not take 1 arguments

If you get the error
Delegate 'System.Func<entityName,int,bool>' does not take 1 arguments
or
Cannot convert lambda expression to type 'string' because it is not a delegate type

then check the linq query and confirm that the "where" condition has == instead of = ..
var allProducts = from p in context.Products where p.productID == 1 select p;

I wasted a lot of time on this and would like to help anyone else who might have similar issues

Friday, August 12, 2011

Add a table that was deleted in an Entity diagram

If you have come here, I understand your pain. You deleted a table from a entity diagram for some reason and you have trying in vain to add it back using the "update data model from database" option.

Unfortunately there is no easy way to add it back. For some reason, the people who designed it thought that if a user deleted a entity, why would he want to add it back again? But they forgot there are various reasons why someone would want to do it. For eg, I created a model from a database on server A. The database had a table nemed "Attendees". All the other tables started with a lower case. Now moved my database server to a new server and so I thought its a good time to rename this table for consistency. So I renamed and configured my entity model to refresh from the new server expecting that everything would be alright. But lo and behold, now I had 2 entities in the diagram called "Attendees" and "attendees1". Ok, I understand .. when the wizard could not find a table called "Attendees" instead of deleting the table, it thought it might be a entity I created manually and so left it as it is. When it now a new table with the same name, it just created another entity with "1" attached to the end.
I can solve this by just deleting both the enitities and refreshing the table again. Surprisingly, it was not so easy. When I deleted and refreshed, the "attendee" table would no longer appear. What I found is that it just deletes from the designer, but keeps a reference to the table.
Ok, again I understand the reason why the designer leaves the reference is because how else will the designer figure out other entities that I have actually deleted from the diagram, but still have same tables in the database? But I think they could have built that function in the wizard so the user can decide on what tables he would not like in the diagram and what tables he would like to add again.

Anyway, back to what this post is all about. How will I add this table back again? There are 2 options and both options involve editing the edmx file

     Option 1) Delete all reference to "attendees" entity in the diagram
     Option 2) Add the "attendees" reference to the places where it might be missing so the designer adds it back.

Option 1 would be tricky if you have lots of references for that table and the table design is complex.
In my case, I opted for option 2 because I thought adding a reference back to the designer would be easy for me.
Option 1 is pretty straight forward and so I will not discuss on how to go about doing it
For option 2, you will have to do the following....
There are 3 main sections in the edmx file
  1. Storage model - a refernce to all the tables
  2. Conceptual model - entities that are part of the entity model
  3. Mapping - entity properties to database column mapping
The missing table "attendees" was missing in the sections conceptual model and mappings.

Step 1: Add missing enity in conceptual model
Copy the attendees tag from Storage model
<EntitySet Name="attendees" EntityType="MyModel.Store.attendees" store:Type="Tables" Schema="dbo" />

into the tag within  "EntityContainer". Remember to make the changes like removing attributes not needed and also removing the ".store" from the namespace. For my case the tag I added would look like this
<edmx:ConceptualModels>
  <Schema Namespace="MyModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
   <EntityContainer Name="MyEntities">
      <EntitySet Name="attendees" EntityType="MyModel.attendees" />

Step 2: Add missing entity tag to conceptual model
Copy the attendees entity tag and its contents from storage model
<EntityType Name="attendees">
<Key>
  <PropertyRef Name="attendees_id" />
</Key>
    <Property Name="attendees_id" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="Column1" Type="bigint" Nullable="false" />
    <Property Name="Column2" Type="varchar" Nullable="false" />
    <Property Name="Column3" Type="bit" Nullable="false" />
    <Property Name="Column4" Type="dateime" Nullable="false" />
</EntityType>

as a new entity type under the ConceptualModel\Schema tag .. It will look something like this
<edmx:ConceptualModels>
<Schema Namespace="MyModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
   <EntityType Name="attendees">
    <Key>
      <PropertyRef Name="attendees_id" />
    </Key>
     <Property Name="attendees_id" Type="Int64" Nullable="false" />
     <Property Name="Column1" Type="Int64" Nullable="false" />
     <Property Name="Column2" Type="String" Nullable="false" />
     <Property Name="Column3" Type="Binary" Nullable="false" />
     <Property Name="Column4" Type="DateTime" Nullable="false" />
  </EntityType/>
Note, I made changes to the types of the columns .. for eg, all bigint are Int64, varchar as string, bit as binary. I also removed any other attributes that are not needed like StoreGeneratedPattern="Identity" from the primary key "attendees_id"

Step 3: Add the mapping
Add the mapping as below
<edmx:Mappings>
  <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
      <EntityContainerMapping StorageEntityContainer="MyModelStoreContainer" CdmEntityContainer="MyEntities">
         <EntitySetMapping Name="attendees">
            <EntityTypeMapping TypeName="IsTypeOf(MyModel.attendees)">
               <MappingFragment StoreEntitySet="attendees">
                  <ScalarProperty Name="attendees_id" ColumnName="attendees_id" />
                  <ScalarProperty Name="Column1" ColumnName="Databasecolumn1" />
                  <ScalarProperty Name="Column2" ColumnName="Databasecolumn2" />
                  <ScalarProperty Name="Column3" ColumnName="Databasecolumn3" />
                  <ScalarProperty Name="Column4" ColumnName="Databasecolumn4" />
               </MappingFragment>
         </EntityTypeMapping>
       </EntitySetMapping>
For this change, note that you need to add a mapping for each column in your database

Step 4: Get all other relations for the table
Its quite possible that you had other relations for this with other database tables and that is the reason you opted for option1 instead of option2. For this you just need to open the designer again, right click and select the "Update model from database" option and Viola! all the other relations and mappings are automatically added ..
Hope this helps ..

Wednesday, April 6, 2011

Create PDF file from a template using Aspose.net

There are many applications where reports or custom documents have to be created in PDF formats. There are various tools available in the market to create PDF document on the fly. If you selected the tool provided by Aspose (http://www.aspose.com/community/files/default.aspx), read on ..

My requirement was to create a PDF document on the fly within a ASP.net application. The document to be created was a certificate and it had a fixed format. Only some of the text (like name, date) within the certificate had to fetched from the database and the document had to be created on user request (on demand, on the fly).

Instead of creating the whole document from scratch each time the document is to be created, I thought the best approach would be to create a PDF template and add form fields for all the fields that would change. Then use Aspose control to open the template, fill the fields. I thought this would be an efficient way to create these documents and response time would be reduced drastically. It would also be easier to code because most of the content of the document is in place and I do not have to code to place the content with the document.

As this was a ASP.net application and the document was to be created only the user requested for it (using a link within a web page), I did not want to save the document on the web server because I did not want to go through the hassle of having to delete these documents later or having piles of documents using my web server space. So the solution was to use streams and manage everything in memory.

The document also had to be secure and the user must not be able to edit the fields or make any changes to the document. The only permission that was to be available to the users was to open the document and print it. So here is the code I finally came up with



public static MemoryStream CreateCertificate(string pName, string pDate)
{
//open template
string lpdfTemplate = "

Hiding a node in a TreeView control

I had a web page with a treeView control and I wanted to hide a particular node for a specific condition. I thought this would be pretty easy and I might just have to set the "Visible" property of the node. But I was surprised to see that the node does not have this property maybe because the node is not a control.

If the treeview is built from a data source, you can use the TreeNodeDataBound event to acheive this. But its not as simple as doing
e.node.visible because as I said, visible is not a property

Even treeviewControl.Nodes.Remove(e.node) will not work if you are trying to remove a node that is a leaf node (node that does not have children).

So to remove a node, just try this code
e.Node.Parent.ChildNodes.Remove(e.Node);

Unable to resolve dimension value "match_parent" in attribute "layout_width"

Unable to resolve dimension value "match_parent" in attribute "layout_width"


If you get the above error while developing any Android application, just replace change "match_parent" with "fill_parent"

I spend some time figuring this out .. so thought maybe this would help someone out there who has similar issues

Tuesday, October 19, 2010

Email attachments - using memory stream

In my previous post I mentioned about a task where I had to send HTML mails. In each of the emails, I also had to attach a file. The files were dynamically created and I wanted to avoid having to physically create the files on the servers, attach the files to the mail and then having to delete it.

I found that it is possible to attach files as memory streams using
Message.Attachments.Add(memoryStream, ...

But as I wrote the code to do this, I found that the size of the file been attached was always 0 kb. So back to the trouble shooting ..

I was creating the file in a different assembly and the file was been received as a memory stream. So the code looked something like this

Class A
- Get details to create the file from database
- Call a method in Class B to create the file and store the returned memory stream in local variale
- Call a method in class C to send mails and pass the local memory stream to this method

Class B
- create a new file and return the file as memory stream object

Class C
- Create a mailmessage.
- Attach the file received as memorystream parameter to the mail message
- send the mail.

Everything seemed right. I even debugged the code to ensure that the memorystream object been created in class B was not empty. I debugged to see if the memory stream received by the method in class C had all the proper content and was not empty. Again everything looked fine. So where was the problem. Various people on the internet seemed to suggest flusing the memomorystream, moving the position to 0, etc but nothing worked

I finally realized that when files are attached as a memory stream to emails, the stream needs to be open. So first I tried by not closing the stream in Class B. But that did not work. So in class C before attaching the file to the mail message, I created a new stream using the same stream I got as a parameter, like this

MemoryStream memoryStream = new MemoryStream(pMyStream.ToArray());
MyMailMessage.Attachments.Add(new Attachment(memoryStream, "Name.pdf", MediaTypeNames.Application.Pdf));


and that worked !!

Line Breaks does not appear in HTML emails

Its been a looong time since my last post. That doesn't mean that I have been idle and not working :-). Just that I have been busy (which is good) and also postponing my task of updating this blog (which is bad).

There have been various issues that I have faced in the last year or so and solutions I found out the hard way which I want to write about and hopefully, I get it done sooner than later.

Anyway to start of, I will start of with a very trivial issue that some of you might have never noticed, but something which stumped me for couple of hours.

I had a task to send HTML mails using Lotus notes and I had a tough time getting the line breaks to appear. I checked all the usual things to ensure that the mails are marked as HTML and still the line breaks would not appear.

I thought it is a lotus notes client issue until I finally found what I was doing wrong.
HTML tag for line break is <br> and not <br/>.


In HTML the <br> tag has no end tag.
But in XHTML the <br> tag must be properly closed like <br />.