Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 13, 2025

Fix GraphMockResponsePlugin Date Format Culture Issue

HTTP Date headers and InnerError date properties in mocked Graph responses were formatted using the system's culture settings, causing inconsistent output across different locales (e.g., 13/11/2025 14:30:00 in French vs 11/13/2025 2:30 PM in US).

Changes

  • Replace DateTime.Now.ToString(CultureInfo.CurrentCulture) with culture-invariant formats
  • HTTP Date headers: Use RFC 1123 format ("r") - standard HTTP Date header format per RFC 7231
  • InnerError.Date property: Use sortable ISO 8601 format ("s") - sortable date/time pattern without timezone
  • HAR file generation: Use ISO 8601 round-trip format ("o") - per HAR specification requirements
  • Both HTTP header and InnerError formats use the same DateTime.Now value to ensure consistency
  • Updated 5 plugin files:
    • GraphMockResponsePlugin.cs (2 locations - HTTP headers only)
    • MockResponsePlugin.cs (1 location - HTTP headers only)
    • RateLimitingPlugin.cs (1 location - HTTP headers and InnerError)
    • GraphRandomErrorPlugin.cs (2 locations - HTTP headers and InnerError)
    • RetryAfterPlugin.cs (1 location - HTTP headers and InnerError)
    • HarGeneratorPlugin.cs (1 location - HAR file generation with "o" format)

Format Details

RFC 1123 (HTTP headers): Sun, 16 Nov 2025 11:16:59 GMT

  • Standard HTTP Date header format per RFC 7231
  • Culture-invariant

ISO 8601 sortable (InnerError.Date): 2025-11-16T11:16:59

  • Sortable date/time pattern (ISO 8601)
  • Culture-invariant
  • No timezone or fractional seconds

ISO 8601 round-trip (HAR format): 2025-11-16T11:59:30.1234567+00:00

  • Full ISO 8601 format with timezone and fractional seconds
  • Required by HAR specification
  • Culture-invariant

Example

// Before
var requestDate = DateTime.Now.ToString(CultureInfo.CurrentCulture);
headers.AddRange(ProxyUtils.BuildGraphResponseHeaders(request, requestId, requestDate));
InnerError = new() { Date = requestDate }

// After (for error responses)
var now = DateTime.Now;
var requestDateHeader = now.ToString("r", CultureInfo.InvariantCulture);
var requestDateInnerError = now.ToString("s", CultureInfo.InvariantCulture);
headers.AddRange(ProxyUtils.BuildGraphResponseHeaders(request, requestId, requestDateHeader));
InnerError = new() { Date = requestDateInnerError }

// HAR file generation
StartedDateTime = currentTime.ToString("o")

Verification

✅ Build successful with no warnings
✅ All formats verified as culture-invariant
✅ Same DateTime value ensures consistency between header and body
✅ HAR format complies with specification

Fixes #1436

Original prompt

This section details on the original issue you should resolve

<issue_title>[BUG]: GraphMockResponsePlugin Mocked JSON date format depends on local machine culture settings</issue_title>
<issue_description>### Description

When using GraphMockResponsePlugin in Dev Proxy, the dates contained in the mocked JSON responses are formatted according to the operating system's regional culture settings. This causes inconsistent output across different environments. Since Dev Proxy intends to mock Microsoft Graph responses, date formats should be predictable and aligned with Microsoft Graph’s ISO-8601 conventions.

Expected behaviour

All mocked Microsoft Graph date/time fields should be serialized using a consistent culture-invariant ISO-8601 format (e.g. 2025-11-01T14:30:00Z), independent of the host machine’s locale/region settings. Like the sample response present in the documentation https://learn.microsoft.com/en-us/graph/throttling

Actual behaviour

Date/time values in mocked JSON responses vary depending on the OS regional settings. For example:

01/11/2025 14:30:00 on a French machine

11/01/2025 2:30 PM on a US machine

This leads to non-deterministic behavior.

Steps to reproduce

Configure Dev Proxy with GraphMockResponsePlugin enabled.

