Search This Blog

Wednesday, February 26, 2014

Ajax FileUpload on all Browsers including IE 8, 10

File Upload in ASP.NET MVC via ajax

Problem

While looking for fileupload options via ajax and without posting the whole form, we often come across code in the internet using FormData API, which works perfectly fine on chrome and mozilla but on on IE. so a code snippet using a FormData API would like this below

//View Code
<script type="text/javascript">
    function save() {
        $("#test").submit();
    }
    function submitForm() {
        var formData = new FormData($('#test')[0]);

            $.ajax({
                url: '@Url.Action("Upload","FileUpload")',
                type: 'POST',
                data: formData,
                async: false,
                success: function (data) {
                    alert('posted')
                },
                cache: false,
                contentType: false,
                processData: false
            });

            return false;
    }
</script>
<h2>Index</h2>
<input type="button" value="Submit" onclick="save();" />
    
<form id="test" action="javascript:submitForm();" method="post" enctype = "multipart/form-data">
    <div>
        <label for="fileUpload">File upload</label>
        <input type="file" id="fileUpload" name="fileUpload" />
    </div>
</form>

//Controller Code
public ActionResult Upload()
        {
            HttpPostedFileBase postedFile = Request.Files[0];
            return View();
        }
The above snipped works fine on chrome and mozilla and you will be able to see the postedFile in the controller but it does not work on IE because most versions of IE does not support FormData.

Solution

So the solution I came up with after going some recommendations over internet about HTML controls on different browsers is that its better to use iframes. So Idea is to point the target of the form to an iframe and even bind a load event to the iframe so that you know when the upload is finished and write additional jquery functions. Also you can even hide the iframe and not show the user. But this solution works on IE as well. The code is as below

The code also shows how to post additional data along with the file post.

@{
    ViewBag.Title = "Index";
}
<script src="~/scripts/jquery-1.9.1.min_.js"></script>
<script type="text/javascript">
    function successFunction() {
        alert($('#my_iframe').contents().find('p').html());
    }
    function redirect() {
        //debugger;
        document.getElementById('my_form').target = 'my_iframe'; //'my_iframe' is the name of the iframe
        //document.getElementById('my_form').submit();
        var callback = function () {
            if (successFunction)
                successFunction();
            $('#my_iframe').unbind('load', callback);
        };

        $('#my_iframe').bind('load', callback);
        $('#hfParam').val('id:1');

        $('#my_form').submit();
        //$("#my_form").trigger("submit");
     
    }
</script>
<h2>Index</h2>
<input type="button" name="action" value="Upload" onclick="redirect();"/>
<form id="my_form" name="my_form" action="/FileUpload/UploadFile" method="POST" enctype="multipart/form-data" >
    <div id="main">
        <input name="my_hidden" id="hfParam" type="hidden" />
        <input name="my_files" id="my_file" type="file" />
        <iframe id='my_iframe' name='my_iframe' src="">
        </iframe>
        <div id="someDiv"></div>
    </div>

</form>


[HttpPost]

        public ActionResult UploadFile()

        {
            ContentResult result = new ContentResult() { Content = "<p></p>", ContentType = "text/html"};
            HttpPostedFileBase postedFile = Request.Files[0];
            try
            {
                result.Content = "<p>" + postedFile.FileName + "</p>";

            }
            catch (System.Exception ex)
            {
                result.Content = ex.Message;
            }
            return result;
        }

Thursday, February 20, 2014

JQuery Set Visibility ON/OFF for a Button in ASP.NET MVC

How to Make a Button Visible true or False of a button in ASP.NET MVC project

I posted the same solution on stackoverflow site

First Method: As explained above, but I am afraid, it will not work if for example you have a partial view and based on something there you want to show or hide something.
Second Method:Initial Page load, button is visible.
<input id='btnAdd' type='button' value='Add' style='display:block;'/>
Based on some action on page/partial view
<script>
  function disableAdd() {
  $('#btnAdd').hide();
}
</script>
*Please note, jquery will not be able to hide/show if you use visibility in style sheet.

Readonly TextBox using @Html.TextAreaFor

How to Create Conditional Readonly TextBox in ASP.NET MVC5

