Category: .NET Core

From unstructured data to application

Imagine that you have this kind of texts:

Alpert of Metz – 11th-century – France – Medieval writers
Aimoin of Fleury – c. 960 – c. 1010 – France – Medieval writers
Amulo Lugdunensis (Archbishop of Lyon) – 9th-century – France – Medieval writers
Amulo Lugdunensis (Archbishop of Lyon) – 9th-century – France / Carolingian Empire – Medieval writers
Andrew of Fleury – 11th-century – France – Medieval writers
Angelomus of Luxeuil – 9th-century – Francia / France – Medieval writers

Vitsentzos or Vikentios Kornaros or Vincenzo Cornaro – c. 1553 – c. 1614 – Kingdom of Candia / Crete / Greece – Renaissance

Adrianus of Tyre – c. 113 – c. 193 – Greece / Roman Empire – Ancient & Classical writers

How transform this unstrcutured data to make an application that search like in the picture below ( just the R from CRUD )?

Detailing  the tools:

1.  Transforming data: Excel + VBA – to parse from the text the name, country / countries , years period  movement and generate insert  /stored procedurees call

2. Storing+ retrieving data: Sql Server – creating tables and stored procedures to insert / retrieving data

3. Acessing data: .NET Core – to make WebAPI to export as WebAPI HTTP endpoints t

4. Display data:

5. Deploy:

  • RedfHat OpenShift to deploy site
  • Azure to have sql server on the web

Hours or work ~ 20 . And hey, it works!

.NET Core SignalR Hub+ Angular Observable

TL;DR: Deliver all the table content continuously paginated to the browser with .NET Core and Angular


Long Description:

I was thinking that delivering paginating data is kind of lame. Why should I , for seeing the whole data, should keep pressing next page / or scrolling  down ? I understand that on the server it is necessary to do this – but on the client ?

And I was thinking – what about Observables in Angular  , combined with SignalR ? Those observables could obtain data every time – and SignalR is pushing cotinously, until it arrives at the end of the data.

Done with talking –  let’s show some code:

We have an Employee classs

public class Employee
    {
        public string Name { get; set; }
        public int Id { get; set; }

    }

code

and we are feeding with data in a DALEmployee

public class DalEmployee
    {
        public int FindCountEmployees(string name)
        {
            return ((name ?? "").Length + 1) * 10;
        }

        public async Task<Employee[]> FindEmployee(int pageNumber, int pageSize, string name)
        {
            await Task.Delay((pageNumber + 1) * 1000);
            var ret = new Employee[pageSize];
            int startNumber = (pageNumber - 1) * pageSize;
            for (int i = 0; i < pageSize; i++)
            {
                var e =new Employee();
                e.Id = startNumber + i;
                e.Name = e.Id + "employee ";
                ret[i] = e;
            }

            return ret;
        }
    }

We have SignalR that delivers continously the data via a Hub that is connected to an URL

//do not forget  services.AddSignalR().AddJsonProtocol()  ;
            app.UseSignalR(routes =>
            {
                routes.MapHub<MyHub>("/employees");
            })

