Custom Invoke Azure WebJob



How to Make a Web job triggering POST request  

Url format is
https://{sitename}.scm.azurewebsites.net/api/triggeredwebjobs/{webjobname}/run

You'll need to add basic auth header with your deployment credentials.



Server side triggering code
------------------------------------

   private async void postmethod()
        {
            using (var client = new HttpClient())
            {
                var values = new List<KeyValuePair<string, string>>();

                var content = new FormUrlEncodedContent(values);
                client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "{Basic auth code }");

                var response = await client.PostAsync("https://{sitename}.scm.azurewebsites.net/api/triggeredwebjobs/{webjobname}/run", content);

                var responseString = await response.Content.ReadAsStringAsync();
            }

        }

REST Api


REST stands for Representational State Transfer.
It is a simple stateless architecture that generally runs over HTTP


The term API stands for Application Programming Interface. The term can be used to describe the features of a library, or how to interact with it.
 


HTTP methods

There are technically 8 different HTTP methods:
GET
POST
PUT
DELETE
OPTIONS
HEAD
TRACE
CONNECT

HTTP Status Codes

When you make an HTTP request, the server will respond with a code which corresponds to whether or not the request was successful and how the client should proceed. There are four different levels of codes:
  • 2xx = Success
  • 3xx = Redirect
  • 4xx = User error
  • 5xx = Server error
Here's a list of the most important status codes:

Success codes:

  • 200 - OK (the default)
  • 201 - Created
  • 202 - Accepted (often used for delete requests)

User error codes:

  • 400 - Bad Request (generic user error/bad data)
  • 401 - Unauthorized (this area requires you to log in)
  • 404 - Not Found (bad URL)
  • 405 - Method Not Allowed (wrong HTTP method)
  • 409 - Conflict (i.e. trying to create the same resource with a PUT request)
 

Scaffold your ASP.NET MVC project with the MvcScaffolding package


Installation

The short version is thisInstall-Package MvcScaffoldingIf you understood that, do it and skip ahead to “Scaffolding a CRUD interface”. If not, read on.
1. Install ASP.NET MVC 3, which includes the excellent NuGet Package Manager.
2. Create or open an ASP.NET MVC 3 web application. I’m calling mine ‘SoccerSite’.
3. Install the MvcScaffolding package. You can install it using the NuGet Package Manager Console, so it only takes a few seconds and you don’t have to download anything using your browser.  To do so,
  • Open the Package Manager Console window using Visual Studio’s View->Other Windows->Package Manager Console menu item.
  • Enter the following:
Install-Package MvcScaffolding

Scaffolding a CRUD interface

Scaffold Controller Team –Repository -Force

Installing or Upgrading MvcScaffolding

Update-Package MvcScaffolding


Defining simple relations between model classes

I’m going to continue the tutorial in the introductory post, which assumes you’ve already installed created the following model class:
public class Team
{
    public int TeamId { get; set; }
    [Required] public string Name { get; set; }
    public string City { get; set; }
    public DateTime Founded { get; set; }
}
Now I’d like to define another model class, Player. Each Player is associated with a team:
public class Player
{
    public int PlayerId { get; set; }
    public string Name { get; set; }
 
    // Having a property called <entity>Id defines a relationship
    public int TeamId { get; set; }
}
Simply having the TeamId property on Player is enough for both MvcScaffolding and EF Code First to realise there’s a 1:many relationship. Actually MvcScaffolding supports two conventions for defining relations – this is the simple one; I’ll explain the alternative later.
Note that defining TeamId as a non-nullable int, it’s mandatory. Each player must be in a team. If you wanted the relationship to be optional, use a nullable link property instead (i.e., public int? TeamId { get; set; }).
If you scaffold your UI now, by executing the following commands…
Scaffold Controller Team -Force
Scaffold Controller Player
public class Player
{
    public int PlayerId { get; set; }
    public string Name { get; set; }
    public int TeamId { get; set; }
 