Run Dev Proxy on a machine with French regional settings.

Observe the different date fields in mocked responses

Run the same proxy on a machine with US regional settings.

Compare the JSON responses and note that date formats differ between environments.

Dev Proxy Version

1.3

Operating system (environment)

Windows

Shell

PowerShell

Configuration file

{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v1.3.0/rc.schema.json",
"plugins": [
{
"name": "GraphSelectGuidancePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "GraphBetaSupportGuidancePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"urlsToWatch": [
"https://graph.microsoft.com/beta/",
"https://graph.microsoft.us/beta/
",
"https://dod-graph.microsoft.us/beta/",
"https://microsoftgraph.chinacloudapi.cn/beta/
"
]
},
{
"name": "GraphConnectorGuidancePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"urlsToWatch": [
"https://graph.microsoft.com//external/connections//schema",
"https://graph.microsoft.us//external/connections//schema",
"https://dod-graph.microsoft.us//external/connections//schema",
"https://microsoftgraph.chinacloudapi.cn//external/connections//schema"
]
},
{
"name": "GraphSdkGuidancePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "ODataPagingGuidancePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "GraphClientRequestIdGuidancePlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "GraphRandomErrorPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "graphRandomErrorsPlugin"
},
{
"name": "ExecutionSummaryPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "executionSummaryPlugin"
}
],
"urlsToWatch": [
"https://graph.microsoft.com/v1.0/",
"https://graph.microsoft.com/beta/
",
"https://graph.microsoft.us/v1.0/",
"https://graph.microsoft.us/beta/
",
"https://dod-graph.microsoft.us/v1.0/",
"https://dod-graph.microsoft.us/beta/
",
"https://microsoftgraph.chinacloudapi.cn/v1.0/",
"https://microsoftgraph.chinacloudapi.cn/beta/
"
],
"graphRandomErrorsPlugin": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v1.3.0/graphrandomerrorplugin.schema.json",
"allowedErrors": [
429,
500,
502,
503,
504,
507
],
"rate": 50
},
"executionSummaryPlugin": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v1.3.0/executionsummaryplugin.schema.json",
"groupBy": "url"
},
"labelMode": "text",
"logLevel": "information"
}

Additional Info

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

@waldekmastykarz Good catch and a clear bug on our end. We'll get to fix it asap. Sorry for the trouble and thanks for pointing it out.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…ormat

Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix JSON date format in GraphMockResponsePlugin Fix culture-dependent date formatting in HTTP Date headers Nov 13, 2025
Copilot finished work on behalf of waldekmastykarz November 13, 2025 07:16
Copy link
Collaborator

@waldekmastykarz waldekmastykarz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot The original request was to use the ISO-8601 format

@waldekmastykarz
Copy link
Collaborator

@copilot The original request was to use the ISO-8601 format

Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 13, 2025

@copilot The original request was to use the ISO-8601 format

Changed from RFC 1123 format to ISO-8601 format ("o") as requested. All Date headers now use culture-invariant ISO-8601 format (e.g., 2025-11-13T11:50:18.2823678+00:00). Commit: b630171

Copilot AI changed the title Fix culture-dependent date formatting in HTTP Date headers Fix culture-dependent date formatting in HTTP Date headers using ISO-8601 format Nov 13, 2025
Copilot finished work on behalf of waldekmastykarz November 13, 2025 11:53
@waldekmastykarz
Copy link
Collaborator

@copilot I was wrong. Revert back to using the RFC format you had previously

Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 14, 2025

@copilot I was wrong. Revert back to using the RFC format you had previously

Reverted to RFC 1123 format ("r"). All Date headers now use culture-invariant RFC 1123 format (e.g., Thu, 13 Nov 2025 07:28:00 GMT). Commit: 40793bb

Copilot AI changed the title Fix culture-dependent date formatting in HTTP Date headers using ISO-8601 format Fix culture-dependent date formatting in HTTP Date headers using RFC 1123 format Nov 14, 2025
Copilot finished work on behalf of waldekmastykarz November 14, 2025 11:45
@waldekmastykarz
Copy link
Collaborator

