milosev.com
  • Home
    • List all categories
    • Sitemap
  • Downloads
    • WebSphere
    • Hitachi902
    • Hospital
    • Kryptonite
    • OCR
    • APK
  • About me
    • Gallery
    • Curriculum vitae
      • Resume
      • Lebenslauf
    • Social networks
      • Facebook
      • Twitter
      • LinkedIn
      • Xing
      • GitHub
      • Google Maps
      • Sports tracker
    • Adventures planning
  1. You are here:  
  2. Home
  3. ASP.NET

Special character in Razor

Details
Written by: Stanko Milosev
Category: Razor
Published: 12 November 2012
Last Updated: 30 November -0001
Hits: 3711

@:(@Model.SubType)

 

If I want brackets

WebApi and jQuery "lazy load"

Details
Written by: Stanko Milosev
Category: WebApi
Published: 17 November 2014
Last Updated: 06 April 2022
Hits: 5805

This page helped me to write this article. Idea was to write one my hobby project where I will display data from mySql database where I am keeping Serbian Real Estates collected from different agencies (at this moment two).

This article will have two parts, one is for creating web api, and second one is jQuery part (lazy load, filling screen, load more data on resize event)

Start new project, choose ASP.NET MVC 4 Web Application, and call it for example RealEstateWebClient:

Choose web api:

 Since this project is for Serbian Real Estates, my model looks like this:

  public class RealEstateModel
  {
    public int Id { get; set; }
    public string Company { get; set; }
    public string City { get; set; }
    public string Location { get; set; }
    public string Type { get; set; }
    public int SquareMeters { get; set; }
    public float Price { get; set; }
    public string Link { get; set; }
    public int Page { get; set; }
    public int Active { get; set; }
    public string UpdateTime { get; set; }
    public string UpdateDate { get; set; }
    public string InsertTime { get; set; }
    public string InsertDate { get; set; }
  }

Now we can add controller. Right click on "Controllers" node in Solution Explorer:

Choose "Empty API controller", and call it RealEstatesController for example:

My controller looks something like:

using System.Web.Http;

namespace RealEstateWebClient.Controllers
{
  using System;
  using System.Collections.Generic;

  using MySql.Data.MySqlClient;

  using RealEstateWebClient.Models;

  public class RealEstatesController : ApiController
    {

      public IEnumerable GetAllRealEstates([FromUri] int from, int to)
      {
        string MyConString = System.Configuration.ConfigurationManager.ConnectionStrings["MovieDBContext"].ConnectionString;

        string sql = "select * from RealEstate limit " + from + ", " + to;

        try
        {
          var connection = new MySqlConnection(MyConString);
          var cmdSel = new MySqlCommand(sql, connection);

          connection.Open();

          MySqlDataReader dataReader = cmdSel.ExecuteReader();

          List pom = new List();

          while (dataReader.Read())
          {
            pom.Add(new RealEstateModel
            {
              Id = int.Parse(dataReader["id"].ToString()),
              Company = dataReader["company"].ToString(),
              City = dataReader["city"].ToString(),
              Location = dataReader["location"].ToString(),
              Type = dataReader["type"].ToString(),
              SquareMeters = int.Parse(dataReader["squaremeters"].ToString()),
              Price = float.Parse(dataReader["price"].ToString()),
              Link = dataReader["link"].ToString(),
              Active = int.Parse(dataReader["active"].ToString()),
              UpdateTime = dataReader["updatetime"].ToString(),
              UpdateDate = dataReader["updatedate"].ToString(),
              InsertTime = dataReader["inserttime"].ToString(),
              InsertDate = dataReader["insertdate"].ToString()
            });
          }
          return pom;

        }
        catch (Exception e)
        {
          List error = new List();
          error.Add(
            new RealEstateModel
            {
              City = e.Message
            });
          return error;
        }


        return null;
      }

    }
}

Here notice how I call connectionString from Web.config:

string MyConString = System.Configuration.ConfigurationManager.ConnectionStrings["MovieDBContext"].ConnectionString;

