API Archives - Stackify Fri, 17 May 2024 04:58:16 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.4 https://stackify.com/wp-content/uploads/2023/02/favicon.png API Archives - Stackify 32 32 How to Use LoggerFactory and Microsoft.Extensions.Logging for .NET Core Logging With C# https://stackify.com/net-core-loggerfactory-use-correctly/ Fri, 21 Jul 2023 07:40:00 +0000 https://stackify.com/?p=7114 Do you use .NET (formerly .NET Core)? If so, you’re probably familiar with the built-in .NET Core LoggerFactory which is in Microsoft.Extensions.Logging. Back when it was introduced, it created a lot of confusion around logging with ASP.NET Core. Several years latter, the dust has settled down, and .NET logging has become somewhat “boring”, which means predictable and consistent.

In this post, we’ll offer you a guide on .NET logging. These are the topics we’ll cover:

  • Basics of the .NET Core Logging With LoggerFactory
  • Where is the LoggerFactory Created?
  • Accessing the LoggerFactory Object via Dependency Injection and Services
  • Accessing the Logging API Outside of a MVC Controller
  • How to Use the Logging API from Everywhere
  • Extend the Microsoft.Extensions.Logging API Functionality by Using NLog or Serilog Providers

Let’s get started.

Basics of the .NET Core Logging With LoggerFactory

It is designed as a logging API that developers can use to capture built-in ASP.NET logging as well as for their own custom logging. The logging API supports multiple output providers and is extensible to potentially be able to send your application logging anywhere.

Other logging frameworks like NLog and Serilog have even written providers for it. So you can use the ILoggerFactory and it ends up working sort of like Common.Logging does as a facade above an actual logging library. By using it in this way, it also allows you to leverage all of the power of a library like NLog to overcome any limitations the built-in Microsoft.Extensions.Logging API may have.

Where is the LoggerFactory Created?

Configuring the .NET logging facilities used to be way harder than it is today. In recent versions of .NET (6 and newer), the configuration of web apps has been greatly simplified. For starters, the Startup class is gone. You can have it back if you really want it but by default, it’s no longer there.

Instead, all configuration now lives in the Program.cs class.

Currently, if you start a new ASP.NET web API (making sure you don’t choose to use the minimal API format), your Program.cs class should look like the following:

var builder = WebApplication.CreateBuilder(args);


// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Right after the first line, we’ll add two more lines and that will be the start of our logging configuration:

builder.Logging.ClearProviders();
builder.Logging.AddConsole();

Accessing the LoggerFactory Object via Dependency Injection and Services

In the example code below, I am showing off 2 different ways to access the LoggerFactory from your MVC controller. Dependency injection can give you the factory or a logger either one.

public class ValuesController : Controller
{
        private ILoggerFactory _Factory;
        private ILogger _Logger;

        //set by dependency injection
        public ValuesController(ILoggerFactory factory, ILogger logger)
        {
            _Factory = factory;
            _Logger = logger;
        }

	[HttpGet]
	public IEnumerable Get()
	{
            var loggerFromDI = _Factory.CreateLogger("Values");            
            _Logger.LogDebug("From direct dependency injection");
            loggerFromDI.LogDebug("From dependency injection factory");
	}
}

Accessing the Logging API Outside of a MVC Controller

OK, so this is where the new logging API quickly becomes a nightmare. Dependency injection works great for accessing it in your MVC controller. But…how do you do logging in a class library that is consumed by this MVC project?

1. You could pass your existing LoggerFactory into every object/method you call (which is a terrible idea).

2. You could create your own LoggerFactory within your class library

This is an option as long as you don’t use any providers like a File provider that can’t have multiple instances writing at the same time. If you are using a lot of different class libraries you would have a lot of LoggerFactory objects running around.

3. Create a centrally located static class or project to hold and wrap around the main LoggerFactory reference

I see this as the best solution here unless you aren’t using any providers that have concurrency issues.

How to Use the Logging API from Everywhere

My suggestion is to create a little static helper class that becomes the owner of the LoggerFactory. The class can look something like this below. You can then use this ApplicationLogging class in any code that you want to use logging from and not have to worry about recreating LoggerFactory objects over and over. After all, logging needs to be fast!

public class ApplicationLogging
{
	private static ILoggerFactory _Factory = null;

	public static void ConfigureLogger(ILoggerFactory factory)
	{
		factory.AddDebug(LogLevel.None).AddStackify();
		factory.AddFile("logFileFromHelper.log"); //serilog file extension
	}

	public static ILoggerFactory LoggerFactory
	{
		get
		{
			if (_Factory == null)
			{
				_Factory = new LoggerFactory();
				ConfigureLogger(_Factory);
			}
			return _Factory;
		}
		set { _Factory = value; }
	}
	public static ILogger CreateLogger() => LoggerFactory.CreateLogger();
}    

Extend the Microsoft.Extensions.Logging API Functionality by Using NLog or Serilog Providers

Both NLog and Serilog both have a provider that you can use to extend the functionality of the built-in logging API. They essentially redirect all of the logs being written to the new logging API to their libraries. This gives you all the power of their libraries for the output of your logs while your code is not tied to any particular library. This is similar to the benefit of using Common.Logging.

Conclusion

Logging is an essential part of most non-trivial applications. As such, it shouldn’t be hard to integrate it into your application. The idea behind .NET’s built-in logging capabilities represents exactly that: by making logging a first-class citizen of the framework, friction is greatly reduced.