    public virtual Team Team { get; set; } // This is new
}
… and by telling Team to have a property that holds its Players:
public class Team
{
    public int TeamId { get; set; }
    [Required] public string Name { get; set; }
    public string City { get; set; }
    public DateTime Founded { get; set; }
 
    public virtual ICollection<player> Players { get; set; } // This is new
}
Notice that both of these new properties are marked virtual. This lets Entity Framework use its Lazy Loading feature so the associated entities will be fetched as needed, and spares you having to write code to fetch them in your controller. I’ll talk more about this in a moment.
Now if you were to scaffold the UI with models like this, by issuing the following commands:
Scaffold Controller Team -Force
Scaffold Controller Player -Force



Scaffold Controller Team -Repository -Force
Scaffold Controller Player -Repository -Force


Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application



Add Column Sort Links to the Students Index Page
To add sorting to the Student Index page, you'll change the Index method of the Student controller and add code to the Student Index view.

Add Sorting Functionality to the Index Method

In Controllers\StudentController.cs, replace the Index method with the following code:
public ActionResult Index(string sortOrder)
{
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
   var students = from s in db.Students
                  select s;
   switch (sortOrder)
   {
      case "name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:
         students = students.OrderBy(s => s.LastName);
         break;
   }
   return View(students.ToList());
}
This code receives a sortOrder parameter from the query string in the URL. The query string value is provided by ASP.NET MVC as a parameter to the action method. The parameter will be a string that's either "Name" or "Date", optionally followed by an underscore and the string "desc" to specify descending order. The default sort order is ascending.
The first time the Index page is requested, there's no query string. The students are displayed in ascending order byLastName, which is the default as established by the fall-through case in the switch statement. When the user clicks a column heading hyperlink, the appropriate sortOrder value is provided in the query string.
The two ViewBag variables are used so that the view can configure the column heading hyperlinks with the appropriate query string values:
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
These are ternary statements. The first one specifies that if the sortOrder parameter is null or empty,ViewBag.NameSortParm should be set to "name_desc"; otherwise, it should be set to an empty string. These two statements enable the view to set the column heading hyperlinks as follows:
Current sort orderLast Name HyperlinkDate Hyperlink
Last Name ascendingdescendingascending
Last Name descendingascendingascending
Date ascendingascendingdescending
Date descendingascendingascending
The method uses LINQ to Entities to specify the column to sort by. The code creates an IQueryable variable before the switch statement, modifies it in the switch statement, and calls the ToList method after the switchstatement. When you create and modify IQueryable variables, no query is sent to the database. The query is not executed until you convert the IQueryable object into a collection by calling a method such as ToList. Therefore, this code results in a single query that is not executed until the return View statement.
As an alternative to writing different LINQ statements for each sort order, you can dynamically create a LINQ statement. For information about dynamic LINQ, see Dynamic LINQ.

Add Column Heading Hyperlinks to the Student Index View

In Views\Student\Index.cshtml, replace the <tr> and <th> elements for the heading row with the highlighted code:
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
        </th>
        <th>First Name
        </th>
        <th>
            @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
This code uses the information in the ViewBag properties to set up hyperlinks with the appropriate query string values.
Run the page and click the Last Name and Enrollment Date column headings to verify that sorting works.

After you click the Last Name heading, students are displayed in descending last name order.

Add a Search Box to the Students Index Page

To add filtering to the Students Index page, you'll add a text box and a submit button to the view and make corresponding changes in the Index method. The text box will let you enter a string to search for in the first name and last name fields.

Add Filtering Functionality to the Index Method