and delivers all data continuously

 public class MyHub: Hub
    {
       
        public override async Task OnConnectedAsync()
        {
            Console.WriteLine("!!!!connected");
            await Task.Delay(1000);
        }
        public ChannelReader<Employee[]> GetEmps(string name)
        {
            var channel = Channel.CreateUnbounded<Employee[]>();
            _ = WriteItems(channel.Writer, name); //it not awaits!

            return channel.Reader;
        }

        private async Task WriteItems(ChannelWriter<Employee[]> writer, string name)
        {
            var dal = new DalEmployee();
            var nr = dal.FindCountEmployees(name);
            int nrPages = 10;
            for (int i = 0; i < nr / nrPages; i++)
            {
                var data = await dal.FindEmployee(i+1, nrPages, name);
                await writer.WriteAsync(data);
            }

            writer.TryComplete();            
        }

And this is all that is required on the .NET Core side

For the Angular Part

We have a hubconnectionbuilder that connect to the hub

export class MydataService {

  h:HubConnection;
  constructor(private http: HttpClient) { 
    this.h= new HubConnectionBuilder()
      .withUrl(environment.urlAPI + "/employees")
      .withHubProtocol(new JsonHubProtocol())
      //.withHubProtocol(new MessagePackHubProtocol())
      .build();
      window.alert('start');
    this.h.start()
    .catch((t) => window.alert(1));
  }
  
  
}

and a observable that returns the values



  public getAllEmpsStream(name:string): Observable<Employee[]>{
    
    const subject = new Subject<Employee[]>();
    this.h.stream<Employee[]>("GetEmps",name).subscribe(subject);
    return subject.asObservable();

  }

The code on the component is aggregating the values into an array

findEmployees(){
    this.load=true;
    this.service
      
      .getAllEmpsStream(this.nameEmp)
      //.getEmps(this.nameEmp)
      .pipe(finalize(() => this.load=false))
      .subscribe(it  => {
        
        //window.alert(it.length);
        this.emp.push(...it);

      });

  }

And that is all. All the values are returned page after page without the need of human intervention…

Angular , .NET Core, IIS Express and Windows Authentication

2 years ago I have written about .NET Core Windows Authentication :http://msprogrammer.serviciipeweb.ro/2016/09/26/asp-net-core-and-windows-authentication/ 

The idea was that for Windows authentication this is mandatory in Web.Config:

forwardWindowsAuthToken="true"

Now I want to show how to achieve the same in  IIS Express .NET Core as backend and Angular for front end

For .NET Core / IIS Express

1. Configure IISExpress : https://www.danesparza.net/2014/09/using-windows-authentication-with-iisexpress/ 

On short: find %userprofile%\documents\iisexpress\config\applicationhost.config  or %userprofile%\my documents\iisexpress\config\applicationhost.config  and put

<windowsAuthentication enabled="true">
    <providers>
        <add value="Negotiate" />
        <add value="NTLM" />
    </providers>
</windowsAuthentication>

2.  On your project: Put in launchSettings.json :

“windowsAuthentication”: true,
“anonymousAuthentication”: false,

3.  Optional: To verify add an Action that returns

(this.User?.Identity?.Name ?? "Not ad enabled")

For Angular

return this.http.get(url,{
withCredentials: true
});

4. ASP.NET Core 2.1
https://github.com/aspnet/Home/releases/tag/2.1.0

Windows authentication is not enabled after creating project with the Windows authentication option selected
When creating a template with Windows authentication, the settings to enable Windows authentication in launchSettings.json are not applied.
Workaround: Modify launchSettings.json as follows:

“windowsAuthentication”: true,
“anonymousAuthentication”: false,

.NET Core 2.0 WebAPI with .NET Framework 4.6( for COM interoperability)

The problem :

I want some .NET Core Web API in Kestrel mode that have access to some COM components ( such as Word.Application )

Solution:

( Theory : in order to have dll’s that works in .NET Framework application and in .NET Core, you should have .NET Standard 2.0 along .NET Framework 4.6.1 and .NET Core 2.0 ( see https://docs.microsoft.com/en-us/dotnet/standard/net-standard )

Step 1 :  create the .NET 4.6.1 dll that access the COM object

Step 2: create the .NET WEB API application. Edit the .csproj file and replace the target framework with

<PropertyGroup>
<TargetFrameworks>net461</TargetFrameworks>
</PropertyGroup>

Save the .csproj

Step 3 ; Remove the Microsoft.AspNetCore.All metapackage and install yours . For me it was enough to install those 3:

install-package microsoft.aspnetcore.mvc

install-package Microsoft.AspNetCore

install-package Microsoft.AspNetCore.Diagnostics

( you may want to add CORS and/or others)

Step 4: run

dotnet restore

and

dotnet build

Step 5: Reference the dll that you have created in the Step 1  and reference from a controller action. Build again.

Step 6; Check that you have now an exe file in build / debug / net461. You can run this exe / deploy in IIS /

Tiny Types–documentation–part 4

This is a series

  1. http://msprogrammer.serviciipeweb.ro/2018/03/12/tiny-types-in-cpart-1/
  2. http://msprogrammer.serviciipeweb.ro/2018/03/19/tiny-types-part-2adding-iequatable/
  3. http://msprogrammer.serviciipeweb.ro/2018/03/26/tinytypesadding-equality-operatorpart-3/

  4. http://msprogrammer.serviciipeweb.ro/2018/04/02/tiny-typesdocumentationpart-4/

tiny types in C#

Build Status

Tiny types is a NuGET dll , https://www.nuget.org/packages/TinyTypesObjects/

Also , you can find the construction here: http://msprogrammer.serviciipeweb.ro/category/tinytypes/

The documentation is copied shameless from https://github.com/jan-molak/tiny-types

Installation

To install the module from nuget : … Install-Package TinyTypesObjects …

Defining Tiny Types

An int on its own is just a scalar with no meaning. With an object, even a small one, you are giving both the compiler and the programmer additional information about what the value is and why it is being used.

Jeff Bay, Object Calisthenics

Single-value types

To define a single-value TinyType – extend from TinyType<T>() :

If you want operator ==, please use TinyTypeOf or TinyTypeOfString

using TinyTypesObjects;

public class Age : TinyTypeOf<int>
    {
        public Age(int nr) : base(nr)
        {

        }
    }
public class FirstName : TinyTypeOfString
    {
        public FirstName(string str) : base(str)
        {

        }
    }

Every tiny type defined this way has a get property value of type T, which you can use to access the wrapped primitive value. For example:

var firstName = new FirstName("Jan");

Assert.AreEqual(firstName.value , "Jan");
        
Converting from / to original values

There are defined conversions between type T and the class

public void TestConvert()
        {
            string s = "http://msprogrammer.serviciipeweb.ro";
            TinyTypeOfString tt = s;
            Assert.AreEqual(s, (string)tt);

            int nr = 7;
            TinyTypeOf<int> tt1 = nr;

            Assert.AreEqual(nr, (int)tt1);
        }
        

so the following code should work for the class with constructor string

class TestConstructor
    {
        public TestConstructor(string firstName)
        {
            FirstName = firstName;
        }

        public string FirstName { get; }
    }
[TestMethod]
        public void TestConstructor()
        {
            var firstName = new FirstName("Jan");
            TestConstructor tc = new TestConstructor(firstName);
            Assert.AreEqual(tc.FirstName, "Jan");
        }
Equals or ==

Each tiny type object has an equals method, which you can use to compare it by value:

int nr = 7;
            TinyTypeOf<int> tt1 = nr;
            TinyTypeOf<int> tt2 = nr;

            Assert.AreEqual(tt1, tt2);
            Assert.IsTrue(tt1 == tt2);
Links:

GitHub: https://github.com/ignatandrei/tinyTypes

Blog About: http://msprogrammer.serviciipeweb.ro/category/tinytypes/

NuGet: https://www.nuget.org/packages/TinyTypesObjects/

TinyTypes–adding equality operator–part 3

This is a series

  1. http://msprogrammer.serviciipeweb.ro/2018/03/12/tiny-types-in-cpart-1/
  2. http://msprogrammer.serviciipeweb.ro/2018/03/19/tiny-types-part-2adding-iequatable/
  3. http://msprogrammer.serviciipeweb.ro/2018/03/26/tinytypesadding-equality-operatorpart-3/

  4. http://msprogrammer.serviciipeweb.ro/2018/04/02/tiny-typesdocumentationpart-4/

Now we have come to the interesting part – the equality operator.

We have already operator equals, but not ==

 [TestMethod]
        public void TestSimpleIntOperatorEqual()
        {
            int nr = 7;
            TinyType<int> tt1 = nr;
            TinyType<int> tt2 = nr;

            Assert.AreEqual(tt1, tt2);
            Assert.IsFalse(tt1 == tt2);
        }
        [TestMethod]
        public void TestSimpleStringOperatorEqual()
        {
            string s = "http://msprogrammer.serviciipeweb.ro";
            TinyType<string> tt1 = s;
            TinyType<string> tt2 = s;

            Assert.AreEqual(tt1, tt2);
            Assert.IsFalse(tt1 == tt2);
        }

Because we primary want this TinyTypes for structs( int, double, bool, and so on) we can define a new class

For this we could implement operator  ==  by using the Equals operator ( because we KNOW that a struct cannot be null)

public class TinyTypeOf<T> : TinyType<T>
        where T:struct
    {
        public TinyTypeOf(T tDef) : base(tDef)
        {
        }

       
        public static bool operator ==(TinyTypeOf<T> lhs, TinyTypeOf<T> rhs)
        {
            if(lhs is null)
            {
                return rhs is null;
            }
            return lhs.t.Equals(rhs.t);
        }

        public static bool operator !=(TinyTypeOf<T> lhs, TinyTypeOf<T> rhs)
        {
            return !(lhs==rhs);
        }

CODE FOR NEW CLASS

Also, because the string is not a struct, but a class, we need for String also:

public class TinyTypeOfString : TinyType<string>

And the tests are

using Microsoft.VisualStudio.TestTools.UnitTesting;
using TinyTypesObjects;

namespace TinyTypesTest
{
    [TestClass]
    public class TestTinyTypeOperatorEqual
    {
        [TestMethod]
        public void TestSimpleIntOperatorEqual()
        {
            int nr = 7;
            TinyType<int> tt1 = nr;
            TinyType<int> tt2 = nr;

            Assert.AreEqual(tt1, tt2);
            Assert.IsFalse(tt1 == tt2);
        }
        [TestMethod]
        public void TestSimpleStringOperatorEqual()
        {
            string s = "http://msprogrammer.serviciipeweb.ro";
            TinyType<string> tt1 = s;
            TinyType<string> tt2 = s;

            Assert.AreEqual(tt1, tt2);
            Assert.IsFalse(tt1 == tt2);
        }
        [TestMethod]
        public void TestSimpleStringOperatorEqualWorks()
        {
            string s = "http://msprogrammer.serviciipeweb.ro";

            TinyTypeOfString tt1 = s;
            TinyTypeOfString tt2 = s;

            Assert.AreEqual(tt1, tt2);
            Assert.IsTrue(tt1 == tt2);
        }

        [TestMethod]
        public void TestSimpleIntOperatorEqualWorks()
        {
            int nr = 7;
            TinyTypeOf<int> tt1 = nr;
            TinyTypeOf<int> tt2 = nr;

            Assert.AreEqual(tt1, tt2);
            Assert.IsTrue(tt1 == tt2);
        }
        [TestMethod]
        public void TestSimpleIntNrOperatorEqualWorks()
        {
            int nr = 7;
            TinyType<int> tt1 = nr;
            
            Assert.AreEqual(tt1, nr);
            Assert.IsTrue(tt1 == nr);
        }
    }
}

Tiny Types part 2–adding IEquatable

This is a series

  1. http://msprogrammer.serviciipeweb.ro/2018/03/12/tiny-types-in-cpart-1/
  2. http://msprogrammer.serviciipeweb.ro/2018/03/19/tiny-types-part-2adding-iequatable/
  3. http://msprogrammer.serviciipeweb.ro/2018/03/26/tinytypesadding-equality-operatorpart-3/

  4. http://msprogrammer.serviciipeweb.ro/2018/04/02/tiny-typesdocumentationpart-4/

As always, the bigger problem is adding equality. The Tiny Type should be equal with the inner value – and with the other type with the same value. And, in C#, when you implement equality , there is a whole theory – see https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx .

So the code to define equality is 60 lines long just for defining equality for

public class TinyType<T>:IEquatable<T>, IEquatable<TinyType<T>>

   

But this is not all. This is the code for testing equality

using Microsoft.VisualStudio.TestTools.UnitTesting;
using TinyTypesObjects;

namespace TinyTypesTest
{
    [TestClass]
    public class TestTinyTypeEquals
    {
        [TestMethod]
        public void TestSimpleStringEquals()
        {
            #region arrange
            string s = "http://msprogrammer.serviciipeweb.ro";
            #endregion
            #region act
            TinyType<string> tt1 = s;
            TinyType<string> tt2 = s;
            #endregion
            #region assert
            Assert.IsTrue(tt1.Equals(tt2));
            Assert.AreEqual(tt1, tt2);
            Assert.AreEqual<string>(tt1, tt2);
            Assert.AreEqual<TinyType<string>>(tt1, tt2);
            Assert.AreEqual<string>(s, tt2);
            #endregion
        }
        [TestMethod]
        public void TestSimpleStringWithNull()
        {
            #region arrange
            string s = null;
            #endregion
            #region act
            TinyType<string> tt1 = s;
            TinyType<string> tt2 = null;
            #endregion
            #region assert
            Assert.IsFalse(tt1.Equals(tt2));
            Assert.AreNotEqual(tt1, tt2);
            Assert.AreEqual<string>(tt1, tt2);
            Assert.AreNotEqual<TinyType<string>>(tt1, tt2);
            Assert.AreEqual<string>(s, tt2);
            #endregion
        }
        [TestMethod]
        public void TestSimpleStringNull()
        {
            #region arrange
            string s = null;
            #endregion
            #region act
            TinyType<string> tt1 = s;
            TinyType<string> tt2 = s;
            #endregion
            #region assert
            Assert.IsTrue(tt1.Equals(tt2));
            Assert.AreEqual(tt1, tt2);
            Assert.AreEqual<string>(tt1, tt2);
            Assert.AreEqual<TinyType<string>>(tt1, tt2);
            Assert.AreEqual<string>(s, tt2);
            #endregion
        }
        [TestMethod]
        public void TestSimpleIntEquals()
        {
            #region arrange
            int s = 1;
            #endregion
            #region act
            TinyType<int> tt1 = s;
            TinyType<int> tt2 = s;
            #endregion
            #region assert
            Assert.IsTrue(tt1.Equals(tt2));
            Assert.AreEqual(tt1, tt2);
            Assert.AreEqual<int>(tt1, tt2);
            Assert.AreEqual<TinyType<int>>(tt1, tt2);
            Assert.AreEqual<int>(s, tt2);
            
            #endregion
        }

    }
}

Tiny types in C#–part 1

This is a series

  1. http://msprogrammer.serviciipeweb.ro/2018/03/12/tiny-types-in-cpart-1/
  2. http://msprogrammer.serviciipeweb.ro/2018/03/19/tiny-types-part-2adding-iequatable/
  3. http://msprogrammer.serviciipeweb.ro/2018/03/26/tinytypesadding-equality-operatorpart-3/

  4. http://msprogrammer.serviciipeweb.ro/2018/04/02/tiny-typesdocumentationpart-4/

I have read about tiny types in Javascript  – at https://darrenhobbs.com/2007/04/11/tiny-types/ and at https://janmolak.com/tiny-types-in-typescript-4680177f026e . It was an interesting idea – especially in this world of REST API .

I decided to make the same on C# – so here it is: https://github.com/ignatandrei/tinyTypes and at https://www.nuget.org/packages/TinyTypesObjects .

For the moment , the tests are minimal – just to get working :

using Microsoft.VisualStudio.TestTools.UnitTesting;
using TinyTypesObjects;

namespace TinyTypesTest
{
    [TestClass]
    public class TestTinyType
    {
        [TestMethod]
        public void TestConvert()
        {
            string s = "http://msprogrammer.serviciipeweb.ro";
            TinyType<string> tt = s;
            Assert.AreEqual(s, (string)tt);
        }
        [TestMethod]
        public void TestBehaviour()
        {
            #region arrange + act
            Author a1 = new Author("andrei", "ignat");
            Author a2 = new Author(
                new FirstName("andrei"),new LastName( "ignat"));

            Author a3 = new Author(firstName:"andrei",lastName: "ignat");
            #endregion
            #region assert
            Assert.AreEqual(a2.FullName(), a3.FullName());
            Assert.AreEqual(a2.FullName(), a3.FullName());
            #endregion

        }
    }
}

Next time , I will do IComparable / Iequatable /Equals and others

Country Tag Helper–part 5

Now the Country Tag Helper supports .NET Standard 2.0 . This means that support .NET Core 2.0 .

Also, I have made a NuGET package in order to install on every .NET Core 2.0 application with explanations: https://www.nuget.org/packages/CountryTagHelper 

The only trouble here was to add references and make documentation in VS2017 about package ( see https://docs.microsoft.com/en-us/nuget/guides/create-net-standard-packages-vs2017 )

As I said , the source is at GitHub https://github.com/ignatandrei/CountryTagHelper and demo at http://countrytaghelper.apphb.com/

What remains to be done:

localized
add select2 with image flags   

provider / dependency injection for FromIP
readme.md / wiki on github

Country Tag Helper–part 4

 

Now I want to see somewhere in order to prove it Ii s right. I choose https://appharbor.com/ because it is free – and can not beat free for free source.

I made github integration and modify the .csproj file accordingly to https://support.appharbor.com/discussions/problems/90387-is-net-core-supported-yet 

The result is at http://countrytaghelper.apphb.com/ 

Also , I have to modify the code source to get the ip of the user :

string GetUserIP(ViewContext vc)
        {
            StringValues headerFwd;
            if (ViewContext.HttpContext?.Request?.Headers?.TryGetValue("X-Forwarded-For", out headerFwd) ?? false)
            {
                string rawValues = headerFwd.ToString();
                if (!string.IsNullOrWhiteSpace(rawValues))
                {
                    return rawValues.Split(',')[0];
                }

            }
            return ViewContext.HttpContext?.Connection?.RemoteIpAddress?.ToString();

        }

where ViewContext is

 [ViewContext]
        public ViewContext ViewContext { get; set; }

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.