Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Thursday, September 4, 2014

Use SoapUI to test your web services

Recently, I created a web service that external organizations would use as an API to access our data.  I decided to use WCF and the SOAP architecture to achieve this.  I also created a little .NET console app to test the web service.  Everything worked great.  However, I was a little concerned that I might have unintentionally wrote some code that was only supported by the Microsoft stack.  How could I be sure that my web service could be used by someone using a different platform?

My first idea was to try to access the web service using jQuery.  I felt that if I could successfully invoke the web service using jQuery or JavaScript, this would demonstrate that Microsoft technology wasn't necessary to use my service.  However, I found that calling a SOAP based web service from client side scripting is not an easy task.  In fact, I never got this to work, and there is not a lot of information out there about how to do this.  One problem is that browsers have security measures to stop cross site scripting.  So the web service has to be part of the same site.  If you can get past that, you also have to manually build the SOAP envelope in your javascript which is tedious.  On top of that you have to figure out how to specify your logon credentials within the request.  I concluded that it is just not practical to call a SOAP service from the client.  I think this is where the advantages of using a REST style web service really pay off.

I discovered a widely used application called SoapUI.  It is a free download, and you can use it to invoke the methods of your web service for testing purposes.  This is a way to independently test your web service operations without being bound to Microsoft.

Installation is straight forward and instructions can be found on the site.  Note that you do not need to install Hermes if you're not testing a Java service.

Here is how to test a web service operation.

  1. Open SoapUI and right click on Projects, New SOAP Project.
  2. Name the project and specify the address of the WSDL of your service.
  3. Check the box that says Create Sample Requests.
  4. In the navigator, you'll see each operation of the service.  If you click the plus sign next to each operation you will see the sample request that was created for you.
  5. Click on the request and find the request properties.
  6. If the web service security is set up for TransportWithMessageCredential, then set the username and password properties to something that works.  Also set the WSS-Password Type to PasswordText.
  7. Double-click the request.
  8. In the request window, you'll see the SOAP envelope.  You can see where the parameters go, and can set these here.
  9. Then, click the green arrow which sends the request to the web service.
  10. The results will be shown in the right-hand pane.

Thursday, June 12, 2014

jQuery Plugins

Sometimes you will come across some bit of functionality that jQuery doesn't handle natively and jQuery UI doesn't offer up a solution.  For example, let's say you need to implement a mask on a text box for a phone number.  You could use the Ajax Control Toolkit, but I've had issues getting this to work so I don't recommend it.  I love jQuery and jQuery UI, but you can't do this "out of the box".

A jQuery plugin is an extension of jQuery that "some guy" has written to accomplish something that jQuery doesn't do by itself.  In fact, jQuery UI is basically a "plugin".  The only difference is that jQuery UI is official and a plugin is not.  And this is what makes me a little hesitant to use plugins.  But, in the case of our phone number mask example, I think it's probably the best fit.

First go to the jQuery Plugins page and find something you think will work.  The inputmask seemed to work well for me.  Download all the files, and stick them all in a folder in your project folder.  There should be some documentation either on the plugin page or downloaded into your folder.  It will tell you how to use the plugin in your code.  As an example, here is how I used the inputmask.

First add this script to your page.

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="InputMask/dist/jquery.inputmask.bundle.js" type="text/javascript"></script>

Note that I'm using a content provider (google) to host the "out of the box" jQuery code.  This is simply for brevity.

Then your jQuery would look like this:

        $(document).ready(function () {
            $("#txtPhoneNum").inputmask("999-999-9999");
        });

Tuesday, March 25, 2014

Add a Bootstrap jQuery widget to an MVC view.

Bootstrap is an awesome open source UI framework that uses both CSS and jQuery to provide a great user experience.  Besides straight up CSS, they offer some "widgets" that offer some functionality that jQuery UI does not provide.  The process for getting a widget on your view is almost exactly the same as using jQuery UI.

You have to render both the jQuery and Bootstrap bundles in your layout view.  If you don't have a Bootstrap bundle, you just need Bootstrap.js.  Also ensure Bootstrap.css is in your CSS bundle.