In Controllers\StudentController.cs, replace the Index method with the following code (the changes are highlighted):
public ViewResult Index(string sortOrder, string searchString)
{
    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
    var students = from s in db.Students
                   select s;
    if (!String.IsNullOrEmpty(searchString))
    {
        students = students.Where(s => s.LastName.Contains(searchString)
                               || s.FirstMidName.Contains(searchString));
    }
    switch (sortOrder)
    {
        case "name_desc":
            students = students.OrderByDescending(s => s.LastName);
            break;
        case "Date":
            students = students.OrderBy(s => s.EnrollmentDate);
            break;
        case "date_desc":
            students = students.OrderByDescending(s => s.EnrollmentDate);
            break;
        default:
            students = students.OrderBy(s => s.LastName);
            break;
    }

    return View(students.ToList());
}
You've added a searchString parameter to the Index method. You've also added  to the LINQ statement a whereclausethat selects only students whose first name or last name contains the search string. The search string value is received from a text box that you'll add to the Index view. The statement that adds the where clause is executed only if there's a value to search for.

Note In many cases you can call the same method either on an Entity Framework entity set or as an extension method on an in-memory collection. The results are normally the same but in some cases may be different.
For example, the .NET Framework implementation of the Contains method returns all rows when you pass an empty string to it, but the Entity Framework provider for SQL Server Compact 4.0 returns zero rows for empty strings. Therefore the code in the example (putting the Wherestatement inside an if statement) makes sure that you get the same results for all versions of SQL Server. Also, the .NET Framework implementation of the Contains method performs a case-sensitive comparison by default, but Entity Framework SQL Server providers perform case-insensitive comparisons by default. Therefore, calling the ToUpper method to make the test explicitly case-insensitive ensures that results do not change when you change the code later to use a repository, which will return an IEnumerable collection instead of an IQueryable object. (When you call the Contains method on an IEnumerable collection, you get the .NET Framework implementation; when you call it on an IQueryable object, you get the database provider implementation.)
Null handling may also be different for different database providers or when you use anIQueryable object compared to when you use an IEnumerable collection. For example, in some scenarios a Where condition such as table.Column != 0 may not return columns that have null as the value. For more information, see Incorrect handling of null variables in 'where' clause.

Add a Search Box to the Student Index View

In Views\Student\Index.cshtml, add the highlighted code immediately before the opening table tag in order to create a caption, a text box, and a Search button.
<p>
    @Html.ActionLink("Create New", "Create")
</p>

@using (Html.BeginForm())
{
    <p>
        Find by name: @Html.TextBox("SearchString")  
        <input type="submit" value="Search" /></p>
}

<table>
    <tr>
Run the page, enter a search string, and click Search to verify that filtering is working.
Notice the URL doesn't contain the "an" search string, which means that if you bookmark this page, you won't get the filtered list when you use the bookmark. You'll change the Search button to use query strings for filter criteria later in the tutorial.

Add Paging to the Students Index Page

To add paging to the Students Index page, you'll start by installing the PagedList.Mvc NuGet package. Then you'll make additional changes in the Index method and add paging links to the Index view. PagedList.Mvc is one of many good paging and sorting packages for ASP.NET MVC, and its use here is intended only as an example, not as a recommendation for it over other options. The following illustration shows the paging links.

Install the PagedList.MVC NuGet Package

The NuGet PagedList.Mvc package automatically installs the PagedList package as a dependency. The PagedListpackage installs a PagedList collection type and extension methods for IQueryable and IEnumerable collections. The extension methods create a single page of data in a PagedList collection out of your IQueryable orIEnumerable, and the PagedList collection provides several properties and methods that facilitate paging. ThePagedList.Mvc package installs a paging helper that displays the paging buttons.
From the Tools menu, select Library Package Manager and then Package Manager Console.
In the Package Manager Console window, make sure ghe Package source is nuget.org and the Default project isContosoUniversity, and then enter the following command:
Install-Package PagedList.Mvc

Add Paging Functionality to the Index Method