I posted this solution below on stackoverflow because it worked very well for me, so copying from there


By setting readonly attribute to either true or false is not going to work in most browsers, I have done it as below, when the mode of the page is "reload", I've not included "readonly" attribute.

@if(Model.Mode.Equals("edit")){
@Html.TextAreaFor(model => Model.Content.Data, new { id = "modEditor", @readonly = moduleEditModel.Content.ReadOnly, @style = "width:99%; height:360px;" })
}
@if (Model.Mode.Equals("reload")){
@Html.TextAreaFor(model => Model.Content.Data, new { id = "modEditor", @style = "width:99%; height:360px;" })}

Json Object Postback, IE JSON.stringfy problem resolution.

Making Json Object Post to Server in Asp.NET, Problem in IE.

I am copying my own post from StackOverflow.
There may be situations where it may not be possible to include the Doctype or meta tag or nothing might work as in my case so I had to figure out this way below as explained.
To post json objects back to the server, json.strinfy will have to be supported. To support the same on IE, please download json2.js from https://github.com/douglascrockford/JSON-js and refer in your view. The following code snipped worked for me, I hope it helpe someone else too.
//include jquery library from your preferred cdn or local drive.
<!-- include json2.js only when you need JSON.stringfy method -->
<script type="text/javascript" src="~/scripts/json2.js"></script>
<script type="text/javascript">
function button_click() {
 //object to post back to the server.
 var postData = { "Id": $('#hfUserId').val(), "Name": $('#Name').text(), 
 "address": new Array() };
 var address = new Array(); var addr;
 addr = { "HouseNo": "1", "Street": "ABC", "City": "Chicago", "State": "IL" };
 address[0] = addr;
 addr = { "HouseNo": "2", "Street": "DEF", "City": "Hoffman Est", "State": "IL" };
 address[1] = addr;
//make ajax call to server to save the data
 $.ajax({
    url: '@Url.Action("myAction", "MyController")',
    type: 'POST',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(postData),
    async: true,
    success: function (data) { alert('User Saved'); },
    error: function (data) { alert('Could not save User'); }
    });
}
</script>
The model for the address list will be as below. Please note that the property names are the same as the addr object and it has get and set.
public class Address
{
    public string HouseNo { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}
The controller action will be something like below
[HttpPost]
public ActionResult myAction(string Id, string Name, List<Address> address)
{
   JsonResult result = null;
   result = new JsonResult
                {
                    Data = new
                    {
                        error = false,
                        message = "User Saved !"
                    }
                };
    return result;
}

Friday, November 22, 2013

How to fix Configuration system failed to initialize

Configuration system failed to initialize- Issue in .NET

Problem : 

I was working on a console application which will work as a Task Scheduler on the server, so I created a console application in Visual Studio 2012, so the project was created with Target Framework as v4.5, but the problem with that was, neither our QA server or Production server for that app had Framework v4.5 installed on them. So what I did was, I went to the project properties and changed the Target Framework to 4.0 instead of 4.5 and tried to run on Debug, thats it, I keep getting the error whenever the application was trying to read configuration values using ConfigurationManager.AppSettings and the error reads as below

"Configuration system failed to initialize".

Solution : 

Like most of us, I copied the exception details and googled it and this is what I got as a probable resolution from Stack overflow.



make sure that your config file (web.config if web, or app.config if windows) in your project starts as:
<?xml version="1.0"?>
<configuration>
   <configSections>
      <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="yourProjectName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>

The above answer and more such similar answers on the internet points to the configSettings section & has been marked as an answer by most people so I guess this has resolved their issues but not in my case. It still gave me the errors. So this is what I did to get it resolved.

If you have an already running Console Application like me lets say in v4.5, then 
1. If that application is open in visual studio make sure its running in the current version, just check-in your changes to source control and close the studio.
2. Open the *.csproject file on notepad and change the targetFramework from 4.5 to 4.0 like this 
"<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>" and save the file.
3. Open the project now on visual studio and go to App.config file and make the change in the file under element startup and make .NETFramework, Version=v4.0 like below

<startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>

Now if you run your application, it should run just fine, atleast in my case.


Wednesday, November 20, 2013

Unable to Resolve Service Name, Oracle connection from ASP.NET or SSIS Business Intelligence Studio

Unable to Resolve Service Name, Oracle connection from ASP.NET or SSIS Business Intelligence Studio

Problem

In one of my recent projects, I had this peculiar problem where I was not able to connect to Oracle Database from my ASP.NET application and every time it gave me an error like "Unable to resolve service name", although my tnsnames.ora file was correct and moreover, I was able to connect to the same oracle datasource from the Oracle SQL Developer studio, it was just driving me crazy.

Solution

One quick solution I figured out for both my connecting to oracle from the BIDS and Microsoft Visual Studio web configuration like below

Lets say your tnsnames.ora reads like below

oradb.mydomain.com =
(DESCRIPTION =
  (ADDRESS = (PROTOCOL = TCP)(HOST = host.mydomain.com)(PORT = 1521))
  (LOAD_BALANCE = YES)
  (CONNECT_DATA =
   (SERVER = DEDICATED)
   (SERVICE_NAME = oradb.mydomain.com)
   (FAILOVER_MODE =
   (TYPE = SELECT)(METHOD = BASIC)(RETRIES = 180)(DELAY = 5)
   )
  )
)

This is what has to be done when putting the connection string inside Visual Studio to get it connected to the oracle database.

<connectionStrings>
<add name="myConn" connectionString="Server=host.mydomain.com/oradb.mydomain.com; User Id=guest; Password=guest" providerName="System.Data.OracleClient" />

So above all that I did was to mention the host name along with the service name. Mind you, there is one important thing here, the oracle data source is running on the default port 1521.

The problem associated with connecting to Oracle datasource using an OLEDBDatsource control on BIDS is slightly more than just the connection to the oracle datasource if you are working on a 64 bit machine/PC. The BIDS is a 32 bit application and so you have to make sure that you have a 32 bit oracle client installed on your PC along with the 64 client of Oracle otherwise the BIDS may not be able to detect the "Oracle Provider for OLE DB" driver from the PC that you are working on. 

Once this is resolved, like the visual studio, here also we will mention the DataSource in the connection string as host/service_name in the connection used as shown in the screen shot shown below.

In the connection manager above, the Server or file name is mentioned as "host.mydomain.com/oradb.mydomain.com". But here also please note that in my case the oracle datasource was running on default port 1521. 

Thants it ! Happy coding !

Tuesday, November 5, 2013

Reading XML nodes with namespaces in SQL Server

Reading XML nodes with namespaces in SQL Server


Like me, many of you might have gone through situations where you might had to parse and read XML in SQL Server. SQL Server 2005 onward have a very good functional support to read XML. Lets go over some examples on how to do so 

1. The first XML is an xml with persons details and contact details and here is how we can read that below

DECLARE @MyXML XML
SET @MyXML = '<SampleXML>
<Person>
<firstName>Kaushik</firstName>
<lastName>Ghosh</lastName>
<skill>ASP.NET</skill>
<language montherTongue="Bengali">Hindi</language>
<age>31</age>
</Person>
<Contacts>
<primaryEmail>primary@mydomain.com</primaryEmail>
<secondaryEmail>secondary@mydomain.com</secondaryEmail>
<primaryPhone>1234567890</primaryPhone>
<secondaryPhone>Melon</secondaryPhone>
</Contacts>
</SampleXML>'

SELECT
a.b.value('Person[1]/firstName[1]','varchar(10)') AS firstName,
a.b.value('Person[1]/lastName[1]','varchar(10)') AS lastName,
a.b.value('Person[1]/skill[1]','varchar(10)') AS skill,
a.b.value('Person[1]/language[1]/@montherTongue','varchar(10)')+ ',' + a.b.value('Person[1]/language[1]','varchar(10)') AS language,
a.b.value('Person[1]/age[1]','varchar(10)') AS age,
a.b.value('Contacts[1]/primaryEmail[1]','varchar(30)') AS primaryEmail,
a.b.value('Contacts[1]/secondaryEmail[1]','varchar(30)') AS secondaryEmail,
a.b.value('Contacts[1]/primaryPhone[1]', 'varchar(10)') AS primaryPhone,
a.b.value('Contacts[1]/secondaryPhone[1]', 'varchar(10)') AS secondaryPhone
FROM @MyXML.nodes('SampleXML') a(b)

In the above example it works fine, when the nodes are not repeating, but what if the XML has repeating nodes, please see the next example. This time we will take an example which will have namespaces, nested nodes with attributes and also multiple repeating nodes.

DECLARE @xml_text xml;
SET @xml_text = '
<towers xmlns="http://www.mydomain.org/schemas/xmls" version="1.4.1.0">
<tower xmlns="http://www.mydomain.org/schemas/xmls" uid="2183256">
<name>J.D. TAYLOR 24 #1</name>
<numAPI>0100320139</numAPI>
<towerLocation uid="Location1">
<latitude uom="dega">20.329705810</latitude>
<longitude uom="dega">-27.720651970</longitude>
</towerLocation>
<towerDatum uid="GL">
<code>GL</code>
<name>Ground Level</name>
</towerDatum>
<operator>Mobile comp1</operator>
<country>Unknown</country>
<county>DuPage</county>
<state>Illinois</state>
<timeZone>-00:00</timeZone>
<commonData>
<dTimCreation>2013-10-04T18:51:09.377</dTimCreation>
<dTimLastChange>2013-10-04T18:51:09.377</dTimLastChange>
</commonData>
</tower>
<tower xmlns="http://www.mydomain.org/schemas/xmls" uid="2183256">
<name>K.D. TAYLOR 24 #1</name>
<numAPI>0100320140</numAPI>
<towerLocation uid="Location2">
<latitude uom="dega">10.329705811</latitude>
<longitude uom="dega">-17.720651970</longitude>
</towerLocation>
<towerDatum uid="SL">
<code>SL</code>
<name>Sea Level</name>
</towerDatum>
<operator>Mobile Company 2</operator>
<country>Unknown</country>
<county>Cook</county>
<state>ILLINOIS</state>
<timeZone>-00:00</timeZone>
<commonData>
<dTimCreation>2013-11-04T18:51:09.377</dTimCreation>
<dTimLastChange>2013-11-04T18:51:09.377</dTimLastChange>
</commonData>
</tower>
</towers>';

with xmlnamespaces('http://www.mydomain.org/schemas/xmls' as towers,
default 'http://www.mydomain.org/schemas/xmls')
    SELECT  T.Item.value('(name/text())[1]', 'varchar(200)') as name,
T.Item.value('(numAPI/text())[1]', 'varchar(30)') as numAPI,
T.Item.value('towerLocation[1]/@uid[1]', 'varchar(20)') as towerLocation,
T.Item.value('towerLocation[1]/latitude[1]', 'varchar(20)') + ' ' 
+ T.Item.value('towerLocation[1]/latitude[1]/@uom[1]', 'varchar(10)') as latitude,
T.Item.value('towerLocation[1]/longitude[1]', 'varchar(20)') + ' ' 
+ T.Item.value('towerLocation[1]/longitude[1]/@uom[1]', 'varchar(10)') as longitude,
T.Item.value('towerDatum[1]/@uid[1]', 'varchar(10)') as towerDatumCode,
T.Item.value('towerDatum[1]/code[1]', 'varchar(10)') + ' or ' 
+ T.Item.value('towerDatum[1]/name[1]', 'varchar(20)') as towerDatum,
T.Item.value('(operator/text())[1]', 'varchar(200)') as operator,
T.Item.value('(country/text())[1]', 'varchar(30)') as country,
T.Item.value('(county/text())[1]', 'varchar(30)') as county,
T.Item.value('(state/text())[1]', 'varchar(30)') as state,
T.Item.value('(timeZone/text())[1]', 'varchar(30)') as timeZone,
T.Item.value('commonData[1]/dTimCreation[1]', 'varchar(30)') as created,
T.Item.value('commonData[1]/dTimLastChange[1]', 'varchar(30)') as changed
    FROM    @xml_text.nodes ( 'towers/tower' ) AS T(item)

The above XML is a more realistic example of XML data that you might need to parse in the database while doing some sort of integration.