Wednesday, November 21, 2012

Asp.Net MVC 4–Creating an AJAX page and using JQueryUI dialog

This is a very quick tutorial on how to create a page that displays data using AJAX. In addition, I will also show how to use the JQueryUI dialog element.

First a quick description of the page we are going to build:

image

There are 5 links on the page. When you click on one of the links 2 parts of the page are updated via jquery. (The div at the bottom and the dialog to the right).

Step 1: Create a MVC 4 Internet application.
Create a new MVC 4 internet application project, which we will use for this tutorial.

Step 2: Check to make sure “UnobtrusiveJavaScriptEnabled” is set to true in your web.config file.

Step 3: Add the references to the unobtrusive scripts in _layout.cshtml:
This is done by adding the line: @Scripts.Render("~/bundles/jqueryval") right after the line: @Scripts.Render("~/bundles/jquery")
image

Note: FYI: The reference to “~/bundles/jqueryval” is based on the bundle names defined in “BundleConfig.cs”.

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));

Step 3: Add a new action to the HomeController, that will return a partial view:

public ActionResult IndexData(int id)
        {
            ViewBag.Id = id;
            ViewBag.Title = "The ID is: " + id;
            return PartialView();
        }

Step 4: Create a view for the IndexData action:

Right click in the action and select “Add View” and select the defaults.

Add the following code to the new IndexData.cshtml page:

@{
   
}
@Html.Hidden("Id",(int)ViewBag.Id)
@Html.TextBox("Title",(string)ViewBag.Title)

Step 4:Update Index.cshtml to show the links and allow calls to occur using AJAX:

Add a reference to the CSS files used by JqueryUi by adding the following code:

@Styles.Render("~/Content/themes/base/css")

Add an Ajax.ActionLink:

@Ajax.ActionLink("ajax load for id: 101", "IndexData", new {id = 101}, new AjaxOptions {HttpMethod = "Get", InsertionMode = InsertionMode.Replace, OnSuccess = "SuccessFunction", UpdateTargetId = "myDiv"})

The above line, adds a link with the text “ajax load for id: 101”. It will call the “IndexData” action on the HomeController and it will pass it the value of 101. Finally, check out the AjaxOptions values:
- The AJAX call will be performed as a GET operation
- The call will result in replacing the DOM with the data that is returned
- If the call succeeds, the “SuccessFunction” will be called.
- Finally the data that is returned by the ajax call will update a DOM element named “myDiv”

We will add a few more such links:

@Ajax.ActionLink("ajax load for id: 202", "IndexData", new {id = 202}, new AjaxOptions {HttpMethod = "Get", InsertionMode = InsertionMode.Replace, OnSuccess = "SuccessFunction", UpdateTargetId = "myDiv"})
<br/>
@Ajax.ActionLink("ajax load for id: 303", "IndexData", new {id = 303}, new AjaxOptions {HttpMethod = "Get", InsertionMode = InsertionMode.Replace, OnSuccess = "SuccessFunction", UpdateTargetId = "myDiv"})
<br/>

The next step is to add a couple of divs that will be used to display the data.

<div id="myDiv"></div>
<div id="myDiv2" style="border-width: medium; border-color: black"></div>

The first div will be used for the dialog and the 2nd div for updating a DOM element directly on the page.

Finally:

Add the following code to the end of the page:

@section scripts
{
    @Scripts.Render("~/bundles/jqueryui")
    <script>
        $(function() {
            $("#myDiv").dialog({ autoOpen: false });
        });
        function SuccessFunction(data) {
            $("#myDiv").dialog("open");

            $("#myDiv2").html(data);
        }
    </script>
}

Lets break down the code:

1. @Scripts.Render("~/bundles/jqueryui"): This line adds the reference to the JqueryUI scripts