This markup will render a button that will produce the popover widget when clicked.

<button type="button" id="Example" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="top" data-content="Phone:  555-5555">
   Popover on top
</button>

Then, add a jQuery file with the following:

$(document).ready(function () {
    $("#Example").popover();
});

Friday, January 10, 2014

AJAX Enabled WCF Service with Windows Authentication

Let's say you have a WCF Service that you are calling from jQuery code.  Everything works fine until you set up Windows Authentication.  Then it blows up.  The problem is that the binding has to be configured to work with Windows Authentication.  Let's first look at the endpoint in the web.config file. Take a look at the binding attribute. It should say "webHttpBinding". WebHttpBinding means that your web service responds to HTTP requests.  This is necessary because this is the only way jQuery can call your service.  In fact, I believe Visual Studio sets it in this way when you added the AJAX Enabled WCF Service rather than a plain old WCF Service.  However there is no configuration for the WebHttpBinding itself, which means it just uses its default configuration which I believe is configured to use anonymous authentication.  So we need to configure the WebHttpBinding to use Windows Authentication by putting the following nodes inside the system.servicemodel node:
    <bindings>
      <webHttpBinding>
        <binding>
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"></transport>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>


Monday, November 25, 2013

Shortcut to "Document is ready" code in jQuery

When you want to execute some jQuery you normally encapsulate the code inside one of these:
$(document).ready(function () {
    // Code that executes when document is ready.
});
However, when looking around at examples in the API documentation, you'll sometimes see this which apparently is equivalent:
$(function() {
    // Code that executes when document is ready.
});

Monday, October 28, 2013

Ignore the route when adding a web service to an MVC project

You may want to add a web service to an MVC project in order to to implement AJAX call backs.  Remember that MVC is always trying to interpret URLs using it's routing configuration.  So, if the routing configuration encounters a URL referring to your web service, the framework won't know what to do with it.

You could just put it into another web project.  This works fine with IE 10, but Chrome will blow up.  I think it has something to do with cross domain configuration (and lack thereof).  Do yourself a favor, and stick it in the MVC project, and remember to add this to your RegisterRoutes method:

routes.IgnoreRoute("YourAjaxEnabledService.svc/DoWork")

Friday, October 18, 2013

MVC Buttons, Links, and Actions

With any web page, you need to execute code on the server in response to user actions.  With traditional web forms, this was accomplished with event handlers generally tied to buttons, and links.  With MVC, we have this concept of an "action method".  So, the question becomes, how do we kick off action methods?  There are 3 big ways to do this:
  1. The user enters a url and the routing system kicks off the action method associated with the route.  The parameters of the action method are in the route itself, or exist as query parameters.  Technically this is a GET request.
  2. The user clicks a link defined by the Html.ActionLink method.  ActionLink will generate a url that contains the route necessary to execute the specified action method on the specified controller with the provided parameters.  Technically this is a GET request.
  3. Within a form element, the user clicks on a button with the "type" attribute set to "submit".  The action method associated with the form is executed.  Parameters are provided through model binding.  Technically this is a POST request.
One and Two are really doing the same thing.  So, we are either doing a GET with a link, or a POST with a button.  When do we use a GET link, and when do we use a POST button?

Standard practice is to use a GET link if we are not changing anything and POST button when are changing something.

What is model binding?  First of all model binding only occurs during a POST.  It's not going to happen if you are kicking off an action method through a link (such as creating one with Html.ActionLink).  Any parameters for the action method associated with the form will be automatically provided based on matching up the names of the ids on the page with the names of the parameters.  So if you have a hidden field with an id of "Price", and you have a parameter of your action method named "Price", this will automatically be sent to the action method when you POST.

Some people are fond of everything being a button, even stuff that shouldn't be a POST.  For example, a "Cancel" button.  One option is...

Create a button and make it behave like a link. Setting the type attribute to "button" will prevent the button from doing a POST

<button id="cancelButton" type="button">Cancel</button>

Then in your jQuery file,

    $("#cancelButton").click(function () {
        window.location = '../ActionName/' + $("#inputParameterId").val()
    });

