Search This Blog

Monday, 7 October 2024

Azure Web Jobs

  • Run background tasks with WebJobs in Azure App Service
  • WebJobs for Windows container, Linux code, and Linux container is in preview. WebJobs for Windows code is generally available and not in preview.
  • Continuous and triggered WebJobs

Friday, 2 February 2024

What is the difference between POST, PUT AND PATCH in HTTP?

 PUT is used for creating or replacing resources, POST is used for creating or appending data to resources, and PATCH is used for partially updating existing resources


Features of the PUT method

The PUT method has the following characteristics:


The request URI is used as the resource identifier

The request body contains the entire updated resource

It has idempotency - repeating the same request yields the same result

If the existing resource does not exist, a new one will be created

If an existing resource exists, it will be completely replaced with the contents of the body


// PUT example  

PUT /Studeant/1

{

  "id": 1,

  "name": "Student",

  "age": 18

}



Features of the POST method

The URI indicates the location of the resource that will handle the request

The request body contains data for creating the new resource

It does not have idempotency - repeating the same request may produce different results

Often used to create new resources

An empty request body may still be valid


// POST example

POST /users  

{

  "name": "Student",

  "age": 21

}

Features of the PATCH method

The PATCH method applies partial modifications to entities of a resource. 

The PATCH method executes the requested changes atomically. 

It means that if the server can't satisfy all the requested changes, 

it doesn't modify the target entity

// PATCH example  

PATCH /Studeant/1

{

  "id": 1,

  "name": "Student",

  "age": 18

}


Action

PUT

PATCH

Request body

Yes

Yes

Response with body Content

No

Yes

Safe

No

No

IDEMPOTENT

Yes

No


Monday, 22 January 2024

N+1 Problem in Entity Framework

 What is Select N+1 Problem?

ORMs can help you to address the impedance mismatch between relational databases and object oriented models and by that make your life simpler. But not knowing about some of their pitfalls can decrease your performance dramatically. One of those pitfalls is the select N+1 problem. This problem is being caused mainly because most of the ORMs out there are enabling lazy loading behavior by default. When we have a parent-children relation, the problem can raise its ugly head. The problem is happening when we are executing a single query and then N following queries (N is the number of parent entities) in order to query for something. As you can expect, doing N+1 queries instead of a single one will flood your database with queries that we can and should avoid. This is very unacceptable.       

 
How to Avoid the N+1 Problem in Entity Framework?

One of the main solutions to the select N+1 problem in Entity Framework is to use the Include method. The Include method is making an eager load for the children that you indicate to it. You give the method a path of all the children you like to load in the query (as long as you have a relation between the entities) and one query will be generated to bring back all the relevant entities. This isn’t a bullet proof solution! There are serious implications that you should understand when you use the Include method. The main implication is that it is doing a join between all the tables that you want to return and the data is retrieved in a flatten manner in order to materialize all the entities from it. Also the materialization process when having a lot of included entities can cause a downgrade of performance. So you will have to weigh the balance between using Include or lazy loading. 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

Tuesday, 16 January 2024

Web vulnerabilities and options for .net core API 3.1


There are four common vulnerabilities in web applications. Be aware of these risks, master features of the technology stacks that help you secure your apps and prevent security breaches is necessary.

  • Cross-site scripting attacks (XSS). Core tip: All data received from clients are untrusted. When you want to output the content, keep an eye on any possibility of including any executable script.

  • SQL injection attacks. Core tip: The concatenation of raw SQL command text with parameters or parts from an untrusted source should be seriously validated.

  • Cross-Site Request Forgery (CSRF), also known as one-click attack or session riding. Core tip: Two websites are browsed, one log in and another is malicious. Submit requests from the malicious website attached with your valid cookie authentication is the common way to attack.

  • Open redirect attacks, also known as "Unvalidated Redirects and Forwards". Core tip: If the login redirects with an unchecked query parameter, users from a fake link could be redirected to a similar login page and causing their credential data leaks.



.Net core web API 3.1 is the latest framework of Microsoft to develop REST API.

Use cookie authentication without ASP.NET Core Identity (https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1.) is easy and quick. HttpOnly cookies will be used by default. Httponly flag is very important to avoid any XSS attack and has other benefits (https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies). Cookie solution relies on client's cookie support.