Back in the day, a great option when it came to .NET logging was to simply use NLog or Serilog and don’t even worry about the new logging API. Even though the built-in logging capabilities are now easier than ever to use, the advice still remains. If you want to capture the built-in ASP.NET logging, you can plugin the NLog/Serilog provider and it will map those messages over. By doing it this way, you can use a different logging library directly and you don’t have to even think about LoggerFactory even existing.

]]>
4 API Security Best Practices To Safeguard Sensitive Data https://stackify.com/4-api-security-best-practices-to-safeguard-sensitive-data/ Mon, 05 Dec 2022 13:53:47 +0000 https://stackify.com/?p=36080 Thanks to the increasing usage of different software solutions, API usage has become an everyday practice. As such, API security is a more prevalent issue in app development than ever before.

SaaS companies have an average of 350 integrations, whereas major SaaS companies like Slack, Zoom and Shopify have 2,000+ integrations. This is great for developers and end users, as Application Programming Interfaces (API) make life easier. 

However, there is an ever-present concern regarding API security, especially public APIs that require third-party logins. Developers are also overburdened to work within unrealistic time frames, raising concerns over quality standards. So, how should companies ensure their data is safeguarded from hackers while utilizing the API ecosystem?

Leveraging API security best practices is how. This article will review the top four security best  practices you can use to secure your APIs from malicious attacks. 

What is API Security?

API security is when you protect APIs from cyberattacks and threats. It’s crucial today because every organization and website has hundreds, if not thousands, of integrated APIs, all of which contain sensitive or private information. 

Successful API security measures have the following steps in place;

  • The API’s processed requests are from valid, verified sources
  • All the processed requests are legitimate
  • All the responses cannot be encrypted or breached in any way

Depending on your organization and the nature of the data, your API implementations are most likely SOAP (Simple Object Access Protocol) or REST (Representational State Transfer) – two standard protocols used to access web services. 

SOAP is standardized, has built-in error handling and doesn’t require using HTTP. REST has a smaller learning curve, is faster and doesn’t require expensive tools. However, SOAP APIs are also more secure by design. Learn more from this SOAP vs. REST guide to understand these two communication protocols.

Types of API Cyberattacks 

APIs are susceptible to attacks because they usually come with documented information about their structure and how they were created. This helps hackers reverse engineer APIs in their attempts to steal private data. Below are the most common types of attacks.

The DDoS Attacks

Distributed Denial-of-service (DoS) attacks are the most common kind. The attack is carried out on an API by overwhelming its memory through thousands of attacks, which result in the API slowing down and ultimately crashing the web server. Another way this happens is hackers send a vast amount of information in each request instead of thousands of requests.

Stolen Authentication

Arguably, the easiest way to access user data is through stolen authentication. Hackers steal an authorized identity and access the API with it. In most cases, the authentication token gets stolen and then misused. If not the token, cybercriminals will also bypass weak authentication to gain access.

Man-in-the-Middle Attack

A man-in-the-middle attack (MITM) happens when a hacker can intercept the communication between the API and the end-user. This usually happens when there is neither one-way nor end-to-end encryption in place. These vicious attacks can often lead to stolen private data, like login credentials.

4 API Security Best Practices

Now that we’ve covered the importance of API security and the types of cyber attacks to expect, let’s go over four API security best practices to protect your users.

1. Use Strong User Authentication

The primary cause of API security breaches is a lack of authentication or poor authentication. With authentication, you have proof that someone is who they say they are, similar to having a business clearly define its LLC formation purpose statement to prove its legitimacy. 

Since APIs serve as the door to an organization’s database, your APIs must be secured. Using strong user authentication and one way, as it reduces the security risk of losing user authentications.

The best way to accomplish strong user authentication is to either have multi-factor authentication or, even better, have a trusted authorization mechanism, such as OAuth. Either method limits access to web services to only the legitimate users. 

2. Encrypt All Your Online and Offline Data

Encrypting data is essential to protect yourself from various attacks, the most common being MITM attacks. As explained previously, these are when perpetrators access private data, such as login credentials, credit card numbers, account details and other personal information. Data transfers between APIs servers must always be appropriately encrypted to prevent theft. 

According to statistics, 33% of all Americans have been a victim of identity theft, with credit card fraud being the most common.

Companies should cipher all exchanges with the Transport Layer Security (TLS) protocol – the upgraded version of the Secure Sockets Layer (SSL) protocol. While you can opt for one-way encryption, two-way encryption is much better and more secure. 

Look at WhatsApp. The application boasts a high level of security by assuring all their chats are end-to-end encrypted. This level of protection ensures WhatsApp is desirable to users. 

So, while data encryption is essential, extra security never hurts. Another way to protect yourself from ID theft is by using credit protection services. Credit protection services help you monitor your financial activities and ensure no fraudulent activities occur. If your credit score is negatively affected, these services will also help resolve this problem. 

3. Add API Throttling And Rate Limiting

Containing an abundance of private data, APIs are highly desirable to hackers. Unfortunately, this also makes APIs vulnerable to DDoS attacks. Having rate limits in place is a great start to preventing successful API attacks. 

Set a threshold, after which all requests will be rejected. For example, 8,000 requests per day per account. 

Besides threshold limitations, also make use of throttling. Throttling algorithms check for the legitimacy of APR requests and perform other safety procedures. And while throttling will slow down a user’s connection, which is annoying, users will still have access to the API and you’ll avoid breaches. 

By having both in place, there’s little chance of the company data being compromised because of data breaches, as illustrated below. 

Besides security, if you’re worried about user experience because of throttling, check out Stackify’s Application Performance Management tool, Retrace. It gives you visibility over the performance of all your applications and provides the insights you’ll need to keep users happy, and their data safe.

4. Don’t Expose Excessive Data

Often, APIs reveal more information than necessary, and hackers can use that data. Ensuring this doesn’t happen should be a priority. To safeguard information, all responses end users receive should only be related to the request’s success or failure. This ensures APIs only provide only the required data. Anything more is playing right into the hackers’ hands. 