Of course you have to install first MySQL, you can do that with NuGet, just write MySQL in the search box.

Then notice how parameters of my function look like:

public IEnumerable<RealEstateModel> GetAllRealEstates([FromUri] int from, int to)

that is because we will call our API with from - to parameters

---

Our controller is ready, now we need client part. Right click on project, click Add -> HTML page:

In my case I call it index.html, and it looks like this:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    
    <head>
        <title></title>
        <meta content="width=device-width, initial-scale=1" name="viewport">
        <script type="text/javascript" src="/jquery-2.1.1.js"></script>
        <script type="text/javascript" src="/index.js"></script>
        <link type="text/css" href="/index.css" rel="stylesheet">
    </head>
    <body>
    
        <table id="realEstatesTable">
 
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Company</th>
                    <th>City</th>
                    <th>Location</th>
                    <th>Type</th>
                    <th>SquareMeters</th>
                    <th>Price</th>
                    <th>Link</th>
                    <th>Page</th>
                    <th>Active</th>
                    <th>UpdateTime</th>
                    <th>UpdateDate</th>
                    <th>InsertTime</th>
                    <th>InsertDate</th>
                </tr>
            </thead>
            
            <tbody>            
            </tbody>

        </table>

    </body>

</html>

Then css will look like I already described here, and now comes jQuery.

First we will create function to load data:

function loadData(from, to) {
	uri = 'api/Realestates/?from=' + from + '&to=' + to;
	$.getJSON(uri)
		.done(function (data) {
			from = from + 10;
			fromGlobal = from;
			
			$.each(data, function (key, item) {

				$('#realEstatesTable > tbody:last').append(
					'<tr>' +
						'<td>' + item.Id + '</td>' +
						'<td>' + item.Company + '</td>' +
						'<td>' + item.City + '</td>' +
						'<td>' + item.Location + '</td>' +
						'<td>' + item.Type + '</td>' +
						'<td>' + item.SquareMeters + '</td>' +
						'<td>' + item.Price + '</td>' +
						'<td> <a href="' + item.Link + '" target=_blank>' + item.Link + '</td>' +
						'<td>' + item.Page + '</td>' +
						'<td>' + item.Active + '</td>' +
						'<td>' + item.UpdateTime + '</td>' +
						'<td>' + item.UpdateDate + '</td>' +
						'<td>' + item.InsertTime + '</td>' +
						'<td>' + item.InsertDate + '</td>' +
					'</tr>'
				);
			});
			if ($("#realEstatesTable").height() < $(window).height()) {
				loadData(from, to);
			}
		});

};

Here notice how my URI variable looks like:

uri = 'api/Realestates/?from=' + from + '&to=' + to;

API is called with big "R" and with "s" on the end for unknown reason... I guess because I named controller as RealEstatesController

Then notice in done method of getJson recursive call:

if ($("#realEstatesTable").height() < $(window).height()) {
  loadData(from, to);
}

With condition:

$("#realEstatesTable").height() < $(window).height()

I am checking if height of table (mount of loaded data) is less then height of the screen, if table height is smaller - load data, otherwise don't load it any more.

Then load data if user scrolled to the bottom of page:

$(window).scroll(function () { 
  if ($(window).scrollTop() + $(window).height() == $(document).height())
  {
    loadData(fromGlobal, numberOfItems);
  }
});

Here notice condition:

if ($(window).scrollTop() + $(window).height() == $(document).height())

Also, if user, for example, had browser in restored mode (not maximized), then we need to load data again if the screen is not filled:

$(window).resize(function () {
	if ($("#realEstatesTable").height() < $(window).height()) {
		loadData(fromGlobal, numberOfItems);
	}
});

Example you can download from here. Also here you can see live demo, but I am not sure for how long will I keep it...

ProgressBar using SignalR

Details
Written by: Stanko Milosev
Category: Core
Published: 14 March 2021
Last Updated: 06 April 2022
Hits: 573
In order to write this article, I was using this web site.