I don't particularly care for this solution.  Feels like a hack to me.

Some might want everything to be a link, even though a "Save" button should be a POST.  We could...

Create a link and make it behave like a submit button.

<a id="LinkSave" href="#">Link Save</a>

Then, in your jQuery file,

    $("#LinkSave").click(function () {
        $("#myForm").submit();
    });

AND, to get this to work, your form has to have an ID, so you have to do some extra stuff with your Html.BeginForm helper...

@Using Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, New With {.id = "myForm"})

Besides being ugly and a hack, this only works in IE. So I don't like that either.

Your best bet is to leave POSTing to buttons and GETting to links.  If you apply css in a smart way, you can style them to look the same.  For example:

                        <div class="actionButtons">
                            <input name="Save" type="submit" value="Save" />
                            @Html.ActionLink("Cancel", "ApplicationSummary", New With {.id = Model.Nutshell.ApplicationId})
                        </div>

The CSS looks like this:
.actionButtons A, .actionButtons INPUT {
    font-size: 10pt; 
    color: White; 
    margin: .5em; 
    font-weight: normal;
    text-decoration: none; 
    padding: .15em 1.5em .2em 1.5em;
    background-color: #353535; 
    border: 1px solid black;
}

So, any anchor or input tags inside a container with the "actionButtons" class will have this style.

One final note.  What if you need more than one POST button on the same page?  You could put two submit buttons within the same form and differentiate between the two in the action method using something like:

            If Request("Save") IsNot Nothing Then
                'Save Logic Here
            ElseIf Request("Verify") IsNot Nothing Then
                'Verify Logic Here
            End If

I don't like that because it's hackish and messy. Just put two or more forms on the page, and have each form target a different action method for each submit button.

UPDATE:  OK, so having two forms isn't always practical.  What if you need to submit the same data, but in two different ways depending on what button is clicked?  Go ahead, and put to submit buttons on your form.  Make sure the name attribute is identical. Let's name them both "TheViewButton".  The value attribute will obviously be different.  Your action method will look like this:

<HttpPost>
Function TheViewName(viewModel As TheViewModel, TheViewButton As String) As ActionResult
   If TheViewButton = "Save" Then
      'Save Logic
   Else
      'Other Logic
   End If
End Function

I like this solution a bit better.

Wednesday, September 25, 2013

Using a jQuery UI widget in on an MVC view

First, you need to add references to the appropriate jQuery libraries. The recommended way to do this is to use NuGet. Right click your project, and click on Manage NuGet Packages. Search online and install jQuery and jQuery UI. This will add the .js files as well as .css files that are used by the widgets. Bundles will be created in your BundleConfig file and these bundles will be rendered in your default layout file. Essentially, rendering a bundle is equivalent to using a <script> tag to reference the .js files. If you use another layout file, you must copy these statements over.

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")

This example will add the functionality of the datepicker widget to a text box. First create a textbox and make sure it has the id attribute:

@Html.TextBoxFor(Function(x) x.ProposedStartDate, New With {.id = "ProposedStartDate"})

I recommend a separate jQuery file for each page that you add jQuery functionality. Create the file, and include a link to this file in your view:

<script type="text/javascript" src="~/Scripts/ViewjQuery/SampleView.js"></script>

In your jQuery files, associate your textbox with the widget by using the following code:

$(document).ready(function () {

    $("#ProposedStartDate").datepicker();

});

Finally, you're not going to like the look of the datepicker, so go to Theme Roller and download a jQuery theme .css file or two. Then reference this css file in the head tag of your layout file thusly:

<link href="~/Content/themes/lightness/jquery-ui-1.10.3.custom.css" rel="stylesheet" type="text/css" />

Finally, you will be satisfied with the look of your datepicker, but you may want to size it down a bit. This has to be done through the font-size css style of a particular class. I don't recommend changing the theme .css that you downloaded. Rather, I would just create a new .css file for these types of tweaks and load it after you load the theme roller css. Put this in there:

.ui-datepicker { font-size:9pt !important}