Therefore, ensure your DevOps processes scan the kind of information your APIs share. If you notice any data that’s not relevant, remove it as quickly as possible, leaving only what is necessary for the end users.

Protect Your APIs From Hackers 

The bad news is there is no stopping hackers. At least not permanently. Fortunately, cyber security has come a long way, and your users can get the best protection if you put the right measures in place.

An iron-clad API security plan ensures your information never lands in the wrong hands. And following the API security best practices mentioned above is a great start to securing your APIs completely.

]]>
Web API Error Handling: How To Make Debugging Easier https://stackify.com/web-api-error-handling/ Thu, 25 Oct 2018 13:58:29 +0000 https://stackify.com/?p=22781  Whether you’re the consumer or producer of an API, you’ve no doubt seen that good error handling can make debugging easier. And you may have noticed that error handling works best when everyone speaks the same language and has the same expectations. But what makes for good error handling? And how can we implement it and ensure consistency across our application?

Today, let’s look at the problem of error handling from two angles: the what and the how. And since tonight is pizza night, I’m going to go with a pizza theme for our examples later on.

First, let’s consider the what.

What Are Good API Errors?

Easy-to-use applications take many things into account. One of those is providing helpful and descriptive errors to their consumers. And a great place to start involves looking at standards. Since much of the web uses JSON and REST, we’ll focus on using what’s outlined for the JSON API. Even more specifically, we’re going to look at typical error codes that we see in most web API’s—4xx and 5xx errors.

Good API errors differentiate client and server errors

The most basic division of errors identifies whether the problem is a result of a client or server error.

4xx-level errors are client errors. These are errors that the client can solve on their own by changing their request. And then 5xx errors are server errors, which indicate to the client that it’s probably not something they did wrong and that they should either retry or contact support.

This is a basic division. Unfortunately, sometimes applications get it wrong. Whether it’s speeding through to a deadline or not having a good error handling template to follow, mistakes do happen. So what you’ll want to do (and we’ll cover this later) is make sure that your application is set up with global exception handling and filtering to provide your consumers with appropriate codes.

404

Good API errors use status codes appropriately

One of the first errors most of us encounter is the infamous HTTP 404 status code. It’s a clear indicator to the consumer that whatever they’re looking for is not there. But you may have also seen the vast list of error codes that you’re not as familiar with.

How do you know which to use? And how specific do you have to get?

Tip 1: Stick with well-known codes

My recommendation would be to not attempt to use all the error codes available. There are basic ones that most developers know and can recognize. And others that are more obscure and that will lead to confusion.

So what error codes should we use? Well, I advise that you get familiar with at least some of them. The ones listed below are the ones I would expect to occasionally see when I call an API. Therefore I would want an application developer to generate them under the right conditions.

Code Description Notes
400 Bad Request This is the generic error that tells us someone created a bad request. Perhaps required fields are missing or header values are not filled in.
401 Unauthorized Indicates that authentication has failed. This could be because of an expired, missing, or invalid token.
403 Forbidden Indicates that authorization failed. Alternatively, you can also use 404 so that the consumer doesn’t know that the resource even exists.
404 Not Found The requested resource is not found. Companies like GitHub also use 404 if you try to access a resource that you do not have the authorization to access.
500 Internal Server Error When something goes wrong on the server, the consumer can’t do anything about it. Just let them know there’s a problem and that they should try again later or contact support.

Now you may have noticed that I didn’t include codes like 405-Method Not Allowed or 503-Service Unavailable. These are common codes, but I would not expect an application developer to generate them. They’re either handled by frameworks, servers, or network components already.

Tip 2: Avoid codes you don’t understand

Many developers get a bit overzealous when they first learn about all the HTTP status codes available. They want to use the absolute most correct code for every situation. However, this results in unnecessary complexity in their application. It also causes consuming applications to modify their logic as well to account for more codes that could be returned.

For example, if a request header field is too large, then yes, sure, you could send a 431-Request Header Fields Too Large as the response. But then you’re forcing the consuming application’s developer to look up 431 to find out what it means and write logic to expect that response. Instead, send a 400-Bad Request and provide a helpful description that’s easy to read and understand.

Additionally, there are codes that are custom to particular uses. Let’s consider 498-Token Expired and 499-Invalid Token. When you’re first setting up your authentication, it may be tempting to use these. However, upon further inspection, you may notice that both of these are specifically for use with ArcGIS Server—whatever that may be. Additionally, 499 can also be used by nginx for indicating that a client has closed the connection.

So in this case, send back a 401-Unauthorized and provide a good message that gives enough information for the client to fix the problem.

Additionally, giving your consumers a 507-Insufficient Storage or 508-Loop Detected could give bad guys more information on how to bring your system down. Don’t make your consumers troubleshoot for you. Just say, Hey, sorry—Internal Server Error. Try again and if you still have problems, here’s an easy way to reach out and get help.

cubical image

Tip 3: Provide the right number of errors

Per the JSON API spec, “A server MAY choose to stop processing as soon as a problem is encountered, or it MAY continue processing and encounter multiple problems.”

They use the language “MAY” for a reason. It’s up to you. At this point, you should consider your customers and what makes sense for them. Does it make sense to first send a “Pizza size is required” error and then wait until the next submission to tell them that, oh, by the way, “Crust type is required,” too?

In this case, the answer is obvious. But there may be times when you’ll have to consider the options. For example, if errors only occur after a number of computationally expensive steps, it might make sense to return errors one at a time. In either case, always consider the consumer and the logic that will be implemented on their side. Do they want to know sooner or later that you don’t deliver to their address?