First I started new ASP.NET Core Empty project with Target Framework 5.0:

Then using nuget I installed Microsoft.AspNetCore.SignalR.Common:

I have added new folder "Hubs", where I added new class ProgressHub which is inherited from Hub:

using System.Threading;
using Microsoft.AspNetCore.SignalR;

namespace SignalRProgressBar.Hubs
{
  public class ProgressHub : Hub
  {
    public string msg = "Initializing and Preparing...";
    public int count = 100;

    public void CallLongOperation()
    {
      for (int x = 0; x <= count; x++)
      {

        // delay the process to see things clearly
        Thread.Sleep(100);

        if (x == 20)
          msg = "Loading Application Settings...";

        else if (x == 40)
          msg = "Applying Application Settings...";

        else if (x == 60)
          msg = "Loading User Settings...";

        else if (x == 80)
          msg = "Applying User Settings...";

        else if (x == 100)
          msg = "Process Completed!...";

        string myMessage = string.Format(msg + " {0}% of {1}%", x, count);
        Clients.All.SendAsync("ReceiveMessage", myMessage);
      }
    }
  }
}
In Startup.cs in the method ConfigureServices I added SignalR:
public void ConfigureServices(IServiceCollection services)
{
  services.AddSignalR();
}
In EndPoints I added Hub:
app.UseEndpoints(endpoints =>
{
	endpoints.MapHub<ProgressHub>("/progressHub");
});
Then I added wwwroot folder, and support for static files as I already explained here

After that I added index.html page in wwwroot folder, and I added Signalr JavaScript using client library:

As a search I wrote signalR and I have choosen aspnet-signalr:

I have added js library to html

<script defer src="aspnet-signalr/signalr.min.js"></script>
In folder js I have added my Javascript file, which look like this:
var connection = new signalR.HubConnectionBuilder().withUrl("../progressHub").build();
connection.start().then(function () {
    connection.invoke("CallLongOperation").catch(function (err) {
        return console.error(err.toString());
    });
});

connection.on("ReceiveMessage", function (message) {
    document.getElementById('progressbar').value = document.getElementById('progressbar').value + 1; 
    document.getElementById('progressbarText').innerText = message; 
});

My html looks like this:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script defer src="aspnet-signalr/signalr.min.js"></script>
    <script defer src="js/progress.js"></script>
</head>
<body>
    <div style="width: 30%; margin: 0 auto;">

        <label id="progressbarText" style="font-family: Tahoma; font-size: 0.9em; color: darkgray; margin-top: 230px; padding-bottom: 5px; display:inline-block" for="progressbar">
            Initializing and Preparing...
        </label>
        <br />
        <progress id="progressbar" value="1" max="100"></progress>
    </div>
</body>
</html>
Notice line in controller:
Clients.All.SendAsync("ReceiveMessage", myMessage);
and line in Javascript:
connection.on("ReceiveMessage", function (message) {
    document.getElementById('progressbar').value = document.getElementById('progressbar').value + 1; 
    document.getElementById('progressbarText').innerText = message; 
});
This is how SignalR communicates with client and server using WebSocket. Method name on both sides has to be the same.

Example download from here

Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'

Details
Written by: Stanko Milosev
Category: Core
Published: 09 January 2021
Last Updated: 09 November 2021
Hits: 823
Here I gave one example how my Startup.cs looks like, but with Asp.NET Core 3.0 Microsoft change it, you can read about it here

Here is my new Startup.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Radius
{
  public class Startup
  {
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddControllers();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if (env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
      }

      app.UseHttpsRedirection();
      app.UseDefaultFiles();
      app.UseStaticFiles();
      app.UseRouting();
      app.UseCors();

      app.UseEndpoints(endpoints =>
      {
        endpoints.MapControllers();
      });
    }
  }
}

  1. jQuery JSON error handling
  2. jQuery "POST" method
  3. Start empty Asp.Net core project
  4. wwwroot

Subcategories

MVC 4

MVC 3

WebApi

Core

Page 9 of 11

  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11