Another common authentication solution for API is to use JWT (JSON Web Token, https://jwt.io). https://jasonwatmore.com/post/2019/10/11/aspnet-core-3-jwt-authentication-tutorial-with-example-api. In start.cs:

// This method gets called by the runtime. Use this method to add services to the container.

        public void ConfigureServices(IServiceCollection services)

        {

            if (Settings.Cors?.Length > 0)

            {

                services.AddCors(options =>

                {

                    options.AddPolicy("platform",

                    builder =>

                    {

                        builder.WithOrigins(Settings.Cors)

                            // Support https://*.domain.com

                            .SetIsOriginAllowedToAllowWildcardSubdomains()


                            // JWT is not a cookie solution, disable it without allow credential

                            // .AllowCredentials()

                            .DisallowCredentials()


                            

                            // Without it will popup error: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response

                            .AllowAnyHeader()


                            // Web Verbs like GET, POST, default enabled

                            .AllowAnyMethod();

                    });

                });

            }


           

           

            services.Configure<BrotliCompressionProviderOptions>(options =>

            {

                options.Level = CompressionLevel.Optimal;

            });


            services.AddResponseCompression(options =>

            {

                options.EnableForHttps = true;

                options.Providers.Add<BrotliCompressionProvider>();

            });


            // Configure JWT authentication

            // https://jwt.io/

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

                .AddJwtBearer(options =>

                {

                    // Is SSL only

                    options.RequireHttpsMetadata = Settings.SSL;


                    // Save token, True means tokens are cached in the server for validation

                    options.SaveToken = false;


                    // Token validation parameters

                    options.TokenValidationParameters = new TokenValidationParameters()

                    {

                        ValidateIssuerSigningKey = true,

                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(app.Configuration.SymmetricKey)),

                        ValidateIssuer = false,

                        ValidateAudience = false

                    };

                });

        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

        {

            if (env.IsDevelopment())

            {

                app.UseDeveloperExceptionPage();

            }


            // Enable HTTPS redirect

            if (Settings.SSL)

                app.UseHttpsRedirection();


            app.UseRouting();


            // Enable CORS (Cross-Origin Requests)

            // The call to UseCors must be placed after UseRouting, but before UseAuthorization

            if (Settings.Cors?.Length > 0)

            {

                app.UseCors("platform");

            }


            app.UseAuthentication();

            app.UseAuthorization();


            // Enable compression

            app.UseResponseCompression();


            app.UseEndpoints(endpoints =>

            {

                // Apply authentication by default

                endpoints.MapControllers().RequireAuthorization();

            });

        }


After the user log in successfully, add the codes below to generate the token:

        /// <summary>

        /// Login for authentication

        /// </summary>

        /// <param name="model">Data model</param>

        /// <returns>Result</returns>

        [AllowAnonymous]

        [HttpPost("Login")]

        public async Task Login([FromBody]LoginModel model)

        {

            // Act

            var result = await Service.LoginAsync(model);


            if (result.OK)

            {

                // Logined user id

                var userId = result.Data.Get("token_user_id", 0);


                // User role

                var role = result.Data.Get("role", UserRole.User);


                // Token handler

                var tokenHandler = new JwtSecurityTokenHandler();


                // Key bytes

                var key = Encoding.ASCII.GetBytes(App.Configuration.SymmetricKey);


                // Token descriptor

                var tokenDescriptor = new SecurityTokenDescriptor

                {

                    Subject = new ClaimsIdentity(new Claim[]

                    {

                        new Claim(ClaimTypes.Name, userId.ToString()),

                        new Claim(ClaimTypes.Role, role.ToString().ToLower()),

                    }),

                    // Suggest to refresh it at 5 minutes interval, two times to update

                    Expires = DateTime.UtcNow.AddMinutes(12),

                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)

                };


                // Hold the token value and then return to client

                var token = tokenHandler.CreateToken(tokenDescriptor);

                result.Data["authorization"] = tokenHandler.WriteToken(token);

            }


            // Output

            await ResultContentAsync(result);

        }


Because the token is stateless, Web APIs are always facing a replay attack, also known as playback attack. bearer.SaveToken = true means you could access it through await HttpContext.GetTokenAsync("access_token") for any outgoing request. Add necessary validation logic in the database side is helpful. A short-lived, strict authentication with rate-limiting policy token solution will make the project much stronger.





Monday, 15 January 2024

.Net Core Middleware

app.Use vs app.Run in ASP.NET Core middleware ?

Middleware are executed in the same order in which they are added. The difference is, middleware defined using app.Use may call next middleware component in the pipeline. On the other hand, middlware defined using app.Run will never call subsequent middleware. 

Friday, 22 March 2019