So what’s an example of errors that you would give one at a time? If you receive a request that results in a 401 because the token is not good, there’s no reason to continue on and also let them know that their request was also bad for other reasons. They’re not authorized, so they don’t need any additional information that could clue them in on your internal system structure.

Tip 4: Roll up to the most relevant error

Once again, back to the JSON API spec: “When a server encounters multiple problems for a single request, the most generally applicable HTTP error code SHOULD be used in the response. For instance, 400-Bad Request might be appropriate for multiple 4xx errors, or 500-Internal Server Error might be appropriate for multiple 5xx errors.”

Pretty simple: always choose the most relevant generalized error over the more accurate (but too technical) specific error.

Tip 5: Explain what went wrong

The standard goes on to tell you what MAY be included in the error message. They don’t take an opinionated stance on the result because they want it to be open for many use cases. My opinionated stance says that you should try to include the following:

  1. ID: Something that will let your consumers contact you. Then you can reference your logs and metrics to find out what went wrong.
  2. CODE: Even though the HTTP code comes back on the header, it’s good practice to add it to the body as well. This lets others see it and easily map it to a model.
  3. STATUS: This is the text of what your status code means. Don’t make your consumers look it up.
  4. TITLE: Let the consumer know what caused the client error here, but don’t share too much info about internal server errors.

Bonus points go to those of you that also add the following:

  1. LINK: This one is optional, but super helpful. If you can link to a help page or readme document that provides more info, you will be my hero forever. But not many people do this, so don’t feel too bad if you’re as lazy as the rest of us.
  2. DETAIL: Additional info, like how to actually fix the problem (in case you weren’t awesome enough to provide a link).

image

Tip 6: Separate general and domain errors

In addition to differentiating between client and server errors, as well as the different status codes, we can also classify errors as either general or domain-specific. This helps in deciding if we should write custom handling and messaging around it, or if it’s a well-known error condition.

General errors

General errors include things like using the wrong HTTP verb, failing authentication, or failing authorization. It’s typically good to stop processing quickly when these happen and get a response out to consumers. General errors are typically not domain-specific.

Domain errors

These are more specific to your domain. As an example, consider if we had a DeliveryUnavailableException or an OrderAlreadyExistsException. There might be additional things you’d want to do when these types of errors are encountered.

How Should We Implement Error Handling?

Okay, so now we know what errors will provide solid information for our consumers. Next, how do we actually go about it? There are a few different things we can do, like creating filters and error handlers. Let’s look at each of these and see how it’s done.

1. Create filters

You don’t want to repeat yourself. And you want to make sure that all your methods handle errors the same way. That way, there’s one less thing to worry about when you create yet another endpoint. A good option for this involves writing validation and exception filters that catch errors and treat them in a consistent manner.

Validation filters

First, let’s look at errors related to validation. In this case, instead of checking each field in our controller or service, we can add basic validation directly to our model, as shown below.

public class Pizza
{
    [Require]
    public string Size {get; set;}
    [Require]
    public string CrustType {get; set;}
    public string CrustSeasoning {get; set;}
    public List<Topping> Toppings {get; set;}
    [DataType(DataType.Date)]
    public DateTime OrderDate{get; set;}
}

And then we can validate all our models in our ValidationActionFilter.

public class ValidationActionFilter: ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var modelState = actionContext.ModelState;
        if (!modelState.IsValid) {
            actionContext.Response = actionContext.Request
                .CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
        }
    }
}

Exception filters

But what should we do with other types of exceptions? We can use a filter for those, as well.

First, let’s create our exception class.

public class PizzaParlorException: Exception
{
    public PizzaParlorException(HttpStatusCode statusCode, string errorCode, string errorDescription): base($"{errorCode}::{errorDescription}")
    {
        StatusCode = statusCode;
    }

    public PizzaParlorException(HttpStatusCode statusCode)
    {
        StatusCode = statusCode;
    }

    public HttpStatusCode StatusCode {get;}
}

And now let’s create our filter that will process our exceptions.

public class PizzaParlorExceptionFilterAttribute: ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        var exception = context.Exception as PizzaParlorException;
        if (exception != null) {
            context.Response = context.Request.CreateErrorResponse(
                exception.StatusCode, exception.Message);
        }
    }
}

And add it to our GlobalConfiguration.

GlobalConfiguration.Configuration.Filters.Add(new PizzaParlorExceptionFilterAttribute());

Now in our controllers, we throw exceptions by extending our PizzaParlorException like this:

public class OutOfDeliveryZoneException: PizzaParlorException
{
    public OutOfDeliveryZoneException(): base(HttpStatusCode.BadRequest)
    {
    }
}

// or perhaps the following

public class PizzaDeliveryAuthorizationException: PizzaParlorException
{
    public PizzaDeliveryAuthorizationException(): base(HttpStatusCode.NotAuthorized)
    {
    }
}

But that’s not the only way to handle exceptions. We can also use a GlobalErrorHandler.

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

2. Create a GlobalExceptionHandler

First off, why would we want to use a GlobalErrorHandler over an ExceptionFilterAttribute? Well, there are some exceptions that our filters will not catch.

From the ASP.NET site, there are errors that will not be caught by our filters above. This includes exceptions thrown:

  1. From controller constructors
  2. From message handlers
  3. During routing
  4. During response content serialization

And since we want to be covered in these scenarios as well, let’s add our GlobalExceptionHandler.

class GlobalPizzaParlorExceptionHandler: ExceptionHandler
{
    public override void HandleCore(ExceptionHandlerContext context)
    {
        context.Result = new TextPlainErrorResult
        {
            Request = context.ExceptionContext.Request,
            Content = "Pizza Down! We have an Error! Please call the parlor to complete your order."
        };
    }

