Snippset

Snippset Feed

Azure by Martin
...see more

When you use EventId in .NET logs, both the Id (an integer) and Name are sent to Application Insights as part of customDimensions. However, the EventId.Id is stored as a string, which affects how you can filter it.

Limitation in UI Filters

The Application Insights UI filter panel only supports string operations like equals or contains. You can’t use greater than or less than filters directly in the UI.

Use KQL for Numeric Filtering

To filter numerically, use the Logs (Analytics) tab with Kusto Query Language (KQL):

traces
| extend EventIdInt = toint(customDimensions["EventId.Id"])
| where EventIdInt > 1000

This converts the string to an integer so you can filter properly.

Pro Tip

Use numeric ranges for EventId to categorize logs (e.g., 1000–1999 = Auth, 2000–2999 = Payments) and filter easily with KQL.

Azure by Martin
...see more

Tracking custom events with TrackEvent() in Azure Application Insights helps you monitor how users interact with your app. However, to obtain meaningful data, it's essential to name your events clearly and consistently.

Here are some best practices:

Use Clear, Descriptive Names

Write event names using a Verb-Noun format like UserLoggedIn, FileDownloaded, or OrderSubmitted. This makes them easy to understand.

Stick to PascalCase

Use PascalCase (each word starts with a capital letter), and avoid:

  • Spaces (User Logged In)
  • Dashes (User-Logged-In)
  • Underscores (user_logged_in)

Use: UserLoggedIn

Don’t Include Dynamic Data

Keep user IDs, file names, or other changing values out of the event name.
Instead, put that info in custom properties or metrics.

telemetryClient.TrackEvent("ReportDownloaded",
new Dictionary<string, string> { { "FileType", "PDF" }, { "UserRole", "Admin" } });

Keep It Consistent

Follow the same naming style across your app. This makes it easier to search and analyze data later.

Be Specific When Needed

If similar actions happen in different contexts, make your event name more specific:
ContactFormSubmitted vs. FeedbackFormSubmitted

Tip

Use a naming template like:
<Action><Entity>[<Qualifier>]
Example: AddedItemToCart

A clean, consistent naming strategy makes your telemetry easier to work with, both now and in the future.

...see more

To make your ASP.NET Core services easy to test and maintain, follow this proven pattern. The example below demonstrates how to register a service and configure an HttpClient with custom handlers, while keeping the design flexible for unit testing.

1. Register your service separately

Register your service interface and implementation as a singleton (or other lifetime as needed). This keeps the service replaceable in tests:

services.AddSingleton<IMyService, MyService>();

Tip: Use TryAdd for safe registration in reusable code

If your registration code is part of a shared library or package, use TryAdd to avoid overriding existing registrations accidentally:

services.TryAddSingleton<IMyService, MyService>();

2. Configure an HttpClient with handlers

Use a named HttpClient to add retry and logging handlers. These handlers improve reliability and diagnostics:

services.AddHttpClient(nameof(MyService))
.AddHttpMessageHandler(s => new RetryHandler(s))
.AddHttpMessageHandler(s => new LoggingHandler(s));

3. Add memory caching safely

You can call AddMemoryCache() without worry — it internally prevents duplicates:

services.AddMemoryCache();

Full Sample Method:

public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyClientServices(this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
services.AddMemoryCache();
services.TryAddSingleton<IMyService, MyService>();
services.AddHttpClient(nameof(MyService))
.AddHttpMessageHandler(s => new RetryHandler(s))
.AddHttpMessageHandler(s => new LoggingHandler(s));
return services;
}
}

Why This Matters

  • Separation of concerns makes your code easier to test.
  • Named HttpClient with handlers improves reliability and debugging.
  • TryAdd keeps your library safe and reusable.
  • Memory cache registration is simple and safe.

Using this approach ensures your ASP.NET Core apps are easier to maintain, test, and extend.

React by Riley
...see more

When building tree structures in React, you might see this warning:

"Encountered two children with the same key..."

This usually happens when your component is rendering a list or tree and uses the same key value for multiple items. React requires that keys be unique among siblings to correctly track changes.

The Problem