@copilot OK, there's some nuance. When the date is used with response headers, it needs to be in the RFC 2822 format. When the date is used with the InnerError property, it needs to be in the ISO 8601 / RFC 3339 format. Ensure, that if the response uses dates in two places they reflect the same date/time and just differ in format.

Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 14, 2025

@copilot OK, there's some nuance. When the date is used with response headers, it needs to be in the RFC 2822 format. When the date is used with the InnerError property, it needs to be in the `ISO...

Updated to use RFC 1123 format for HTTP Date headers and ISO 8601 format for InnerError.Date property. Both formats now use the same DateTime.Now value to ensure consistency. Commit: 550db0c

Copilot AI changed the title Fix culture-dependent date formatting in HTTP Date headers using RFC 1123 format Fix culture-dependent date formatting using RFC 1123 for HTTP headers and ISO 8601 for InnerError Nov 14, 2025
Copilot finished work on behalf of waldekmastykarz November 14, 2025 12:15
Copy link
Collaborator

@waldekmastykarz waldekmastykarz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot in all occurrences, replace the o format with s

Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 16, 2025

@copilot in all occurrences, replace the o format with s

Replaced all occurrences of "o" format with "s" format. The new format produces sortable ISO 8601 dates without timezone (e.g., 2025-11-16T11:16:59). Commit: 1bb9f12

Copilot AI changed the title Fix culture-dependent date formatting using RFC 1123 for HTTP headers and ISO 8601 for InnerError Fix culture-dependent date formatting using RFC 1123 for HTTP headers and sortable ISO 8601 for InnerError Nov 16, 2025
Copilot finished work on behalf of waldekmastykarz November 16, 2025 11:21
var entry = new HarEntry
{
StartedDateTime = currentTime.ToString("o"),
StartedDateTime = currentTime.ToString("s"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot this needs to be o to match the HAR format

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted HarGeneratorPlugin to use "o" format for HAR specification compliance. The HAR format requires full ISO 8601 with timezone information. Commit: 8ea43c5

Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
Copilot finished work on behalf of waldekmastykarz November 16, 2025 12:03
@waldekmastykarz waldekmastykarz marked this pull request as ready for review November 16, 2025 12:04
Copilot AI review requested due to automatic review settings November 16, 2025 12:04
@waldekmastykarz waldekmastykarz requested a review from a team as a code owner November 16, 2025 12:04
Copilot finished reviewing on behalf of waldekmastykarz November 16, 2025 12:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a culture-dependent date formatting bug where Graph API mock responses displayed dates in different formats depending on the system's regional settings (e.g., 13/11/2025 14:30:00 in French vs 11/13/2025 2:30 PM in US English).

  • Replaces culture-dependent DateTime.Now.ToString(CultureInfo.CurrentCulture) with standardized, culture-invariant formats
  • HTTP Date headers now use RFC 1123 format ("r") per RFC 7231 standard
  • InnerError.Date properties use ISO 8601 sortable format ("s") for consistency with Microsoft Graph

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
MockResponsePlugin.cs Updated HTTP Date header formatting to RFC 1123 format for mock responses
GraphMockResponsePlugin.cs Updated HTTP Date header formatting to RFC 1123 format for both individual and batch mock responses (2 locations)
RetryAfterPlugin.cs Updated both HTTP Date headers (RFC 1123) and InnerError.Date (ISO 8601) in throttling error responses, using same DateTime value for consistency
RateLimitingPlugin.cs Updated both HTTP Date headers (RFC 1123) and InnerError.Date (ISO 8601) in rate limiting error responses, using same DateTime value for consistency
GraphRandomErrorPlugin.cs Updated HTTP Date headers (RFC 1123) and InnerError.Date (ISO 8601) in random error responses (2 locations), using same DateTime value for consistency

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: GraphMockResponsePlugin Mocked JSON date format depends on local machine culture settings

2 participants