2. $(function() : The ready-function, sets up myDiv to be a dialog. In addition, it sets it up to not open by default.

3. function SuccessFunction: This is the function that is called when the Ajax calls return. It opens the dialog and also updates the 2nd div to show the same data in 2 different ways.

Final code for the index.cshtml

@{
    ViewBag.Title = "Home Page";
}
@Styles.Render("~/Content/themes/base/css")
@Ajax.ActionLink("ajax load for id: 101", "IndexData", new {id = 101}, new AjaxOptions {HttpMethod = "Get", InsertionMode = InsertionMode.Replace, OnSuccess = "SuccessFunction", UpdateTargetId = "myDiv"})
<br/>
@Ajax.ActionLink("ajax load for id: 202", "IndexData", new {id = 202}, new AjaxOptions {HttpMethod = "Get", InsertionMode = InsertionMode.Replace, OnSuccess = "SuccessFunction", UpdateTargetId = "myDiv"})
<br/>
@Ajax.ActionLink("ajax load for id: 303", "IndexData", new {id = 303}, new AjaxOptions {HttpMethod = "Get", InsertionMode = InsertionMode.Replace, OnSuccess = "SuccessFunction", UpdateTargetId = "myDiv"})
<br/>
<div id="myDiv"></div>
<div id="myDiv2" style="border-width: medium; border-color: black"></div>
@section scripts
{
    @Scripts.Render("~/bundles/jqueryui")
    <script>
        $(function() {
            $("#myDiv").dialog({ autoOpen: false });
        });
        function SuccessFunction(data) {
            $("#myDiv").dialog("open");
            $("#myDiv2").html(data);
        }      
    </script>
}

Thursday, November 15, 2012

ASP.Net MVC–Returning XML

If you need to return xml content from an MVC controller, the easiest way to do it is to use the “Controller.Content” method.

public class TestController : Controller
{
        public ActionResult Index()
        {
             string result = “<books><book/></books>”
             return this.Content(result, "text/xml");
        }
}

Wednesday, November 14, 2012

Asp.Net WebApi–allowing format to be specified in the URL

By default WebAPI looks at the header to determine how to serve back content. But what if you cant set the header in your client app and so you need to specify the format via the URL?

What you need to do is to add a query string mapping for the XML formatter. This can be done using the following code in “Application_Start” of the Global.aspx.cs file:

MediaTypeFormatter xmlFormatter = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xmlFormatter.AddQueryStringMapping("format", "xml", "text/xml");

And what if you want XML to be your default formatter? The easy way I found for this was to reorder the formatters in “GlobalConfiguration.Configuration.Formatters”, so that the XML formatter was the first in the list.

MediaTypeFormatter xmlFormatter = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
MediaTypeFormatter jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

GlobalConfiguration.Configuration.Formatters.Remove(xmlFormatter);
GlobalConfiguration.Configuration.Formatters.Remove(jsonFormatter);
GlobalConfiguration.Configuration.Formatters.Insert(0,jsonFormatter);
GlobalConfiguration.Configuration.Formatters.Insert(0, xmlFormatter);

Note: If you reorder the formatters, you will need to add a query string mapper for JSON:

jsonFormatter.AddQueryStringMapping("format", "json", "application/json");

Monday, November 12, 2012

Calling webservices from SqlServer Reporting Services (SSRS)

There is surprisingly very little information on the web on how to call webservices from SSRS. So here is a quick list of stuff that I found out:

Note: I am using WCF webservices for what I was doing (shouldn’t matter if you are using some other kind of service, as long as it’s a SOAP service).

Note 2: Use something like Fiddler to inspect the traffic to figure out what the request is going out as. It can be useful to figure out why a call is erroring out.

  1. Create a new data-source.
    1. Choose “Use a connection embedded in my report”
    2. Set the “connection type” as xml
    3. Enter the url to the webservice (eg: http://myserver/ssrsTest.svc)
  2. Right click on the data-source and select add “DataSet”
    1. Select “Use a dataset embedded in my report”
    2. Open the query designer and build your query in there.
  3. Here is what a query looks like to call a method named test that takes no parameters:
    1. <Query>
      <Method Name="test" Namespace="http://tempuri.org/">
      </Method>
      <SoapAction>http://tempuri.org/ITestService/Test</SoapAction>
      </Query>

      The namespaces were found by looking at the WSDL (target namespace defines the namespace)

      <wsdl:operation name="Test">
          <soap:operation soapAction="http://tempuri.org/ITestService/Test" style="document"/>
          <wsdl:input>
              <soap:body use="literal"/>
          </wsdl:input>
          <wsdl:output>
              <soap:body use="literal"/>
          </wsdl:output>
      </wsdl:operation>

  4. Here is what a query looks like to call a method named testWithParameters that takes one parameter
  5. <Query>
    <Method Name="testWithParameters " Namespace="http://tempuri.org/">
    <Parameters>
    <Parameter Name="testParameter"><DefaultValue>1</DefaultValue></Parameter>
    </Parameters>
    </Method>
    <SoapAction>http://tempuri.org/ITestService/testWithParameters</SoapAction>
    </Query>

Saturday, November 10, 2012

How to sideload Windows 8 store apps onto a development device

Here are the steps that one must go through to sideload a Windows 8 store app on to a development device for testing (the dev device is a device other than the one on which it was developed – as on the development machine, Visual Studio takes care of loading the app).

Build the app package

  1. Under Project > Store, select “Create App Packages”
    image
  2. Select No on the first page of the dialog (Do you want to build packages to upload to the Windows Store?)
    image
  3. Make sure you select an architecture that’s appropriate for the machine where you will be testing the package.
    image
  4. The next step will create the app package.
  5. Open the folder where the app package was created, you should find a file with the extension “appxupload”. If you look in the folder, you will also find a file named “Add-AppDevPackage.ps1”
  6. Copy the folder and its contents to the target machine.

Prep the target machine to be able to sideload the a

Note: this preps the target machine as a dev machine. What this means is that your app will run for only 3 months and then expire and you will have to reacquire the dev license.

  1. Run powershell as an administrator on the target machine (the easiest way to do this is to hit Windows key + Q and search for powershell. Tap and drag the powershell icon and you will see the context menu from where you can open it in admin mode).
    image
  2. Setup powershell to run in unrestricted mode by typing “set-executionpolicy unrestriced” and hitting enter. (note: you need to do this only one time per machine).
  3. Acquire a developer license by typing “Show-WindowsDeveloperLicenseRegistration” at the command prompt and following the steps in the dialog (you will have to sign in to your Windows Live account).
  4. To install the application, find the “add-appdevpackage.ps1” file that we found in step 5 above. Run it by typing “Add-AppDevPackage.ps1” and hitting enter.
  5. The application will be installed on the target machine and you will be able to run it from the dashboard.

Monday, November 05, 2012

CRM 2011 - Action Microsoft.Crm.Setup.Server.GrantConfigDBDatabaseAccessAction failed

I got the following error when I was installing CRM 2011 on one of our servers that had CRM 4 installed previously on it:

Action Microsoft.Crm.Setup.Server.GrantConfigDBDatabaseAccessAction failed.

Windows NT user or group 'Domain\SQLAccessGroup {GUID}' not found. Check the name again.

I was able to fix the error by deleting the following logins on the SqlServer being used by CRM:

DomainName\PrivReportingGroup {GUID VALUE}
DomainName\ReportingGroup {GUID VALUE}
DomainName\SQLAccessGroup {GUID VALUE}

Sunday, November 04, 2012

Screen capture in Windows 8

To capture a screen shot on a Windows 8 machine do the following:

Windows Surface devices: Hold down the Windows key while pressing the volume-down button (both are the hardware buttons on the surface – sorry doing this on your keypad will not work). The screen captures get stored in the Photos app under “Screenshots”

Windows 8:

Press “Windows” key + “Print Screen” (PrntScr). The screen shot gets stored under “Screenshots” in your picture library.

Saturday, November 03, 2012

Colorado 2012 Elections–Information Sources

Here are some resources that I found useful to fill out the 2012 ballot

  1. Vote411.org: A very good website for vote information. Enter your address and you get presented with a personalized list of questions that appear on your ballot. In addition, you get information on all the candidates for a particular race as well as some Q&A filled in by the candidates. Was extremely useful in figuring out where different candidates stand on various issues (especially for local races)
  2. Colorado Office of Judicial Performance Review: A review panel consisting of citizens and attorneys that evaluate and provide opinions on retaining judges. A good website to determine how to vote for judges.
  3. 2012 Blue Book: Ballot information booklet published by the State’s Legislative Council Staff
  4. ColoradoBallot.Net: A site with some basic information on ballot initiatives setup by an independent small business owner.
  5. League of Women Voters – Colorado: Another useful site for ballot information