In some apps, a tree of items is built using IDs like id, targetId, and parentId. A common mistake is using a field like targetId as the unique key — but if that field isn't truly unique, React throws an error.

Also, when building the tree structure, developers often assume that parentId matches a node’s id, but sometimes it actually matches others like targetId — and since targetId isn't unique, that causes lookup problems.

The Fix

Here’s how to correctly build the tree and avoid duplicate keys:

  1. Use id as the unique key — it's meant to be unique and stable.
  2. Create a dictionary keyed by id.
  3. Build a helper map from targetId to nodes — since targetId isn't unique, store an array of nodes per targetId.
  4. When assigning children, match parentId to the corresponding targetId, and attach the node to all matches (if multiple).

Here’s a simplified version of the corrected tree builder:

function buildTree(nodes) {
const updatedNodes = nodes.map(node => ({
...node,
id: String(node.id),
targetId: String(node.targetId),
parentId: String(node.parentId),
children: [],
}));
const targetIdToNodes = {};
updatedNodes.forEach(node => {
if (!targetIdToNodes[node.targetId]) {
targetIdToNodes[node.targetId] = [];
}
targetIdToNodes[node.targetId].push(node);
});
const rootNodes = [];
updatedNodes.forEach(node => {
if (node.parentId === '0') {
rootNodes.push(node);
} else {
const parents = targetIdToNodes[node.parentId];
if (parents) {
parents.forEach(parent => {
parent.children.push(node);
});
}
}
});
return rootNodes;
}

In your React rendering, always use node.id for the key:

<TreeNode key={node.id} node={node} />

Takeaway

Always make sure your keys in React are unique and stable. And when building a tree, know what your parentId is pointing to — it can make or break your structure.

React by Riley
...see more

JSX may look like HTML, but it’s actually JavaScript. When used correctly, it brings power and clarity to React development.

Why Use JSX?

  • It’s familiar to anyone who has written HTML.
  • You can mix logic and layout using {} for JavaScript expressions.
  • JSX is compiled into fast and efficient React code.

Key JSX Rules

  • Use className instead of class.
  • Self-closing elements like <img />.
  • Wrap multiple elements in one parent: <div> or <>.

Example:

function Greeting() {
return <h1>Hello, world!</h1>;
}

Common Mistakes

  • Forgetting to close tags.
  • Using class instead of className.
  • Returning multiple sibling elements without a wrapper.
React by Riley
...see more

When using ref in React, especially with forwardRef, it's important to understand how ref works — and how it doesn't.

The Problem

You might see this warning in your console:

ref is not a prop. Trying to access it will result in undefined being returned...

This usually happens when you try to declare ref in your component's propTypes or access it like a normal prop (props.ref). But ref is a special prop in React. It doesn't behave like other props.

✅ The Correct Way to Use ref

When using forwardRef, React gives the ref as the second argument of your function. Here's what that looks like:

const MyComponent = forwardRef(function MyComponent(props, ref) {
// use ref directly
});

Don't try to access ref through props.ref. That won't work.


❌ Don't Do This

MyComponent.propTypes = {
// This will trigger a warning!
ref: PropTypes.any,
};

React doesn't pass ref through the normal props object, so it shouldn’t be validated with propTypes.


The Fix

  • Use ref only via the second argument in forwardRef.
  • Remove ref from propTypes.

This will prevent the warning and adhere to React best practices.

React by Riley
...see more

If you're using TinyMCE in a React app and want to provide users with a way to remove all data-* attributes from their content, you can create a custom toolbar button to do just that.

Why do this?

data-* attributes are often added by frameworks, plugins, or tracking tools. In some cases, you might want to remove these before saving or publishing content, especially for clean, production-ready HTML.

How to Add the Button

You can use TinyMCE’s setup function to add a custom button with a mop-like icon to your toolbar. Here's how:

import { Editor } from '@tinymce/tinymce-react';
function MyEditor({ content, contentChange, onEditorInit }) {
return (
<Editor
value={content}
onEditorChange={(newValue) => contentChange(newValue)}
onInit={onEditorInit}
init={{
height: 500,
menubar: false,
plugins: 'code',
toolbar: 'undo redo | mopCleaner | bold italic underline | code',
setup: (editor) => {
editor.ui.registry.addIcon('mopCleanerIcon', `
<svg width="24" height="24" viewBox="0 0 24 24">
<path d="M12 2v14" stroke="currentColor" stroke-width="2"/>
<path d="M8 16h8l1 4H7l1-4z" fill="currentColor"/>
</svg>
`);
editor.ui.registry.addButton('mopCleaner', {
icon: 'mopCleanerIcon',
tooltip: 'Remove all data-* attributes',
onAction: () => {
const currentContent = editor.getContent();
const cleanedContent = currentContent.replace(/\sdata-[\w-]+="[^"]*"/g, '');
editor.setContent(cleanedContent);
},
});
},
}}
/>
);
}

How it works:

  • The button removes all HTML attributes that match the pattern data-something="value".
  • It works even when multiple data-* attributes are in a single tag.
  • You can customize the icon or tooltip to match your app's style.

Tip:

To support edge cases, such as attributes with single quotes or no values, you can enhance the regex as needed.

React by Riley
...see more

TinyMCE is a popular rich text editor used to add content-editing capabilities to web apps. When working with React, TinyMCE provides an official wrapper that makes integration quick and easy.

Here’s how to set it up in a React project:

1. Install the Package

Use npm:

npm install @tinymce/tinymce-react

2. Basic Usage

Import the component and render it:

import { Editor } from '@tinymce/tinymce-react';
function MyEditor() {
return (
<Editor
initialValue="<p>Start typing...</p>"
init={{
height: 300,
menubar: false,
plugins: 'link image code',
toolbar: 'undo redo | formatselect | bold italic | link image | code',
}}
/>
);
}

This will render a fully functional rich text editor inside your React component.

3. Handling Content Changes

You can capture changes to the editor content like this:

<Editor
onEditorChange={(newContent) => {
console.log(newContent); // Save or process the content here
}}
/>

Tips:

  • TinyMCE is highly customizable with plugins, themes, and custom toolbars.

  • You can host TinyMCE locally or use the cloud version.

  • It supports custom buttons, icons, and content filtering.


Learn More:

Visit TinyMCE React Docs for advanced configuration options.

Azure by Martin
...see more

Application Insights doesn’t store the original .NET LogLevel (like Debug or Trace) — it only stores SeverityLevel, which combines them. To make your logs easier to filter and analyze, you can add LogLevel as a custom property using a TelemetryInitializer.

Example:

public class LogLevelInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
if (telemetry is TraceTelemetry trace &&
telemetry is ISupportProperties props &&
!props.Properties.ContainsKey("LogLevel"))
{
props.Properties["LogLevel"] = trace.SeverityLevel switch
{
SeverityLevel.Verbose => "TraceOrDebug",
SeverityLevel.Information => "Information",
SeverityLevel.Warning => "Warning",
SeverityLevel.Error => "Error",
SeverityLevel.Critical => "Critical",
_ => "Unknown"
};
}
}
}

Integration

Register the initializer in your app:

services.AddSingleton<ITelemetryInitializer, LogLevelInitializer>();

Now, every trace will include a LogLevel key in customDimensions.

...see more

It’s best practice to tailor logging levels per environment (Development, Staging, Production) by using environment-specific configuration files like appsettings.Development.json or appsettings.Production.json.

Example for Development (verbose logging):

{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Information",
"System": "Warning",
"YourAppNamespace": "Trace"
}
}
}

Example for Production (concise logging):

{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"System": "Warning",
"YourAppNamespace": "Information"
}
}
}

By adjusting log levels per environment, you can capture detailed diagnostics during development while reducing noise and performance impact in production.

Add to Set
  • .NET
  • Agile
  • AI
  • ASP.NET Core
  • Azure
  • C#
  • Cloud Computing
  • CSS
  • EF Core
  • HTML
  • JavaScript
  • Microsoft Entra
  • PowerShell
  • Quotes
  • React
  • Security
  • Software Development
  • SQL References
  • Technologies
  • Testing
  • Visual Studio
  • Windows