    private class TextPlainErrorResult: IHttpActionResult
    {
        public HttpRequestMessage Request {get; set;}
        public string Content {get; set;}

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response =
                new HttpResponseMessage(HttpStatusCode.InternalServerError);
            response.Content = new StringContent(Content);
            response.RequestMessage = Request;
            return Task.FromResult(response);
        }
    }
}

Now, what do we need to do in order for that filter to catch the exception? Add it to our GlobalConfiguration.

public static class SetupFiltersExtensions
{
    public static IAppBuilder SetupFilters(this IAppBuilder builder, HttpConfiguration config)
    {
        config.Services.Replace(typeof (IExceptionHandler), new PizzaParlorExceptionHandler());
        return builder;
    }
}

Now there’s just one more thing we’ll want to do.

3. Create a LoggerHandler

With the GlobalExceptionHanlder, there’s still a chance that an exception will not be caught here. However, we’re guaranteed to be able to log it. And we’re able to set up as many exception loggers as we need. I’m just going to use log4net’s logger in this example.

public class Log4NetExceptionLogger: ExceptionLogger
{
    private ILog log = LogManager.GetLogger(typeof(Log4NetExceptionLogger));

    public async override Task LogAsync(ExceptionLoggerContext context, System.Threading.CancellationToken cancellationToken)
    {
        log.Error("An unhandled exception occurred.", context.Exception);
        await base.LogAsync(context, cancellationToken);
    }

    public override void Log(ExceptionLoggerContext context)
    {
        log.Error("An unhandled exception occurred.", context.Exception);
        base.Log(context);
    }

    public override bool ShouldLog(ExceptionLoggerContext context)
    {
        return base.ShouldLog(context);
    }
}

And again, make sure to add it to your configuration.

public static class WebApiConfig
{
    public static IAppBuilder RegisterApiConfig(this IAppBuilder app, HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Services.Add(typeof(IExceptionLogger), new Log4NetExceptionLogger());
        return app;
    }
}

One additional step you should take—use the StackifyAppender. This way, Retrace is set up to automatically collect all your logging messages.  Try Retrace’s free, two week trial today

<log4net>
    <root>
        <level value="DEBUG" />
        <appender-ref ref="StackifyAppender" />
    </root>
    <appender name="StackifyAppender" type="StackifyLib.log4net.StackifyAppender, StackifyLib.log4net" />
</log4net>

Consider Your Errors Handled!

And that’s it for today. We went over the basics of what errors provide to our consumers, as well as how to implement errors in our ASP.NET application. Now you’re ready to provide the right error and handle exceptions consistently throughout your application.

As your next step, take a look at your current projects and error handling. Verify that you’re providing the right web API error in the right context, and consider ways that you can make it easier for your consumers to fix problems on their own.

]]>
How to Call WCF Services and Create SOAP Services with ASP.NET Core https://stackify.com/soap-net-core/ Tue, 19 Sep 2017 09:35:17 +0000 https://stackify.com/?p=13833 If you are looking to use SOAP or WCF with ASP.NET Core, you are not alone. It is one of the most searched for and requested features for .NET Core. In this article, we will discuss how to consume a WCF SOAP service from your .NET Core application. We also show how to create and host a SOAP service with ASP.NET Core.

To start, let’s give a little background as to what SOAP is.

What is SOAP?

SOAP envelopeThe Simple Object Access Protocol (SOAP) is a protocol specification for exchanging structured information across distributed and possibly heterogeneous systems. It uses XML as its message format and relies on application layer protocols such as HTTP. Most people know it as the default protocol for web services.

Up until not too long ago, SOAP was the de facto standard for writing web services, and the Service Oriented Architecture (SOA) depended heavily on it. SOAP defines a message format that should be followed but inside of it we are free to add whatever we like – it is even possible to include binary attachments.

The SOAP specification defines a containing envelope (<envelope>), and inside it, we can have a header (<header>) and a body (<body>) and the body can include a fault section (<fault>) together with other subsections. Only <body> is mandatory, and <fault> is only used for responses, not requests, where an error occurred.

Extensions to SOAP include the ability to include chunks of binary content in the middle of a message; it is called Message Transmission Optimization Mechanism (MTOM), an alternative to using Base-64 to encode the binary streams, which typically makes it 30% larger.

SOAP Web Services

When invoking web services, the body must include the action to be called on the web service as well as any possible arguments. SOAP web services always use POST and submit the envelope as the payload to a single well-known URL. The web service framework will direct the request to some class and method on the system.

A web service makes available a Web Services Definition Language (WSDL) file where the details about the service are described: the name of each action method, the parameters and return values of each, and what faults are expectable. From this WSDL, Visual Studio (and other tools, such as the SVCUtil.exe command line utility) can generate code proxies that can interact with the web service.

There are some specifications, known collectively as WS-* (WS-star), which include WS-Policy, WS-Addressing, WS-Trust, WS-SecureConversation, WS-Transaction and a few others. These are key to providing enterprise-level functionality to web services; mind you, these standards are platform-independent, meaning, for example, a web service that implements WS-Transaction can be part of a distributed transaction across heterogeneous systems.

SOAP vs REST

There’s another player, not exactly new, which is the Representational State Transfer (REST). It’s technically not a protocol, but rather a style. With REST, we embrace the HTTP protocol in its entirety, including:

  • Using meaningful, not opaque, URLs, like /Product/Buy/101
  • Leveraging the HTTP verbs: GET for retrieving information in an idempotent way, POST for creating a resource, PUT for updating an existing one and DELETE for removing it
  • Making sense of the HTTP return codes: 201 means that something was created, 200 means that the request was processed successfully
  • Because REST supports GET, it is now possible to cache responses