In Controllers\StudentController.cs, add a using statement for the PagedList namespace:
using PagedList;
Replace the Index method with the following code:
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
   ViewBag.CurrentSort = sortOrder;
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

   if (searchString != null)
   {
      page = 1;
   }
   else
   {
      searchString = currentFilter;
   }

   ViewBag.CurrentFilter = searchString;

   var students = from s in db.Students
                  select s;
   if (!String.IsNullOrEmpty(searchString))
   {
      students = students.Where(s => s.LastName.Contains(searchString)
                             || s.FirstMidName.Contains(searchString));
   }
   switch (sortOrder)
   {
      case "name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:  // Name ascending 
         students = students.OrderBy(s => s.LastName);
         break;
   }

   int pageSize = 3;
   int pageNumber = (page ?? 1);
   return View(students.ToPagedList(pageNumber, pageSize));
}
This code adds a page parameter, a current sort order parameter, and a current filter parameter to the method signature:
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
The first time the page is displayed, or if the user hasn't clicked a paging or sorting link, all the parameters will be null.  If a paging link is clicked, the page variable will contain the page number to display.
A ViewBag property provides the view with the current sort order, because this must be included in the paging links in order to keep the sort order the same while paging:
ViewBag.CurrentSort = sortOrder;
Another property, ViewBag.CurrentFilter, provides the view with the current filter string. This value must be included in the paging links in order to maintain the filter settings during paging, and it must be restored to the text box when the page is redisplayed. If the search string is changed during paging, the page has to be reset to 1, because the new filter can result in different data to display. The search string is changed when a value is entered in the text box and the submit button is pressed. In that case, the searchString parameter is not null.
if (searchString != null)
{
    page = 1;
}
else
{
    searchString = currentFilter;
}
At the end of the method, the ToPagedList extension method on the students IQueryable object converts the student query to a single page of students in a collection type that supports paging. That single page of students is then passed to the view:
int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));
The ToPagedList method takes a page number. The two question marks represent the null-coalescing operator. The null-coalescing operator defines a default value for a nullable type; the expression (page ?? 1) means return the value of page if it has a value, or return 1 if page is null.

Add Paging Links to the Student Index View

In Views\Student\Index.cshtml, replace the existing code with the following code. the changes are highlighted.
@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />

@{
    ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
        <input type="submit" value="Search" />
    </p>
}
<table class="table">
    <tr>
        <th>
            @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
        </th>
        <th>
            First Name
        </th>
        <th>
            @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter=ViewBag.CurrentFilter })
        </th>
        <th></th>
    </tr>


@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstMidName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID })
        </td>
    </tr>
}

</table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

@Html.PagedListPager(Model, page => Url.Action("Index", 
    new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
The @model statement at the top of the page specifies that the view now gets a PagedList object instead of a Listobject.
The  using statement for PagedList.Mvc gives access to the MVC helper for the paging buttons. 
The code uses an overload of BeginForm that allows it to specify FormMethod.Get.
@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
The default BeginForm submits form data with a POST, which means that parameters are passed in the HTTP message body and not in the URL as query strings. When you specify HTTP GET, the form data is passed in the URL as query strings, which enables users to bookmark the URL. The W3C guidelines for the use of HTTP GET recommend that you should use GET when the action does not result in an update.
The text box is initialized with the current search string so when you click a new page you can see the current search string.
 Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
The column header links use the query string to pass the current search string to the controller so that the user can sort within filter results:
 @Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
The current page and total number of pages are displayed.
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
If there are no pages to display, "Page 0 of 0" is shown. (In that case the page number is greater than the page count because Model.PageNumber is 1, and Model.PageCount is 0.)
The paging buttons are displayed by the PagedListPager helper:
@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )
The PagedListPager helper provides a number of options that you can customize, including URLs and styling.  For more information, see TroyGoode  / PagedList on the GitHub site.
Run the page.
Click the paging links in different sort orders to make sure paging works. Then enter a search string and try paging again to verify that paging also works correctly with sorting and filtering.

Search This Blog

Arsip Blog

Powered by Blogger.

Recent

Comment

Author Info

Like This Theme

Popular Posts

Video Of Day

Sponsor

Most Popular