Tuesday, July 23, 2013

Call a WCF web service using jQuery

First, add an AJAX-enabled WCF Service to your project.  There is a Visual Studio template for this.  Add a web method like the following:

    <OperationContract(), WebGet()>
    Public Function GetFood(inputId As String) As Food()
        Dim ReturnFood As New List(Of Food)
        If inputId = 1 Then
            ReturnFood.Add(New Food With {.Id = "1", .Name = "Bananas", .Color = "Yellow"})
        ElseIf inputId = 2 Then
            ReturnFood.Add(New Food With {.Id = "2", .Name = "Apples", .Color = "Red"})
        Else
            ReturnFood.Add(New Food With {.Id = "1", .Name = "Bananas", .Color = "Yellow"})
            ReturnFood.Add(New Food With {.Id = "2", .Name = "Apples", .Color = "Red"})
        End If
        Return ReturnFood.ToArray
    End Function

Notice the WebGet attribute.  This allows your web method to be called using a GET operation.  Very important.  Won't work without this.  What this means is if you browse to http://yourserver/AjaxGetResultsService.svc/GetFood, you will get Json back in return.

Also notice that I'm returning an array of Food which is a class I made up.  The .net framework will automatically turn this into Json for you.

So, if you had a button with an id of buttonPopulateFood, the following jQuery code would call this method and display the results.

    $("#buttonPopulateFood").click(function () {
        $.ajax({
            url: "AjaxGetResultsService.svc/GetFood",
            type: "GET",
            dataType: "json",
            data: {
                inputId: "1"
            },
            success: function (json) {
                displayJson(json);
            },
            error: function () { alert("You have failed.") }
        });
    });

Here is the displayJson function I'm calling.  I'm using the each function to iterate through the json array.

function displayJson(jsonData) {
    $.each(jsonData.d, function (index, value) {
        $("#food").append(index + ": " + value.Name + ", ");
    });
};

jQuery Basics

JavaScript

JavaScript is a programming language that runs inside a browser.  Because it runs inside a browser, it runs on the user's machine instead of on the web server.  JavaScript code will respond much quicker to events like button clicks than code that runs on the server.  JavaScript also uses a technology known as AJAX to call server code without a time consuming post back.  Incorporating more JavaScript into your web site can speed up and improve the user experience.  However, JavaScript is ugly.  You sometimes have to jump through a lot of hoops to do simple things, including AJAX calls.

jQuery

jQuery is simply a JavaScript library.  It is literally just one file that you download at jquery.com.  It's free and open source (you can't compile JavaScript anyway).  The library contains a bunch of functions that you can call.  The functions do pretty much everything you would want to do with JavaScript, so every line of code you write is just a call to a jQuery function.

To use jQuery, you just need to reference the jQuery library with a line like the following in the head tag of your html page:

    <script type="text/javascript" src="jquery-1.10.2.js"></script>  

You should definitely keep your own JavaScript in a separate file as well:

    <script src="StevesJScript.js" type="text/javascript"></script>

Let's dive into an example to demonstrate how this all works.

Clicking buttons

First, add a text box, a few buttons, and a paragraph to display some results to your page:

   <input type="text" id="textBoxNumber" />  
   <button id="buttonPressMe">Press Me</button>  
   <button id="buttonClear">Clear</button>  
   <p id="results">results</p>

Instead of setting the event attribute on the actual tag, you can associate a click event in your JavaScript file by calling a jQuery function.  This almost feels like a "code-behind" page like you see with ASP WebForms.

$(document).ready(function () {

    $("#buttonPressMe").click(function () {
        $("#results").text($("#textBoxNumber").val())
    });

    $("#buttonClear").click(function () {
        $("#textBoxNumber").val("");
    });

});

The $ function selects an element.  In this case, we select the whole document.  Then we call the ready function for that element.  So this means, after the document loads, whatever is sent to the ready function will execute.  You can see we have selected both buttons by id (using the # symbol) and have called the click function which specifies what to execute when the selected button is clicked.  Here I am simply displaying the contents of the text box and clearing out the text box.