REST is not a specification, and therefore there is no mandatory message format, but JSON is quite often the choice, although XML is not uncommon too. Some implementations allow negotiating the content to expect. But REST is no silver bullet, and, specifically, it leaves out, among others:

  • A standard for sending binary contents (like MTOM for SOAP)
  • Support for distributed transactions
  • Security mechanisms, other than using HTTPS

Currently, REST is commonly used for simple request-response calls using JSON, including AJAX-style calls. It lacks the specifications and complexity that WCF and SOAP offers, but is great for simple use cases.

You can easily create REST APIs with ASP.NET Core MVC. Learn more about SOAP vs REST.

How SOAP Services Worked Before .NET Core

In the days before.NET Core, starting with .NET/ASP.NET 1.1, we had XML Web Services as of 2001. It was part of the ASP.NET framework, and it provided an easy, although limited, way to create web methods. Many things were missing, such as security features, but it built on top of ASP.NET so it benefited inherently from it.

Realizing this, Microsoft released the Web Services Enhancements (WSE) package in 2002, based on a draft version of the WS-Security protocol. Two versions followed, consolidating the implementation of WS-Security and introducing WS-Policy, WS-Addressing, WS-Trust and WS-SecureConversation support as well as Message Transmission Optimization Mechanism (MTOM), a performance-friendly way to transmit binary contents.

Then came WCF. It was touted as the “one ring” of web services, the one that would rule them all. The ABC acronym, – Address, Binding, and Contract – says it all: give us a contract and a binding and we can call any address!

It was, indeed, highly customizable, with bindings that allowed it to interoperate with other technologies while offering a high-performance binary format for Windows-only communication, the ability to talk directly to Microsoft Message Queue (MSMQ), local-mode inter-process communication (IPC) and even disconnected UDP.

Just think about this: using the same interface and just switching some configuration settings you can communicate with totally different services, not necessarily WCF on both endpoints.

From the start, it included extensibility at various levels through the use of behaviors, instance management and throttling, different layers of security and duplex channels; subsequent releases introduced service discoverability and routing and REST eventually also dropped by.

WCF was Microsoft’s flagship technology for implementing web services, be it SOAP, REST or whatever you would like.

WCF is an enterprise solution that can support a wide array of complex requirements. This complexity is why it hasn’t been ported to .NET Core (yet, anyway).

How to Call a SOAP Service with .NET Core

Then came .NET Core and the story changed: WCF was not here, or, to be precise, there was no server-side WCF, only client-side, meaning, you could write a WCF proxy to access aSOAP or REST web services, but you could not implement one.

WCF is one of the most requested features, and there is an open discussion in WCF’s GitHub repository about this: https://github.com/dotnet/wcf/issues/1200. Microsoft recently made recently available an online survey asking the developer community to express their views about this, and, namely, what do they consider the more important features of WCF; it is available here: https://www.research.net/r/GitWCF, do sound your voice there.

So, if you want to use WCF on the client side with .NET Core, you can certainly do so. First, make sure you add the System.ServiceModel.Primitives and one of System.ServiceModel.Http (for the BasicHttpBinding/BasicHttpsBinding or NetHttpBinding/NetHttpsBinding bindings, which includes SOAP and REST) or System.ServiceModel.NetTcp (for NetTcpBinding, a Windows-only binary protocol). Absent are named pipes, MSMQ and support for the WS-* specs.

A simple example is in order, first, the contract:

[ServiceContract]
public interface IPingService
{
	[OperationContract]
	string Ping(string msg);
}

Then, the client code:

var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress(new Uri("http://server/PingService.svc"));
var channelFactory = new ChannelFactory(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
var result = serviceClient.Ping("Ping");
channelFactory.Close();

As you can see, nothing different to what you would do in the full .NET framework. Of course, there is no App.config or Web.config files, so you need to configure things manually, like creating the appropriate binding and endpoint address.

You can also use svcutil.exe manually to generate proxy classes for you that will work with .NET Core.

However, if you think about it, SOAP is not that complex, and, also, ASP.NET Core is very easy to extend.

[adinserter block=”33″]

How to Create a SOAP Service with ASP.NET Core

Microsoft wrote a blog post about implementing a middleware component capable of handling SOAP requests.

The example is very clear and informative and is a pleasant read, and Digital Design must have thought the same, because they made available on GitHub a fully functional (and extended) version of the blog’s sample code, which you can find here: https://github.com/DigDes/SoapCore.

Because we live in the age of NuGet, a package is also available; it’s called SoapCore.

By using SoapCore on top of ASP.NET Core, you can benefit from all the ASP.NET Core goodies, such as routing and filters.

As an example, for the client-side, you can use pretty much the same class as I showed before. For the server end, you will need to write a service class that implements the contract:

public class SampleService : IPingService
{
	public string Ping(string msg)
	{
		return string.Join(string.Empty, msg.Reverse());
	}
}

And we just need to register the service implementation under a well-known address:

public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton(new PingService());
     services.AddMvc();
     //rest goes here
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,  ILoggerFactory loggerFactory)
{
    app.UseSoapEndpoint(path: "/PingService.svc", binding: new BasicHttpBinding());
    app.UseMvc();
    //rest goes here
}

If you are interested, you can add a custom exception-to-string transformer, if you do, you can extract a meaningful message from any exception that should occur and return it to the client as a fault string:

services.AddSoapExceptionTransformer((ex) => ex.Message);

What the code does is inject a custom middleware to the ASP.NET Core pipeline which listens to HTTP POSTs, checks if the proper headers are present and extracts the action method and its parameters from the payload, which then forwards to the given implementation class.

