1<!DOCTYPE html> 2<html lang="en" data-theme="light"> 3 4<head> 5 <meta charset="UTF-8" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 <link rel="manifest" href="manifest.json" /> 8 <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%239b4dca'><path d='M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5'/></svg>" /> 9 10 <!-- Core SEO Meta Tags --> 11 <title>OData WebAPI Tester Online - Microsoft Dataverse & Dynamics 365 Query Runner</title> 12 <meta name="description" content="Free online developer studio to test, format, validate, and execute Microsoft Dataverse and Dynamics 365 OData Web API queries directly in your browser without sharing credentials. Features multi-line OData syntax editor, visual clause builder, live linter, resizable split screen, and code generator for Xrm.WebApi, Power Automate, C#, and cURL."> 13 <meta name="keywords" content="OData, Dataverse Web API, Dynamics 365, FetchXML vs OData, Web API Tester, OData v4, PowerApps, Power Platform, XrmToolBox, Xrm.WebApi, Dataverse Query Runner, Visual Clause Builder, AshV"> 14 <meta name="author" content="Ashish Vishwakarma (AshV)"> 15 <meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1"> 16 <link rel="canonical" href="https://www.ashishvishwakarma.com/webapi-tester/"> 17 <link rel="author" href="https://www.ashishvishwakarma.com/"> 18 19 <!-- Theme & Mobile Web App Capabilities --> 20 <meta name="theme-color" content="#9b4dca"> 21 <meta name="color-scheme" content="light dark"> 22 <meta name="apple-mobile-web-app-capable" content="yes"> 23 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> 24 <meta name="apple-mobile-web-app-title" content="WebAPI Tester"> 25 26 <!-- OpenGraph / Social Media Meta Tags --> 27 <meta property="og:type" content="website"> 28 <meta property="og:site_name" content="OData WebAPI Tester Online"> 29 <meta property="og:url" content="https://www.ashishvishwakarma.com/webapi-tester/"> 30 <meta property="og:title" content="OData WebAPI Tester Online - Microsoft Dataverse & Dynamics 365 Query Runner"> 31 <meta property="og:description" content="Test, format, validate, and execute Microsoft Dataverse and Dynamics 365 OData Web API queries in browser with zero credentials. Multi-line editor, visual clause builder, split screen, and code generator."> 32 <meta property="og:locale" content="en_US"> 33 34 <!-- Twitter Card Meta Tags --> 35 <meta name="twitter:card" content="summary_large_image"> 36 <meta name="twitter:url" content="https://www.ashishvishwakarma.com/webapi-tester/"> 37 <meta name="twitter:title" content="OData WebAPI Tester Online - Microsoft Dataverse & Dynamics 365 Query Runner"> 38 <meta name="twitter:description" content="Test, format, validate, and execute Microsoft Dataverse and Dynamics 365 OData Web API queries in browser with zero credentials. Multi-line editor, visual clause builder, split screen, and code generator."> 39 40 <!-- Structured Data: JSON-LD Schema (WebApplication, FAQPage, HowTo) --> 41
41<script type="application/ld+json"> 42 { 43 "@context": "https://schema.org", 44 "@graph": [ 45 { 46 "@type": "WebApplication", 47 "@id": "https://www.ashishvishwakarma.com/webapi-tester/#webapp", 48 "name": "OData WebAPI Tester Online", 49 "url": "https://www.ashishvishwakarma.com/webapi-tester/", 50 "applicationCategory": "DeveloperApplication", 51 "operatingSystem": "All (Web Browser)", 52 "browserRequirements": "Requires JavaScript. Requires HTML5.", 53 "description": "Test, format, validate, and execute Microsoft Dataverse and Dynamics 365 OData Web API queries directly in your browser without sharing credentials.", 54 "author": { 55 "@type": "Person", 56 "name": "Ashish Vishwakarma", 57 "url": "https://www.ashishvishwakarma.com/", 58 "sameAs": [ 59 "https://www.linkedin.com/in/ashishvishwakarma-ashv", 60 "https://github.com/AshV" 61 ] 62 }, 63 "offers": { 64 "@type": "Offer", 65 "price": "0", 66 "priceCurrency": "USD" 67 }, 68 "featureList": [ 69 "Test OData Web API queries in browser with zero credentials via SSO", 70 "Multi-line formatted OData editor with real-time syntax validator and linter", 71 "Visual Clause Builder with field-by-field conditions and nested expand relations", 72 "Resizable split screen comparing Code Editor and Visual Builder side-by-side", 73 "Multi-environment management shared with QDV and FetchXmlTester", 74 "Dataverse Prefer request headers management (FormattedValue)", 75 "Multi-language code generator for Xrm.WebApi, Power Automate, C#, cURL, Fetch, PowerShell", 76 "Preloaded Dataverse query templates library", 77 "Dark and Light theme support" 78 ] 79 }, 80 { 81 "@type": "FAQPage", 82 "@id": "https://www.ashishvishwakarma.com/webapi-tester/#faq", 83 "mainEntity": [ 84 { 85 "@type": "Question", 86 "name": "How do I test Microsoft Dataverse OData queries without sharing credentials?", 87 "acceptedAnswer": { 88 "@type": "Answer", 89 "text": "OData WebAPI Tester executes queries directly within your authenticated browser session via native Single Sign-On (SSO) in a new tab. No passwords, client secrets, or tokens are ever stored or transmitted to external servers." 90 } 91 }, 92 { 93 "@type": "Question", 94 "name": "How do I format and beautify long OData Web API queries?", 95 "acceptedAnswer": { 96 "@type": "Answer", 97 "text": "Paste your raw OData query URL into the Request URI bar or type directly into the Code Editor. Click Beautify to format query clauses across multiple indented lines with structured nested $expand relations." 98 } 99 }, 100 { 101 "@type": "Question", 102 "name": "Can I use Visual Clause Builder and Code Editor side-by-side in split screen?", 103 "acceptedAnswer": { 104 "@type": "Answer", 105 "text": "Yes. Select the Split View option on the toolbar to display the Code Editor and Visual Clause Builder side-by-side with an interactive resizable divider. Any changes in one pane automatically synchronize with the other in real time." 106 } 107 }, 108 { 109 "@type": "Question", 110 "name": "How do I copy Dataverse queries into Power Automate or JavaScript?", 111 "acceptedAnswer": { 112 "@type": "Answer", 113 "text": "Click Code Gen in the toolbar to generate ready-to-paste snippets for Xrm.WebApi.retrieveMultipleRecords, Power Automate List rows parameters, Fetch API, C# HttpClient, cURL, and PowerShell." 114 } 115 } 116 ] 117 }, 118 { 119 "@type": "HowTo", 120 "@id": "https://www.ashishvishwakarma.com/webapi-tester/#howto", 121 "name": "How to Test Dataverse OData Web API Queries Online", 122 "description": "Step-by-step guide to run OData v4 queries against Microsoft Dataverse without third-party credentials.", 123 "step": [ 124 { 125 "@type": "HowToStep", 126 "name": "Connect Dataverse Environment", 127 "text": "Add or select your Dynamics 365 or Microsoft Dataverse organization URL in the Environment Manager." 128 }, 129 { 130 "@type": "HowToStep", 131 "name": "Build or Paste OData Query", 132 "text": "Compose your query using the multi-line Code Editor, Visual Clause Builder, or preloaded templates." 133 }, 134 { 135 "@type": "HowToStep", 136 "name": "Execute Query", 137 "text": "Click Test OData or press Ctrl+Enter to execute the query via Web API GET in your authenticated browser session." 138 } 139 ] 140 } 141 ] 142 } 143 </script>
143 144 145 <!-- Stylesheets --> 146 <link rel="stylesheet" type="text/css" href="styles/codemirror.css" /> 147 <link rel="stylesheet" type="text/css" href="styles/odata-theme.css" /> 148 <link rel="stylesheet" type="text/css" href="styles/style.css" /> 149</head> 150 151<body> 152 <!-- NoScript SEO Fallback for Web Crawlers and Search Engines --> 153 <noscript> 154 <div class="crawler-noscript-content"> 155 <h1>OData WebAPI Tester Online - Microsoft Dataverse & Dynamics 365 Query Runner</h1> 156 <p><strong>OData WebAPI Tester</strong> is a 100% client-side developer studio designed to format, validate, test, and execute Microsoft Dataverse and Dynamics 365 OData v4 Web API queries directly in your browser with zero credential sharing.</p> 157 158 <h2>Key Features</h2> 159 <ul> 160 <li><strong>Browser Single Sign-On (SSO):</strong> Safely test queries in your authenticated Dataverse session with zero credentials, tokens, or proxies stored or transmitted.</li> 161 <li><strong>Multi-line OData Code Editor:</strong> Real-time syntax highlighting, bracket matching, indentation, and live OData linter for queries.</li> 162 <li><strong>Visual Clause Builder:</strong> Build complex OData queries visually with entity sets, field-by-field conditions, operators, and nested <code>$expand</code> relationships.</li> 163 <li><strong>Resizable Split Screen:</strong> Inspect Code Editor and Visual Clause Builder side-by-side with real-time bidirectional synchronization.</li> 164 <li><strong>Environment Manager:</strong> Seamlessly switch between development, UAT, and production tenants. Interoperable with FetchXmlTester and Quick Data Viewer (QDV).</li> 165 <li><strong>Code Generator:</strong> Generate production-ready code snippets for <code>Xrm.WebApi.retrieveMultipleRecords</code>, Power Automate Flow (List rows), C# HttpClient, cURL, Fetch API, and PowerShell.</li> 166 </ul> 167 168 <h2>OData Query Syntax Reference</h2> 169 <p>Supported system query options in Dataverse OData v4:</p> 170 <ul> 171 <li><code>$select</code>: Comma-separated list of attributes to return (e.g. <code>$select=name,telephone1,address1_city</code>).</li> 172 <li><code>$filter</code>: Boolean expression to filter rows (e.g. <code>$filter=statecode eq 0 and (contains(name,'Contoso') or address1_city eq 'Seattle')</code>).</li> 173 <li><code>$expand</code>: Semicolon-delimited nested relationship queries (e.g. <code>$expand=primarycontactid($select=fullname,emailaddress1;$filter=donotemail eq false)</code>).</li> 174 <li><code>$orderby</code>: Sort order for results (e.g. <code>$orderby=createdon desc</code>).</li> 175 <li><code>$top</code>: Number of rows to return per page (e.g. <code>$top=50</code>).</li> 176 <li><code>$count</code>: Boolean flag to return the total row count (e.g. <code>$count=true</code>).</li> 177 </ul> 178 179 <h2>Frequently Asked Questions</h2> 180 <h3>How do I test Microsoft Dataverse OData queries without sharing credentials?</h3> 181 <p>OData WebAPI Tester executes queries directly within your authenticated browser session via native Single Sign-On (SSO) in a new tab. No passwords, client secrets, or tokens are ever stored or transmitted to external servers.</p> 182 183 <h3>How do I format and beautify long OData Web API queries?</h3> 184 <p>Paste your raw OData query URL into the Request URI bar or type directly into the Code Editor. Click Beautify to format query clauses across multiple indented lines with structured nested $expand relations.</p> 185 186 <h3>Can I use Visual Clause Builder and Code Editor side-by-side in split screen?</h3> 187 <p>Yes. Select the Split View option on the toolbar to display the Code Editor and Visual Clause Builder side-by-side with an interactive resizable divider. Any changes in one pane automatically synchronize with the other in real time.</p> 188 189 <h3>How do I copy Dataverse queries into Power Automate or JavaScript?</h3> 190 <p>Click Code Gen in the toolbar to generate ready-to-paste snippets for Xrm.WebApi.retrieveMultipleRecords, Power Automate List rows parameters, Fetch API, C# HttpClient, cURL, and PowerShell.</p> 191 </div> 192 </noscript> 193 194 <div class="app-container"> 195 <!-- Main Studio Card --> 196 <main class="studio-main-card" role="main"> 197 <!-- Studio Toolbar Header --> 198 <header class="editor-toolbar" role="toolbar" aria-label="Editor controls and environment manager"> 199 <div class="toolbar-content-area"> 200 <!-- Row 1: Environment Manager Strip --> 201 <div class="env-manager-strip"> 202 <div class="env-status-side">
203 <span class="env-label">Environment:</span> 204 <div id="envActiveIndicatorBox" class="env-active-indicator-box" title="Active Dataverse Environment" onclick="EnvManager.openModal()"> 205 <span id="envStatusDot" class="status-dot offline"></span> 206 <span id="envActiveLabel">No environment selected</span> 207 </div> 208 </div> 209 210 <div class="env-pills-side"> 211 <div id="envPillsRow" class="env-pills-row"> 212 <!-- Injected dynamically by env-manager.js --> 213 </div> 214 <button class="btn-secondary" onclick="EnvManager.openModal()" title="Add or manage Dataverse environments (Ctrl+K)"> 215 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 216 <line x1="12" y1="5" x2="12" y2="19"></line> 217 <line x1="5" y1="12" x2="19" y2="12"></line> 218 </svg> 219 <span>Add / Manage</span> 220 </button> 221 </div> 222 </div> 223 224 <!-- Row 2: Query Title and Action Controls --> 225 <div class="toolbar-controls"> 226 <!-- Query Name Box --> 227 <div class="query-name-box"> 228 <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 229 <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> 230 <polyline points="14 2 14 8 20 8"></polyline> 231 <line x1="16" y1="13" x2="8" y2="13"></line> 232 <line x1="16" y1="17" x2="8" y2="17"></line> 233 </svg> 234 <input id="queryName" type="text" placeholder="What is this query for? (e.g., Active Accounts with Contacts)" autocomplete="off" /> 235 </div> 236 237 <!-- View Mode Switcher (Code Editor vs Visual Clause Builder vs Split Screen) --> 238 <div class="view-mode-switch" title="Switch view layout: Code Editor, Visual Clause Builder, or Resizable Split Screen"> 239 <button id="btnViewCode" class="view-mode-btn active" onclick="switchStudioView('code')"> 240 <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg> 241 <span>Code</span> 242 </button> 243 <button id="btnViewVisual" class="view-mode-btn" onclick="switchStudioView('visual')"> 244 <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg> 245 <span>Visual Builder</span> 246 </button> 247 <button id="btnViewSplit" class="view-mode-btn" onclick="switchStudioView('split')" title="View Code and Visual Builder side-by-side in resizable split screen"> 248 <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="12" y1="3" x2="12" y2="21"></line></svg> 249 <span>Split</span> 250 </button> 251 </div> 252 253 <!-- Action Buttons Group --> 254 <div class="toolbar-actions-group"> 255 <!-- Syntax Validation Pill --> 256 <div id="statusPill" class="status-pill valid" title="OData syntax validation status"> 257 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"> 258 <polyline points="20 6 9 17 4 12"></polyline> 259 </svg>
260 <span>Valid OData</span> 261 </div> 262 263 <!-- Beautify Button --> 264 <button id="btnBeautify" class="btn-tool" onclick="beautifyQuery()" title="Format and indent OData clauses (Ctrl+Shift+F)"> 265 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 266 <line x1="21" y1="10" x2="3" y2="10"></line> 267 <line x1="21" y1="6" x2="3" y2="6"></line> 268 <line x1="21" y1="14" x2="3" y2="14"></line> 269 <line x1="21" y1="18" x2="3" y2="18"></line> 270 </svg> 271 <span>Beautify</span> 272 </button> 273 274 <!-- Minify Button --> 275 <button id="btnMinify" class="btn-tool" onclick="minifyQuery()" title="Minify query to a single line"> 276 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 277 <polyline points="4 14 10 14 10 20"></polyline> 278 <polyline points="20 10 14 10 14 4"></polyline> 279 <line x1="14" y1="10" x2="21" y2="3"></line> 280 <line x1="3" y1="21" x2="10" y2="14"></line> 281 </svg> 282 <span>Minify</span> 283 </button> 284 285 <!-- Templates Modal Button --> 286 <button id="btnTemplates" class="btn-tool" onclick="QueryLibrary.openTemplatesModal()" title="Browse common Dataverse OData templates"> 287 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 288 <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> 289 <line x1="3" y1="9" x2="21" y2="9"></line> 290 <line x1="9" y1="21" x2="9" y2="9"></line> 291 </svg> 292 <span>Templates</span> 293 </button> 294 295 <!-- Code Generator Button --> 296 <button id="btnCodeGen" class="btn-tool" onclick="openCodeGenerator()" title="Generate Xrm.WebApi, Flow, C#, or cURL code"> 297 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 298 <polyline points="16 18 22 12 16 6"></polyline> 299 <polyline points="8 6 2 12 8 18"></polyline> 300 </svg> 301 <span>Code Gen</span> 302 </button> 303 304 <!-- Open File Button --> 305 <button id="btnOpenFile" class="btn-tool" onclick="openLocalQueryFile()" title="Load OData query from a local file (Ctrl+O)"> 306 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 307 <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path> 308 </svg> 309 <span>Open</span> 310 </button> 311 312 <!-- Share Link Button --> 313 <button id="btnShareLink" class="btn-tool" onclick="shareQueryLink()" title="Copy sharable URL containing this query and environment"> 314 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 315 <circle cx="18" cy="5" r="3"></circle> 316 <circle cx="6" cy="12" r="3"></circle> 317 <circle cx="18" cy="19" r="3"></circle> 318 <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line> 319 <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line> 320 </svg>
321 <span>Share</span> 322 </button> 323 324 <!-- Save to Library Button --> 325 <button id="btnSaveLibrary" class="btn-tool btn-tool-accent" onclick="saveQueryToLibrary()" title="Save query to browser library (Ctrl+S)"> 326 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 327 <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path> 328 <polyline points="17 21 17 13 7 13 7 21"></polyline> 329 <polyline points="7 3 7 8 15 8"></polyline> 330 </svg> 331 <span>Save</span> 332 </button> 333 334 <!-- Saved Queries Button --> 335 <button id="btnOpenSavedQueries" class="btn-tool" onclick="QueryLibrary.openModal()" title="View and load saved queries"> 336 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 337 <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path> 338 <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path> 339 </svg> 340 <span>Library</span> 341 <span id="savedQueriesBadge" class="headers-badge">0</span> 342 </button> 343 344 <!-- Documentation & FAQ Guide Button --> 345 <button id="btnDocsModal" class="btn-tool" onclick="openDocsModal()" title="Browse Dataverse OData v4 reference, syntax guide, and FAQ"> 346 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 347 <circle cx="12" cy="12" r="10"></circle> 348 <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path> 349 <line x1="12" y1="17" x2="12.01" y2="17"></line> 350 </svg> 351 <span>Docs & FAQ</span> 352 </button> 353 354 <!-- Theme Toggle Button --> 355 <button id="themeToggleBtn" class="btn-icon" onclick="toggleTheme()" title="Toggle Light/Dark Theme" aria-label="Toggle Theme"> 356 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 357 <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> 358 </svg> 359 </button> 360 </div> 361 </div> 362 </div> 363 364 <!-- Brand Logo (Right Side) with Semantic H1 for SEO --> 365 <div class="brand-logo-badge"> 366 <h1 class="brand-title-h1"> 367 <a href="https://www.ashishvishwakarma.com/" target="_blank" class="brand-logo-link brand-title" title="Developer Studio by Ashish Vishwakarma">WebAPI Studio</a> 368 </h1> 369 <span class="brand-subtitle">Dataverse • OData v4</span> 370 </div> 371 </header> 372 373 <!-- Studio Workspace Area: Supports 'code', 'visual', and 'split' layout modes --> 374 <div id="studioWorkspace" class="studio-workspace-area" data-view="code"> 375 <!-- Code Editor Pane --> 376 <div id="editorPane" class="workspace-pane editor-pane"> 377 <div id="editorContainer" class="editor-container"> 378 <textarea id="odataEditor" wrap="off"></textarea> 379 380 <!-- Floating Validation Error Banner --> 381 <div id="validationToastBar" class="validation-toast-bar"> 382 <div class="validation-error-text"> 383 <svg width="16" height="16" viewB
383ox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 384 <circle cx="12" cy="12" r="10"></circle> 385 <line x1="12" y1="8" x2="12" y2="12"></line> 386 <line x1="12" y1="16" x2="12.01" y2="16"></line> 387 </svg> 388 <span id="validationErrorText">OData syntax error detected</span> 389 </div> 390 <button class="btn-sm-secondary" onclick="document.getElementById('validationToastBar').classList.remove('active')">Dismiss</button> 391 </div> 392 </div> 393 </div> 394 395 <!-- Resizable Divider Splitter Handle --> 396 <div id="workspaceSplitter" class="workspace-splitter" title="Drag to resize split view"> 397 <div class="splitter-handle-bar"></div> 398 </div> 399 400 <!-- Visual Clause Builder Pane --> 401 <div id="visualBuilderPane" class="workspace-pane visual-builder
401-pane"> 402 <div id="visualBuilderContainer" class="visual-builder-container"> 403 <!-- Injected dynamically by clause-builder.js --> 404 </div> 405 </div> 406 </div> 407 408 <!-- Studio Bottom Configuration & Execution Bar --> 409 <footer class="studio-bottom-panel"> 410 <div class="bottom-actions-row"> 411 <!-- HTTP Method & Version Selector --> 412 <div class="method-version-pill" title="Target Web API endpoint version"> 413 <span class="method-tag">GET</span> 414 <select id="apiVersionSelect" class="version-select" aria-label="Dataverse API Version"> 415 <option value="v9.2" selected>v9.2</option> 416 <option value="v9.1">v9.1</option> 417 <option value="v9.0">v9.0</option> 418 </select> 419 </div> 420 421 <!-- Request URI Box (Editable with bidirectional sync) --> 422 <div class="request-uri-box"> 423 <input id="requestURI" type="text" placeholder="Generated WebAPI Request URI... Paste any raw OData URL to parse" spellcheck="false" autocomplete="off" title="WebAPI Request URI (Live sync with editor; paste any URL here)" /> 424 <button id="btnCopyUri" class="uri-copy-btn" onclick="copyRequestUri()" title="Copy WebAPI Request URI to clipboard"> 425 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 426 <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect> 427 <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path> 428 </svg> 429 <span id="copyUriLabel">Copy</span> 430 </button> 431 </div> 432 433 <!-- Prefer Headers Button --> 434 <button class="btn-headers-pref" onclick="openHeadersModal()" title="Configure Dataverse Prefer headers (Formatted Values, Page Size)"> 435 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 436 <line x1="4" y1="21" x2="4" y2="14"></line> 437 <line x1="4" y1="10" x2="4" y2="3"></line> 438 <line x1="12" y1="21" x2="12" y2="12"></line> 439 <line x1="12" y1="8" x2="12" y2="3"></line> 440 <line x1="20" y1="21" x2="20" y2="16"></line> 441 <line x1="20" y1="12" x2="20" y2="3"></line> 442 <line x1="1" y1="14" x2="7" y2="14"></line> 443 <line x1="9" y1="8" x2="15" y2="8"></line> 444 <line x1="17" y1="16" x2="23" y2="16"></line> 445 </svg> 446 <span>Headers</span> 447 <span id="headersCountBadge" class="headers-badge">1</span> 448 </button> 449 450 <!-- Test OData Primary Button --> 451 <button id="testButton" class="btn-primary-test" onclick="testOData()" title="Execute query in Microsoft Dynamics 365 WebAPI (Ctrl+Enter)"> 452 <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> 453 <polygon points="5 3 19 12 5 21 5 3"></polygon> 454 </svg> 455 <span>Test OData</span> 456 </button> 457 </div> 458 459 <!-- Hidden inputs for cross-compatibility --> 460 <input type="hidden" id="orgURL" /> 461 </footer> 462 </main> 463 </div> 464 465 <!-- ========================================================================= --> 466 <!-- Modals --> 467 <!-- ========================================================================= --> 468 469 <!-- Environment Context Studio Modal (Shared with QDV & FetchXmlTester) --> 470 <div id="envModal" class="modal-overlay" onclick="if(event.target === this) EnvManager.closeModal()"> 471 <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="modalTitle"> 472 <div class="modal-header"> 473 <div class="modal-title-group"> 474 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2.2"> 475 <rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect> 476 <rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect> 477 <line x1="6" y1="6" x2="6.01" y2="6"></line>
478 <line x1="6" y1="18" x2="6.01" y2="18"></line> 479 </svg> 480 <h3 id="modalTitle">Environment Context Studio</h3> 481 </div> 482 <button class="modal-close-btn" onclick="EnvManager.closeModal()" title="Close (Esc)" aria-label="Close">â</button> 483 </div> 484 485 <div class="modal-body"> 486 <p class="modal-desc"> 487 Connect your Microsoft Dataverse / Dynamics 365 environments. Select an environment to execute OData queries directly in your browser session with zero credentials. 488 </p> 489 490 <div class="env-input-wrapper"> 491 <div class="input-with-icon"> 492 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 493 <circle cx="12" cy="12" r="10"></circle> 494 <line x1="2" y1="12" x2="22" y2="12"></line> 495 <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path> 496 </svg> 497 <input id="txtModalEnv" type="url" placeholder="https://org.crm.dynamics.com" autocomplete="off" spellcheck="false" /> 498 </div> 499 <button id="btnModalAddEnv" class="btn-primary" onclick="EnvManager.handleAddFromModal()"> 500 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> 501 <line x1="12" y1="5" x2="12" y2="19"></line> 502 <line x1="5" y1="12" x2="19" y2="12"></line> 503 </svg> 504 <span>Add</span> 505 </button> 506 </div> 507 <p style="font-size: 0.75rem; color: var(--text-muted); margin-top: -0.5rem; margin-bottom: 1rem; line-height: 1.4;"> 508 Tip: Full app URLs, paths, and query parameters (e.g. /main.aspx?appid=...) are automatically sanitized on paste. 509 </p> 510 511 <div> 512 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.6rem;"> 513 <span style="font-size: 0.85rem; font-weight: 700; color: var(--text-main);">Saved Environments</span> 514 <span id="modalEnvCount" style="font-size: 0.75rem; color: var(--text-muted); font-weight: 600;">0 saved</span> 515 </div> 516 <div id="modalEnvList" class="env-tags-list"> 517 <!-- Populated dynamically --> 518 </div> 519 </div> 520 </div> 521 522 <div class="modal-footer"> 523 <p style="margin: 0; display: flex; align-items: center; gap: 0.4rem;"> 524 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 525 <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> 526 </svg> 527 <span>100% Client-Side Browser SSO. Credentials are never stored, transmitted, or proxied.</span> 528 </p> 529 </div> 530 </div> 531 </div> 532 533 <!-- Saved Queries Library Modal --> 534 <div id="savedQueriesModal" class="modal-overlay" onclick="if(event.target === this) QueryLibrary.closeModal()"> 535 <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="savedQueriesTitle"> 536 <div class="modal-header"> 537 <div class="modal-title-group"> 538 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2.2"> 539 <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path> 540 <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path> 541 </svg> 542 <h3 id="savedQueriesTitle">Saved Queries Library</h3> 543 </div> 544 <button class="modal-close-btn" onclick="QueryLibrary.closeModal()" title="Close (Esc)" aria-label="Close">â</button> 545 </div> 546 547 <div class="modal-body"> 548 <p class="modal-desc"> 549 Your frequently used OData Web API queries stored securely in browser local storage. Click any query to load it into the editor. 550 </p> 551 552 <div class="input-with-icon" style="margin-bottom: 1rem;">
553 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 554 <circle cx="11" cy="11" r="8"></circle> 555 <line x1="21" y1="21" x2="16.65" y2="16.65"></line> 556 </svg> 557 <input id="txtSearchSavedQueries" type="text" placeholder="Search saved queries..." autocomplete="off" /> 558 </div> 559 560 <div id="savedQueriesList" class="saved-queries-list"> 561 <!-- Populated dynamically --> 562 </div> 563 </div> 564 565 <div class="modal-footer" style="justify-content: space-between;"> 566 <span id="savedQueriesCountLabel">0 queries saved</span> 567 <div style="display: flex; gap: 0.5rem;"> 568 <button class="btn-secondary" onclick="document.getElementById('importFileInput').click()" title="Import queries from JSON"> 569 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 570 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path> 571 <polyline points="17 8 12 3 7 8"></polyline> 572 <line x1="12" y1="3" x2="12" y2="15"></line> 573 </svg> 574 <span>Import</span> 575 </button> 576 <button class="btn-secondary" onclick="QueryLibrary.exportJson()" title="Export saved queries to JSON"> 577 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 578 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path> 579 <polyline points="7 10 12 15 17 10"></polyline> 580 <line x1="12" y1="15" x2="12" y2="3"></line> 581 </svg> 582 <span>Export JSON</span> 583 </button> 584 </div> 585 </div> 586 </div> 587 </div> 588 589 <!-- Preloaded Templates Modal --> 590 <div id="templatesModal" class="modal-overlay" onclick="if(event.target === this) QueryLibrary.closeTemplatesModal()"> 591 <div class="modal-content wide" role="dialog" aria-modal="true" aria-labelledby="templatesTitle"> 592 <div class="modal-header"> 593 <div class="modal-title-group"> 594 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2.2"> 595 <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> 596 <line x1="3" y1="9" x2="21" y2="9"></line> 597 <line x1="9" y1="21" x2="9" y2="9"></line> 598 </svg> 599 <h3 id="templatesTitle">Dataverse OData Templates</h3> 600 </div> 601 <button class="modal-close-btn" onclick="QueryLibrary.closeTemplatesModal()" title="Close (Esc)" aria-label="Close">â</button> 602 </div> 603 604 <div class="modal-body"> 605 <p class="modal-desc"> 606 Ready-to-use Dataverse query patterns illustrating nested expands, CRM date functions, the CRM.In operator, aggregations, and metadata exploration. 607 </p> 608 609 <div id="templatesList" class="templates-grid"> 610 <!-- Populated dynamically --> 611 </div> 612 </div> 613 614 <div class="modal-footer"> 615 <button class="btn-secondary" onclick="QueryLibrary.closeTemplatesModal()">Close</button> 616 </div> 617 </div> 618 </div> 619 620 <!-- Code Generator Modal --> 621 <div id="codeGenModal" class="modal-overlay" onclick="if(event.target === this) CodeGenerator.closeModal()"> 622 <div class="modal-content wide" role="dialog" aria-modal="true" aria-labelledby="codeGenTitle"> 623 <div class="modal-header"> 624 <div class="modal-title-group"> 625 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2.2"> 626 <polyline points="16 18 22 12 16 6"></polyline> 627 <polyline points="8 6 2 12 8 18"></polyline> 628 </svg> 629 <h3 id="codeGenTitle">Code Snippet Generator</h3> 630 </div> 631 <button class="modal-close-btn" onclick="CodeGenerator.closeModal()" title="Close (Esc)" aria-label="Close">â</button> 632 </div> 633 634 <div class="modal-body" id="codeGenContent"> 635 <div class="code-gen-tabs"> 636 <button class="code-tab-btn active" data-tab="xrm" onclick="CodeGenerator.switchTab('xrm')">Xrm.WebApi (JS)</button> 637 <button class="code-tab-btn" data-tab="flow" onclick="CodeGenerator.switchTab('flow')">Power Automate</button> 638 <button class="code-tab-btn" data-tab="fetch" onclick="CodeGenerator.switchTab('fetch')">Fetch API</button> 639 <button class="code-tab-btn" data-tab="csharp" onclick="CodeGenerator.switchTab('csharp')">C# (HttpClient)</button> 640 <button class="code-tab-btn" data-tab="curl" onclick="CodeGenerator.switchTab('curl')">cURL</button> 641 <button class="code-tab-btn" data-tab="powershell" onclick="CodeGenerator.switchTab('powershell')">PowerShell</button> 642 </div> 643 644 <div class="code-snippet-box"> 645 <button class="btn-snippet-copy" onclick="copyCodeSnippet()">Copy Code</button> 646 <pre id="codeSnippetArea" class="code-snippet-pre"></pre> 647 </div> 648 </div> 649 650 <div class="modal-footer"> 651 <button class="btn-secondary" onclick="CodeGenerator.closeModal()">Close</button> 652 </div> 653 </div> 654 </div> 655 656 <!-- Dataverse Request Headers Modal --> 657 <div id="headersModal" class="modal-overlay" onclick="if(event.target === this) closeHeadersModal()"> 658 <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="headersTitle"> 659 <div class="modal-header"> 660 <div class="modal-title-group"> 661 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2.2"> 662 <line x1="4" y1="21" x2="4" y2="14"></line> 663 <line x1="4" y1="10" x2="4" y2="3"></line> 664 <line x1="12" y1="21" x2="12" y2="12"></line> 665 <line x1="12" y1="8" x2="12" y2="3"></line> 666 <line x1="20" y1="21" x2="20" y2="16"></line> 667 <line x1="20" y1="12" x2="20" y2="3"></line> 668 </svg> 669 <h3 id="headersTitle">Dataverse Request Headers</h3> 670 </div> 671 <button class="modal-close-btn" onclick="closeHeadersModal()" title="Close (Esc)" aria-label="Close">â</button> 672 </div> 673 674 <div class="modal-body"> 675 <p class="modal-desc"> 676 Configure standard Dataverse Prefer headers passed to code generators and cURL/Fetch executions.
677 </p> 678 679 <div class="headers-options-list"> 680 <label class="header-option-item"> 681 <input type="checkbox" class="header-checkbox" value='odata.include-annotations="OData.Community.Display.V1.FormattedValue"' checked /> 682 <div class="header-option-info"> 683 <span class="header-option-title">Include Formatted Values</span> 684 <span class="header-option-desc">Returns human-readable text for optionsets, lookups, dates, and currency.</span> 685 <code class="header-option-code">Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"</code> 686 </div> 687 </label> 688 689 <label class="header-option-item"> 690 <input type="checkbox" class="header-checkbox" value='odata.include-annotations="Microsoft.Dynamics.CRM.associatednavigationproperty"' /> 691 <div class="header-option-info"> 692 <span class="header-option-title">Include Associated Navigation Properties</span> 693 <span class="header-option-desc">Includes lookup navigation property names in the response payload.</span> 694 <code class="header-option-code">Prefer: odata.include-annotations="Microsoft.Dynamics.CRM.associatednavigationproperty"</code> 695 </div> 696 </label> 697 698 <label class="header-option-item"> 699 <input type="checkbox" class="header-checkbox" value='odata.maxpagesize=50' /> 700 <div class="header-option-info"> 701 <span class="header-option-title">Max Page Size (50)</span> 702 <span class="header-option-desc">
702Limits the number of entities returned per page response.</span> 703 <code class="header-option-code">Prefer: odata.maxpagesize=50</code> 704 </div> 705 </label> 706 707 <label class="header-option-item"> 708 <input type="checkbox" class="header-checkbox" value='odata.track-changes' /> 709 <div class="header-option-info"> 710 <span class="header-option-title">Track Changes (Delta Queries)</span> 711 <span class="header-option-desc">Requests a delta token to track subsequent additions and updates.</span> 712 <code class="header-option-code">Prefer: odata.track-changes</code> 713 </div> 714 </label> 715 </div> 716 </div> 717 718 <div class="modal-footer"> 719 <button class="btn-secondary" onclick="closeHeadersModal()">Cancel</button> 720 <button class="btn-primary" onclick="updateSelectedHeaders()">Save Headers</button> 721 </div> 722 </div> 723 </div> 724 725 <!-- Documentation, OData Reference & FAQ Modal --> 726 <div id="docsModal" class="modal-overlay" onclick="if(event.target === this) closeDocsModal()"> 727 <div class="modal-content docs-modal-content" role="dialog" aria-modal="true" aria-labelledby="docsModalTitle"> 728 <div class="modal-header"> 729 <div class="modal-title-group"> 730 <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" stroke-width="2.2"> 731 <circle cx="12" cy="12" r="10"></circle> 732 <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path> 733 <line x1="12" y1="17" x2="12.01" y2="17"></line> 734 </svg> 735 <h3 id="docsModalTitle">Dataverse OData Web API Reference & FAQ</h3> 736 </div> 737 <button class="modal-close-btn" onclick="closeDocsModal()" title="Close (Esc)" aria-label="Close">â</button> 738 </div> 739 740 <!-- Docs Tab Navigation --> 741 <div class="docs-tab-nav"> 742 <button id="docTabBtnSyntax" class="docs-tab-btn active" onclick="switchDocsTab('syntax')">OData Syntax Guide</button> 743 <button id="docTabBtnCrmfuncs" class="docs-tab-btn" onclick="switchDocsTab('crmfuncs')">Dataverse Functions</button> 744 <button id="docTabBtnComparison" class="docs-tab-btn" onclick="switchDocsTab('comparison')">FetchXML vs OData</button> 745 <button id="docTabBtnFaq" class="docs-tab-btn" onclick="switchDocsTab('faq')">Frequently Asked Questions</button> 746 </div> 747 748 <div class="modal-body"> 749 <!-- Tab 1: OData Syntax Guide --> 750 <div id="docsTabSyntax" class="docs-section active"> 751 <div class="docs-block"> 752 <h4 class="docs-heading">System Query Options</h4> 753 <div class="docs-table-wrapper"> 754 <table class="docs-table"> 755 <thead> 756 <tr> 757 <th>Option</th> 758 <th>Description</th> 759 <th>Example</th> 760 </tr> 761 </thead> 762 <tbody> 763 <tr> 764 <td><code>$select</code></td> 765 <td>Comma-delimited list of attributes to retrieve</td> 766 <td><code>$select=name,telephone1,address1_city</code></td> 767 </tr> 768 <tr> 769 <td><code>$filter</code></td> 770 <td>Boolean expression to filter entity rows</td> 771 <td><code>$filter=statecode eq 0 and statuscode eq 1</code></td> 772 </tr> 773 <tr> 774 <td><code>$expand</code></td> 775 <td>Include navigation property records (semicolon-delimited subclauses)</td> 776 <td><code>$expand=primarycontactid($select=fullname,emailaddress1)</code></td> 777 </tr> 778 <tr> 779 <td><code>$orderby</code></td> 780 <td>Sort query results ascending or descending</td> 781 <td><code>$orderby=name asc, createdon desc</code></td> 782 </tr> 783 <tr> 784 <td><code>$top</code></td> 785 <td>Limit the maximum number of rows returned</td> 786 <td><code>$top=50</code></td> 787 </tr> 788 <tr> 789 <td><code>$skip</code></td> 790 <td>Skip specified number of rows in results</td> 791 <td><code>$skip=100</code></td> 792 </tr> 793 <tr> 794 <td><code>$count</code></td> 795 <td>Retrieve total matching record count</td> 796 <td><code>$count=true</code></td> 797 </tr> 798 </tbody> 799 </table> 800 </div> 801 </div> 802 803 <div class="docs-block"> 804 <h4 class="docs-heading">Filter Operators</h4> 805 <div class="docs-table-wrapper"> 806 <table class="docs-table"> 807 <thead> 808 <tr> 809 <th>Operator</th> 810 <th>Type</th> 811 <th>Example</th> 812 </tr> 813 </thead> 814 <tbody> 815 <tr> 816 <td><code>eq</code> / <code>ne</code></td> 817 <td>Equality / Inequality</td> 818 <td><code>statecode eq 0</code>, <code>donotemail ne true</code></td> 819 </tr> 820 <tr> 821 <td><code>gt</code> / <code>ge</code></td> 822 <td>Greater than / or equal</td> 823 <td><code>revenue gt 50000</code>, <code>createdon ge 2026-01-01</code></td> 824 </tr> 825 <tr> 826 <td><code>lt</code> / <code>le</code></td> 827 <td>Less than / or equal</td> 828 <td><code>numberofemployees le 100</code></td> 829 </tr> 830 <tr> 831 <td><code>and</code> / <code>or</code> / <code>not</code></td> 832 <td>Logical Conjunctions</td> 833 <td><code>statecode eq 0 and not (statuscode eq 2)</code></td> 834 </tr> 835 <tr> 836 <td><code>contains(a, b)</code></td> 837 <td>String function</td> 838 <td><code>contains(name, 'Contoso')</code></td> 839 </tr> 840 <tr> 841 <td><code>startswith(a, b)</code></td> 842 <td>String function</td> 843 <td><code>startswith(accountnumber, 'ACC')</code></td> 844 </tr> 845 <tr> 846 <td><code>endswith(a, b)</code></td> 847 <td>String function</td> 848 <td><code>endswith(telephone1, '00')</code></td> 849 </tr> 850 </tbody> 851 </table> 852 </div> 853 </div> 854 855 <div class="docs-callout"> 856 <strong>Important Rule in Dataverse:</strong> Inside nested <code>$expand</code> clauses, nested parameters MUST be separated by <strong>semicolons (<code>;</code>)</strong>, not ampersands (<code>&</code>). For example: <code>$expand=primarycontactid($select=fullname;$filter=donotemail eq false)</code>. 857 </div> 858 </div> 859 860 <!-- Tab 2: Dataverse CRM Query Functions --> 861 <div id="docsTabCrmfuncs" class="docs-section"> 862 <div class="docs-block"> 863 <h4 class="docs-heading">Special Dataverse CRM Filter Functions</h4> 864 <p class="docs-text">Microsoft Dataverse supports specialized CRM query functions prefixed with <code>Microsoft.Dynamics.CRM.</code>:</p> 865 <div class="docs-table-wrapper"> 866 <table class="docs-table"> 867 <thead> 868 <tr> 869 <th>Function</th> 870 <th>Description</th> 871 <th>Example</th> 872 </tr> 873 </thead> 874 <tbody> 875 <tr> 876 <td><code>In(PropertyName='...',PropertyValues=[...])</code></td> 877 <td>Match values in a set</td> 878 <td><code>Microsoft.Dynamics.CRM.In(PropertyName='address1_city',PropertyValues=['Seattle','Chicago'])</code></td> 879 </tr> 880 <tr> 881 <td><code>Between(PropertyName='...',PropertyValues=[...])</code></td> 882 <td>Match range between two values</td> 883 <td><code>
883Microsoft.Dynamics.CRM.Between(PropertyName='revenue',PropertyValues=[10000,50000])</code></td> 884 </tr> 885 <tr> 886 <td><code>EqualUserId(PropertyName='...')</code></td> 887 <td>Current logged-in user</td> 888 <td><code>Microsoft.Dynamics.CRM.EqualUserId(PropertyName='ownerid')</code></td> 889 </tr> 890 <tr> 891 <td><code>Last7Days(PropertyName='...')</code></td> 892 <td>Date in the last 7 days</td> 893 <td><code>Microsoft.Dynamics.CRM.Last7Days(PropertyName='createdon')</code></td> 894 </tr> 895 <tr> 896 <td><code>ThisMonth(PropertyName='...')</code></td> 897 <td>Date within current month</td> 898 <td><code>Microsoft.Dynamics.CRM.ThisMonth(PropertyName='modifiedon')</code></td> 899 </tr> 900 <tr> 901 <td><code>NextXDays(PropertyName='...',PropertyValues=[14])</code></td> 902 <td>Date in next X days</td> 903 <td><code>Microsoft.Dynamics.CRM.NextXDays(PropertyName='scheduledend',PropertyValues=[14])</code></td> 904 </tr> 905 </tbody> 906 </table> 907 </div> 908 </div> 909 </div> 910 911 <!-- Tab 3: FetchXML vs OData --> 912 <div id="docsTabComparison" class="docs-section"> 913 <div class="docs-block"> 914 <h4 class="docs-heading">FetchXML vs OData v4 Web API Quick Reference</h4> 915 <div class="docs-table-wrapper"> 916 <table class="docs-table"> 917 <thead> 918 <tr> 919 <th>FetchXML Element</th> 920 <th>OData v4 Web API Equivalent</th> 921 <th>Notes</th> 922 </tr> 923 </thead> 924 <tbody> 925 <tr> 926 <td><code><entity name="account"></code></td> 927 <td><code>/api/data/v9.2/accounts</code></td> 928 <td>OData uses the plural entity set name</td> 929 </tr> 930 <tr> 931 <td><code><attribute name="name" /></code></td> 932 <td><code>$select=name</code></td> 933 <td>Comma-separated attribute list</td> 934 </tr> 935 <tr> 936 <td><code><filter type="and"></code></td> 937 <td><code>$filter=... and ...</code></td> 938 <td>Logical expression</td> 939 </tr> 940 <tr> 941 <td><code><
941condition attribute="statecode" operator="eq" value="0" /></code></td> 942 <td><code>$filter=statecode eq 0</code></td> 943 <td>Uses <code>eq</code>, <code>ne</code>, <code>gt</code>, etc.</td> 944 </tr> 945 <tr> 946 <td><code><link-entity name="contact" from="contactid" to="primarycontactid"></code></td> 947 <td><code>$expand=primarycontactid(...)</code></td> 948 <td>Uses single-valued navigation property name</td> 949 </tr> 950 <tr> 951 <td><code><order attribute="name" descending="false" /></code></td> 952 <td><code>$orderby=name asc</code></td> 953 <td>Sort direction: <code>asc</code> or <code>desc</code></td> 954 </tr> 955 <tr> 956 <td><code><fetch count="50"></code></td> 957 <td><code>$top=50</code></td> 958 <td>Limits returned records</td> 959 </tr> 960 </tbody> 961 </table> 962 </div> 963 </div> 964 </div> 965 966 <!-- Tab 4: Frequently Asked Questions --> 967 <div id="docsTabFaq" class="docs-section"> 968 <div class="docs-faq-list"> 969 <div class="docs-faq-item"> 970 <button class="docs-faq-question" onclick="toggleFaqAccordion(this)"> 971 <span>How do I test Microsoft Dataverse OData queries without sharing credentials?</span> 972 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg> 973 </button> 974 <div class="docs-faq-answer"> 975 OData WebAPI Tester executes queries directly within your authenticated browser session via native Single Sign-On (SSO) in a new tab. No passwords, client secrets, or bearer tokens are ever stored or transmitted to external servers. Your credentials never leave your browser. 976 </div> 977 </div> 978 979 <div class="docs-faq-item"> 980 <button class="docs-faq-question" onclick="toggleFaqAccordion(this)"> 981 <span>How do I format and beautify long OData Web API queries?</span> 982 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg> 983 </button> 984 <div class="docs-faq-answer"> 985 Paste your raw OData query URL into the Request URI bar or type directly into the Code Editor. Click Beautify (or press Ctrl+Shift+F) to format query clauses across multiple indented lines with structured nested $expand relations. 986 </div> 987 </div> 988 989 <div class="docs-faq-item"> 990 <button class="docs-faq-question" onclick="toggleFaqAccordion(this)"> 991 <span>Can I use Visual Clause Builder and Code Editor side-by-side in split screen?</span> 992 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg> 993 </button> 994 <div class="docs-faq-answer"> 995 Yes. Click the "Split" button on the toolbar. The Code Editor and Visual Clause Builder are displayed side-by-side with an interactive resizable divider. Any changes made in the visual builder immediately update the code editor, and edits in the code editor synchronize with the visual builder in real time. 996 </div> 997 </div> 998 999 <div class="docs-faq-item"> 1000 <button class="docs-faq-question" onclick="toggleFaqAccordion(this)">
1001 <span>How do I copy Dataverse queries into Power Automate or JavaScript?</span> 1002 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg> 1003 </button> 1004 <div class="docs-faq-answer"> 1005 Click "Code Gen" in the toolbar. Select "Power Automate" to view the exact values to paste into the Table Name, Select Columns, Filter Rows, Expand Query, and Sort By inputs of the "List rows" action. You can also select "Xrm.WebApi" for JavaScript, "C#", "cURL", "Fetch API", or "PowerShell". 1006 </div> 1007 </div> 1008 1009 <div class="docs-faq-item"> 1010 <button class="docs-faq-question" onclick="toggleFaqAccordion(this)"> 1011 <span>How do I get formatted values (e.g. OptionSet labels and lookup names)?</span> 1012 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg> 1013 </button> 1014 <div class="docs-faq-answer"> 1015 Click the "Headers" button in the bottom panel and ensure <code>Include Formatted Values</code> is checked. This adds the HTTP header <code>Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"</code>, instructing Dataverse to return human-readable text alongside numerical option set codes and GUIDs. 1016 </div> 1017 </div> 1018 1019 <div class="docs-faq-item"> 1020 <button class="docs-faq-question" onclick="toggleFaqAccordion(this)"> 1021 <span>Can I load queries from a file or URL query string (like FetchXmlTester)?</span> 1022 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg> 1023 </button> 1024 <div class="docs-faq-answer"> 1025 Yes! WebAPI Studio fully supports loading queries from external files and URL query parameters with full FetchXmlTester parity: 1026 <ul style="margin: 0.5rem 0 0 1.25rem; padding: 0;"> 1027 <li><code>?load=<url></code> or <code>?url=<url></code> or <code>?file=<url></code>: Fetches and loads any remote OData query file (including raw GitHub links).</li> 1028 <li><code>?query=<odata></code> or <code>?q=<odata></code>: Directly populates the editor from a URL-encoded query.</li> 1029 <li><code>?env=<org_url></code>: Automatically connects to your specified Dataverse tenant.</li> 1030 <li><code>?view=split</code>: Opens directly in resizable split screen mode.</li> 1031 <li><strong>Open Local File:</strong> Click <strong>Open</strong> in the toolbar (or press Ctrl+O) to load any <code>.odata</code>, <code>.txt</code>, or <code>.json</code> file from your disk.</li> 1032 <li><strong>Share Link:</strong> Click <strong>Share</strong> in the toolbar to generate a one-click link containing your current query and environment.</li> 1033 </ul> 1034 </div> 1035 </div> 1036 </div> 1037 </div> 1038 </div> 1039 1040 <div class="modal-footer"> 1041 <a href="https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/query-data-web-api" target="_blank" style="margin-right: auto; color: var(--primary); text-decoration: none; font-size: 0.8rem; font-weight: 600;"> 1042 Microsoft Official Dataverse Web API Docs → 1043 </a> 1044 <button class="btn-primary" onclick="closeDocsModal()">Got it</button> 1045 </div> 1046 </div> 1047 </div> 1048 1049 <!-- Hidden file inputs --> 1050 <input type="file" id="importFileInput" accept="application/json" style="display: none;" onchange="if(this.files[0]){ QueryLibrary.importJson(this.files[0]).then(n => showToast(`Imported ${n} queries`, 'success')).catch(err => showToast(err.message, 'error')); this.value = ''; }" /> 1051 <input type="file" id="localQueryFileInput" accept=".odata,.txt,.sql,.json,.xml" style="display: none;" onchange="handleLocalQueryFile(this)" /> 1052 1053 <!-- Scripts --> 1054
1054<script src="scripts/plurals.min.js"></script>
1054 1055
1055<script src="js/codemirror.js"></script>
1055 1056
1056<script src="js/matchbrackets.js"></script>
1056 1057
1057<script src="js/active-line.js"></script>
1057 1058
1058<script src="js/odata-mode.js"></script>
1058 1059
1059<script src="js/odata-parser.js"></script>
1059 1060
1060<script src="js/odata-validator.js"></script>
1060 1061
1061<script src="js/env-manager.js"></script>
1061 1062
1062<script src="js/query-library.js"></script>
1062 1063
1063<script src="js/code-generator.js"></script>
1063 1064
1064<script src="js/clause-builder.js"></script>
1064 1065
1065<script src="js/clipboard.min.js"></script>
1065 1066
1066<script src="js/app.js"></script>
vendor: 1 bytes, line 1066
1066
1067<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"ebab263559934616bac4700c60028c1b","r":1,"spa":2}' crossorigin="anonymous"></script>
1067 1068</body> 1069 1070</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.