How to get alert message before redirect a page in asp.net using c#


String scriptStr = "<script language='javascript' type='text/javascript'>";
                            scriptStr += "alert('Hi');";
                            scriptStr += "window.location = '";
                            scriptStr += "google.com";
                            scriptStr += "'";
                            scriptStr += "</script>";
                            this.Page.ClientScript.RegisterStartupScript(this.GetType(), "AlertMessage", scriptStr);

Thursday, 7 February 2019

How to call a code-behind method from aspx or asp page?


The code in .aspx page

<asp:Panel ID="PanelId" runat="server" Width="100%" Visible="true">
    <div class="classname " style="font-size: 80%; font-family: arial, helvetica, verdana">
        <br />
        <br />
        <table align="left" border="0" cellspacing="0" cellpadding="0" width="100%" class="classname ">
            <tr align="left" valign="middle">
                <td>
                    &nbsp;
                </td>
                <td>
                    <b>List of documents:</b>
                </td>
            </tr>
            <tr align="left" valign="middle">
                <td>
                    &nbsp;
                </td>
                <td>
                    <ul>
                        <%= this.CsharpMethod()%>
                    </ul>
                </td>
            </tr>
        </table>
    </div>
</asp:Panel>


The c sharp code in  .aspx.cs file


        protected string CsharpMethod ()
        {
string dDoco = string.Empty;
                // Retrieve data from database
                ArrayList al = datalistMethodName();

                if (al.Count > 0)
                {
                    dDoco += "<br><table align=\"left\" border=\"2\" cellpadding=\"2\" width=\"95%\" >";
                    dDoco += "<tr align=\"left\" valign=\"middle\">";
                    dDoco += "<td><b>Document</b></td><td><b>Document Type</b></td></tr>";
                    foreach (var item in al)
                    {
                        dDoco += "<tr align=\"left\" valign=\"middle\" ><td>" + item.Value.ToString() + "</td><td>" + item.Key.ToString() + "</td></tr>";
                    }
                    dDoco += "</table><br><br><br><br>";
                }
                return dDoco;
            }

Wednesday, 16 August 2017

Catching exceptions and displaying error messages in view using Angular2

We can display cached error message in view from component for that need write the following code
in Appcomponent

export class AppComponent {
    iproducts: IProduct[];
    err: any;
    constructor(private _product: ProductService) {
    }
    ngOnInit(): void {
      this._product.getproducts()
          .subscribe(iproducts => this.iproducts = iproducts,
          error => this.err = error);
    }
}


and in HTML Page or template we need to write  following code. Focus only on bold code rest of the code responsible for get values from service

@Component({
    selector: 'my-app',
    template: `<h1>{{err}}</h1>`,
  })

Catching exceptions and displaying error messages in view using Angular2

Thursday, 30 March 2017

Constants in AngularJs



Constants can be injected everywhere including configuration calls. So when you call module.config and set up states,colors,months,weeks or other run time settings you can inject constant values.

<!DOCTYPEhtml>
<html ng-app="app">
<head>
    <title></title>
<metacharset="utf-8"/>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-controller ="MyController">
    {{title}}
 
    <script>
        var app = angular.module('app', []);
        // Storing a single constant value
        app.constant('MOVIE_SAMPLE''The Movie');
        // Now we inject our constant value into a My controller
        app.controller('MyController'function ($scope, MOVIE_SAMPLE){
$scope.title=MOVIE_SAMPLE;
});
</script>
 
</body>
</html>

Constants in angularJs
Constants in AngularJs
 



Thursday, 23 March 2017

Create and Execute a Simple PLINQ Query



Parallel LINQ (PLINQ) is a parallel implementation of the LINQ pattern. A PLINQ query in many ways resembles a non-parallel LINQ to Objects query.
PLINQ is a query execution engine that accepts any LINQ-to-Objects or LINQ-to-XML query and automatically utilizes multiple processors or cores for execution when they are available
The primary difference is that PLINQ attempts to make full use of all the processors on the system. It does this by partitioning the data source into segments, and then executing the query on each segment on separate worker threads in parallel on multiple processors

Create Parallel LINQ and execute













Limitations

  PLINQ only works against local collections. This means that if you’re using LINQ providers over remote data, such as LINQ to SQL or ADO.NET Entity Framework, then you’re out of luck for this version.
  Since PLINQ chunks the collection into multiple partitions and executes them in parallel, the results that you would get from a PLINQ query may not be in the same order as the results that you would get from a serially executed LINQ query.