A couple of notes:

  • The .svc extension is, of course, unnecessary, it is just here to remind us that WCF once mandated it
  • You can use any life cycle for the PingService, not necessarily singleton
  • The bindings on the client and server must match
  • You won’t be able to add any of the ASP.NET Core filters to the service implementation, as they will be ignored; but you can use dependency injection

Even though you can surely use this code for backward compatibility, in the case where you need to have a SOAP service written in .NET Core (for example, if you need to deploy it to Docker), be aware of its limitations:

  • No support of the WS-* specifications
  • No support for MTOM
  • No support for security other than HTTPS or ASP.NET Core’s built-in
  • No behaviors or throttling

Conclusion

Convenient as this SoapCore package may be, it’s still a long way from the full WCF that we had back in .NET framework. Since part of the work is done, you can consider contributing to it or rolling out your own, in the case that you need to write SOAP services. Be aware of the challenges involved, as things can get complex, especially if you need to support any of the WS-* protocols.

Probably better to wait for Microsoft to implement the remaining parts of WCF for .NET Core, and here you can make yourself heard, either by joining the discussion in the WCF repository or by answering the survey.

Remember to also have a full lifecycle APM in place so that you can catch issues early and often. Stackify Retrace offers a free trial.

]]>
SOAP vs. REST: The Differences and Benefits Between the Two Widely-Used Web Service Communication Protocols https://stackify.com/soap-vs-rest/ Tue, 14 Mar 2017 10:21:34 +0000 https://stackify.com/?p=9343 Defining SOAP and REST

SOAP (Simple Object Access Protocol) and REST (Representational State Transfer) are both web service communication protocols. SOAP was long the standard approach to web service interfaces, although it’s been dominated by REST in recent years, with REST now representing more than 70% of public APIs according to Stormpath.  Understand the primary differences between SOAP vs. REST  and how each can benefit your organization’s goals.

SOAP vs REST: Primary Differences

REST operates through a solitary, consistent interface to access named resources. It’s most commonly used when you’re exposing a public API over the Internet. SOAP, on the other hand, exposes components of application logic as services rather than data. Additionally, it operates through different interfaces. To put it simply, REST accesses data while SOAP performs operations through a more standardized set of messaging patterns. Still, in most cases, either REST or SOAP could be used to achieve the same outcome (and both are infinitely scalable), with some differences in how you’d configure it.

SOAP was originally created by Microsoft, and it’s been around a lot longer than REST. This gives it the advantage of being an established, legacy protocol. But REST has been around for a good time now as well. Plus, it entered the scene as a way to access web services in a much simpler way than possible with SOAP by using HTTP.

Benefits of REST Over SOAP

In addition to using HTTP for simplicity, REST offers a number of other benefits over SOAP:

  • REST allows a greater variety of data formats, whereas SOAP only allows XML.
  • Coupled with JSON (which typically works better with data and offers faster parsing), REST is generally considered easier to work with.
  • Thanks to JSON, REST offers better support for browser clients.
  • REST provides superior performance, particularly through caching for information that’s not altered and not dynamic.
  • It is the protocol used most often for major services such as Yahoo, Ebay, Amazon, and even Google.
  • REST is generally faster and uses less bandwidth. It’s also easier to integrate with existing websites with no need to refactor site infrastructure. This enables developers to work faster rather than spend time rewriting a site from scratch. Instead, they can simply add additional functionality.

Still, SOAP remains the preferred protocol for certain use cases. The general consensus among experts these days is that REST is the typically preferred protocol unless there’s a compelling reason to use SOAP (and there are some cases in which SOAP is preferred).

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Benefits of SOAP Over REST

Because you can achieve most outcomes using either protocol, it’s sometimes a matter of personal preference. However, there are some use cases that SOAP tends to be better-suited for. For instance, if you need more robust security, SOAP’s support for WS-Security can come in handy. It offers some additional assurances for data privacy and integrity. It also provides support for identity verification through intermediaries rather than just point-to-point, as provided by SSL (which is supported by both SOAP and REST).

Another advantage of SOAP is that it offers built-in retry logic to compensate for failed communications. REST, on the other hand, doesn’t have a built-in messaging system. If a communication fails, the client has to deal with it by retrying. There’s also no standard set of rules for REST. This means that both parties (the service and the consumer) need to understand both content and context.

Other benefits of SOAP include:

  • SOAP’s standard HTTP protocol makes it easier for it to operate across firewalls and proxies without modifications to the SOAP protocol itself. But, because it uses the complex XML format, it tends to be slower compared to middleware such as ICE and COBRA.
  • Additionally, while it’s rarely needed, some use cases require greater transactional reliability than what can be achieved with HTTP (which limits REST in this capacity). If you need ACID-compliant transactions, SOAP is the way to go.
  • In some cases, designing SOAP services can actually be less complex compared to REST. For web services that support complex operations, requiring content and context to be maintained, designing a SOAP service requires less coding in the application layer for transactions, security, trust, and other elements.
  • SOAP is highly extensible through other protocols and technologies. In addition to WS-Security, SOAP supports WS-Addressing, WS-Coordination, WS-ReliableMessaging, and a host of other web services standards, a full list of which you can find on W3C.

