Reset Entity Framework Migrations and Drop Database

Remove all files from the migrations folder.

dotnet-ef database drop -f -v
dotnet-ef migrations add Initial
dotnet-ef database update

Do that only if you don’t care about your current persisted data

Without Dropping Database

The Issue: You have mucked up your migrations and you would like to reset it without deleting your existing tables.

The Problem: You can’t reset migrations with existing tables in the database as EF wants to create the tables from scratch.

What to do:

  1. Delete existing migrations from Migrations_History table.
  2. Delete existing migrations from the Migrations Folder.
  3. Run dotnet-ef migrations add Initial. This will create a migration in your Migration folder that includes creating the tables (but it will not run it so it will not error out.)
  4. You now need to create the initial row in the MigrationHistory table so EF has a snapshot of the current state. EF will do this if you apply a migration. However, you can’t apply the migration that you just made as the tables already exist in your database. So go into the Migration and comment out all the code inside the “Up” method.
  5. Now run dotnet-ef database update. It will apply the Migration (while not actually changing the database) and create a snapshot row in MigrationHistory.

You have now reset your migrations and may continue with normal migrations.

References
https://stackoverflow.com/questions/11679385/reset-entity-framework-migrations

Installing .NET 6 on Ubuntu 22.04

sudo apt update && sudo apt install -y wget
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo touch /etc/apt/preferences
sudo nano /etc/apt/preferences

Paste :

Package: *
Pin: origin "packages.microsoft.com"
Pin-Priority: 1001
sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-6.0
dotnet --info

References
https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#2204
https://github.com/dotnet/core/issues/7699

Redirect to Login Page if User is not Logged In in ASP.NET Blazor

@inject NavigationManager NavigationManager

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
                <NotAuthorized>
                    @{
                        NavigationManager.NavigateTo("Login",true);
                    }
                </NotAuthorized>
            </AuthorizeRouteView>
            <FocusOnNavigate RouteData="@routeData" Selector="h1"/>
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

MainLayout.razor

@code{ 

    [CascadingParameter] protected Task<AuthenticationState> AuthStat { get; set; }

    protected async override Task OnInitializedAsync()
    {
        base.OnInitialized();
        var user = (await AuthStat).User;
        if(!user.Identity.IsAuthenticated)
        {
            NavigationManager.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(NavigationManager.Uri)}");
        }
    }
}

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-5.0#customize-unauthorized-content-with-the-router-component
https://stackoverflow.com/questions/60840986/blazor-redirect-to-login-if-user-is-not-authenticated

Force Page Reload or Refresh in Blazor

A page is reloaded/refreshed automatically at a specified interval using “NavigationManager” in OnAfterRender() method. Here the NavigateTo(“url”, forceLoad: true) method, is used to force load the browser based on the URI.

@inject NavigationManager uriHelper;

@using System.Threading;

<h1>Hello, world!</h1>

Welcome to your new app.

@code {
    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            var timer = new Timer(new TimerCallback(_ =>
            {
                uriHelper.NavigateTo(uriHelper.Uri, forceLoad: true);
            }), null, 2000, 2000);
        }
    }
}

References
https://www.syncfusion.com/faq/blazor/general/how-do-i-force-page-reload-or-refresh-in-blazor

Dispose Components in Blazor

Synchronous IDisposable

@implements IDisposable

...

@code {
    ...

    public void Dispose()
    {
        obj?.Dispose();
    }
}

Asynchronous IAsyncDisposable

@implements IAsyncDisposable

...

@code {
    ...

    public async ValueTask DisposeAsync()
    {
        if (obj is not null)
        {
            await obj.DisposeAsync();
        }
    }
}

Event handlers

Always unsubscribe event handlers from .NET events.

@implements IDisposable

<EditForm EditContext="@editContext">
    ...
    <button type="submit" disabled="@formInvalid">Submit</button>
</EditForm>

@code {
    ...

    private EventHandler<FieldChangedEventArgs>? fieldChanged;

    protected override void OnInitialized()
    {
        editContext = new(model);

        fieldChanged = (_, __) =>
        {
            ...
        };

        editContext.OnFieldChanged += fieldChanged;
    }

    public void Dispose()
    {
        editContext.OnFieldChanged -= fieldChanged;
    }
}

References
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#synchronous-idisposable
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#asynchronous-iasyncdisposable
https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#event-handlers
https://www.syncfusion.com/faq/blazor/components/how-can-i-properly-dispose-a-component-in-blazor

Using SOAP requests with Postman

Entering your SOAP endpoint

  1. Open a new request tab in Postman and enter your SOAP endpoint URL in the address field.
  2. Select POST from the request method dropdown list.

As an example, use the following endpoint URL:

https://www.dataaccess.com/webservicesserver/NumberConversion.wso

Adding body data

  1. In the Body tab, select raw and choose XML from the dropdown list.
  2. Enter your XML in the text entry area.

If you want to test the number conversion SOAP API used in the last section, enter the following XML in the text entry area:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <NumberToWords xmlns="http://www.dataaccess.com/webservicesserver/">
      <ubiNum>500</ubiNum>
    </NumberToWords>
  </soap:Body>
</soap:Envelope>

Setting your request headers

When you select an XML body type, Postman automatically adds a content type header of application/xml. But depending on your service provider, you may need text/xml for some SOAP requests. Check with your SOAP service to determine which header is appropriate. If you need the text/xml header, you will need to override the default setting added by Postman.

If you are following along with the number conversion SOAP API example, you need to change the content type header to text/xml.

  1. Open the request Headers. If the auto-generated headers are hidden, select the notice to display them.
  2. Deselect the Content-Type header Postman added automatically.
  3. Add a new row with Content-Type in the Key field and text/xml in the Value field.
  4. Add a new row for a header with SOAPAction in the Key field and "#MethodName" in the Value field. (The quotes are required.) Without this header, the service will return 500.

References
https://learning.postman.com/docs/sending-requests/soap/making-soap-requests/

Call SOAP Services in .NET Core

First  add your Soap service to the project using “Add Web Reference…”

var binding = new BasicHttpBinding();
binding.ReceiveTimeout=TimeSpan.FromMinutes(10);
binding.MaxReceivedMessageSize=Int32.MaxValue;
var endpoint = new EndpointAddress(new Uri("http://server/PingService.svc"));
var soap = new SuppliersWSSoapClient(binding, endpoint);
var result = await soap.GetProductReportXMLAsync("username", "password", 90, "14010518", "14010518");
Console.WriteLine(result);

References
https://stackify.com/soap-net-core/
https://rider-support.jetbrains.com/hc/en-us/community/posts/360000408024-Referencing-a-WSDL-service