At the end of the day, the best protocol is the one that makes the most sense for the organization, the types of clients that you need to support, and what you need in terms of flexibility. Most new APIs are built using REST and JSON, simply because it typically consumes less bandwidth and is easier to understand both for developers implementing initial APIs as well as other developers who may write other services against it. Because it’s more easily consumed by most of today’s web browsers, REST+JSON has become the defacto technology for the majority of public APIs. However, SOAP remains a valuable protocol in some circumstances. Plus, you don’t have to look far to find die-hard fans advocating for SOAP for certain use cases.

]]>
Goodbye Web API: Your Guide to RESTful APIs with ASP.NET Core https://stackify.com/asp-net-core-web-api-guide/ Mon, 13 Feb 2017 20:01:45 +0000 https://stackify.com/?p=7042 When ASP.NET Core was released, Microsoft and the .NET community decided to merge the functionality of MVC and Web API. This makes sense since the two have always been very similar. We went through the process of making an ASP.NET Core Web API with various scenarios and came up with these tips for anyone out there wanting to do the same. Are you looking to implement a Web API with ASP.NET Core? Here’s how to accomplish exactly that.

In this article, you’ll learn about

  • Web API vs MVC
  • Migrating Web API to MVC 6
  • Using ASP.NET Core MVC 6 as a RESTful API
  • MVC 6 alternatives for RESTful APIs

ASP.NET Web API vs MVC: What is the Difference?

Before ASP.NET Core, they were very similar. Both followed an MVC type pattern with controllers and actions. Web API lacked a view engine like a Razor and instead was designed to be used for REST APIs. MVC was designed for standard web applications with HTML front ends.

Microsoft touted Web API as a framework for building any type of HTTP service. It was a great alternative to WCF, SOAP, and older ASMX style web services. It was designed from the ground up with JSON and REST in mind. Web API also supported OData, which was a standard way to query data via CRUD operations.

Migrate Existing Web API Controllers by Using a Compatibility Shim

The base class for Web API was ApiController, which no longer exists in ASP.NET Core. You can include the NuGet package for Microsoft.AspNetCore.Mvc.WebApiCompatShim and still use ApiController.

If you are using HttpResponseMessage in your Web API controllers, you will need to make one small code change in your Startup class to call AddWebApiConventions(). This will wire up the HttpResponseMessageOutputFormatter so that it knows how to properly serialize that response.

public void ConfigureServices(IServiceCollection services)
{
	// Add framework services.
	services.AddMvc().AddWebApiConventions(); //Add WebApi
}

Depending on how you want to do routing with Web API, you may also need to register routes for it within your Startup class.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
	app.UseMvc(routes =>
	{
		routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
	});
}

That is all you need to do, and you can migrate your existing Web API code to ASP.NET Core.

Here is a sample controller showing a couple different ways to use your ApiController within ASP.NET Core with the compatibility shim.

[Route("api/[controller]/[action]")]
public class ValuesApiController : ApiController
{
	[HttpGet]
	[ActionName("GetArray")]
	public IEnumerable GetArray()
	{
		//example returns a basic type that is automatically serialized as json - nothing special here
		return new string[] { "value2", "value3" };
	}

	[HttpGet]
	[ActionName("GetSomeJson")]
	public HttpResponseMessage GetSomeJson()
	{
		//example returns a HttpResponseMessage - the shim makes this possible
		var resp = new HttpResponseMessage()
		{
			Content = new StringContent("[{\"Name\":\"ABC\"},[{\"A\":\"1\"},{\"B\":\"2\"},{\"C\":\"3\"}]]")
		};

		resp.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
		return resp;
	}
}

This article also has a lot of good details about using the compatibility shim: Migrating from ASP.NET Web API to MVC 6 – exploring Web API Compatibility Shim.

Using the New ASP.NET MVC 6 Controllers to Act as a RESTful Web API

The new MVC 6 that ships with ASP.NET Core merges the best of both MVC and Web API worlds from ASP.NET. From any controller, you can return a View or object and MVC will take care of serializing it for you. Multiple different routing styles enable you to implement basic MVC web applications or more REST-style APIs.

Here is a bunch of random ways MVC can be implemented if you wanted a Frankenstein mix up of actions.

public class HomeController : Controller
{
	public IActionResult Index()
	{
		return View("Index"); //MVC view
	}

	public IEnumerable GetArray()
	{
		//example returns a basic type that is automatically serialized as json
		return new string[] { "value2", "value3" };
	}

	public object GetSomeObject()
	{
		//example returns an object that is automatically serialized as json
		return new {color = "red", today = DateTime.UtcNow};
	}

	public IActionResult CreateSomething()
	{
		return StatusCode(201); //set status code
	}

	public string Greet(string id)
	{
		return $"Hello {id}";
	}
}

If you are serious about making a REST-style API, the default ASP.NET project in Visual Studio will create a sample API designed around GET, POST, PUT, DELETE standard operations for REST API. Microsoft also has a good tutorial on their site.

Nancy is a Good Web API Alternative for ASP.NET Core

Outside of the standard MVC framework that ships with ASP.NET, there are some community alternatives. One of the most popular is called Nancy. It has been around for quite a long time and was a popular option for web apps built with Mono to run on Linux since it allowed ASP.NET to work without IIS or the standard System.Web pipeline.

Nancy has a few principles that make it an interesting:

  • Super lightweight
  • Request path matching (routing) and parameter handling
  • Can run on any host including IIS, Kestrel, Owin, self-hosted, etc.
  • View engine integration (Razor and others)

My favorite feature of Nancy is how it works with incoming parameters. This simple example will give you an idea of how it works. Be sure to check out their GitHub page for more details and lots of samples.

public class Module : NancyModule
{
    public Module()
    {
        Get("/greet/{name}", x => {
            return string.Concat("Hello ", x.name);
        });
    }
}

Summary on Web API for ASP.NET Core

Web API may not be available for ASP.NET Core, but you can use your old code with the compatibility shim. We also covered how to just use MVC 6. There are some other 3rd party RESTful API solutions like Nancy that you could also consider. Also check out our post about the top ASP.NET Core features.

]]>