diff --git a/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Rendering/BrowserRenderer.ts b/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Rendering/BrowserRenderer.ts
index d3d32f3716..c457a659bc 100644
--- a/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Rendering/BrowserRenderer.ts
+++ b/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Rendering/BrowserRenderer.ts
@@ -168,19 +168,25 @@ export class BrowserRenderer {
const browserRendererId = this.browserRendererId;
const eventHandlerId = renderTreeFrame.attributeEventHandlerId(attributeFrame);
+ if (attributeName === 'value') {
+ if (this.tryApplyValueProperty(toDomElement, renderTreeFrame.attributeValue(attributeFrame))) {
+ return; // If this DOM element type has special 'value' handling, don't also write it as an attribute
+ }
+ }
+
// TODO: Instead of applying separate event listeners to each DOM element, use event delegation
// and remove all the _blazor*Listener hacks
switch (attributeName) {
case 'onclick': {
toDomElement.removeEventListener('click', toDomElement['_blazorClickListener']);
- const listener = () => raiseEvent(browserRendererId, componentId, eventHandlerId, 'mouse', { Type: 'click' });
+ const listener = evt => raiseEvent(evt, browserRendererId, componentId, eventHandlerId, 'mouse', { Type: 'click' });
toDomElement['_blazorClickListener'] = listener;
toDomElement.addEventListener('click', listener);
break;
}
case 'onchange': {
toDomElement.removeEventListener('change', toDomElement['_blazorChangeListener']);
- const listener = evt => raiseEvent(browserRendererId, componentId, eventHandlerId, 'change', { Type: 'change', Value: evt.target.value });
+ const listener = evt => raiseEvent(evt, browserRendererId, componentId, eventHandlerId, 'change', { Type: 'change', Value: evt.target.value });
toDomElement['_blazorChangeListener'] = listener;
toDomElement.addEventListener('change', listener);
break;
@@ -192,7 +198,7 @@ export class BrowserRenderer {
// just to establish that we can pass parameters when raising events.
// We use C#-style PascalCase on the eventInfo to simplify deserialization, but this could
// change if we introduced a richer JSON library on the .NET side.
- raiseEvent(browserRendererId, componentId, eventHandlerId, 'keyboard', { Type: evt.type, Key: (evt as any).key });
+ raiseEvent(evt, browserRendererId, componentId, eventHandlerId, 'keyboard', { Type: evt.type, Key: (evt as any).key });
};
toDomElement['_blazorKeypressListener'] = listener;
toDomElement.addEventListener('keypress', listener);
@@ -208,6 +214,18 @@ export class BrowserRenderer {
}
}
+ tryApplyValueProperty(element: Element, value: string | null) {
+ // Certain elements have built-in behaviour for their 'value' property
+ switch (element.tagName) {
+ case 'INPUT':
+ case 'SELECT': // Note: this doen't handle
+
+
+
Method:
+
+
+
+
+
Request body:
+
+
+
+
+
Request headers:
+ @foreach (var header in requestHeaders)
+ {
+
+ }
+
+
+
+
+
+@if (responseStatusCode.HasValue)
+{
+ Response
+ Status:
@responseStatusCode
+ Body:
+ Headers:
+}
+
+
+
+@functions {
+ string uri = "http://api.icndb.com/jokes/random";
+ string method = "GET";
+ string requestBody = "";
+ List requestHeaders = new List();
+
+ HttpStatusCode? responseStatusCode;
+ string responseBody;
+ string responseHeaders;
+
+ async void DoRequest()
+ {
+ responseStatusCode = null;
+
+ try
+ {
+ var requestMessage = new HttpRequestMessage()
+ {
+ Method = new HttpMethod(method),
+ RequestUri = new Uri(uri),
+ Content = string.IsNullOrEmpty(requestBody)
+ ? null
+ : new StringContent(requestBody)
+ };
+
+ foreach (var header in requestHeaders)
+ {
+ if (!requestMessage.Headers.TryAddWithoutValidation(header.Name, header.Value))
+ {
+ requestMessage.Content?.Headers.TryAddWithoutValidation(header.Name, header.Value);
+ }
+ }
+
+ var response = await Http.SendAsync(requestMessage);
+ responseStatusCode = response.StatusCode;
+ responseBody = await response.Content.ReadAsStringAsync();
+ var allHeaders = response.Headers.Concat(response.Content?.Headers
+ ?? Enumerable.Empty>>());
+ responseHeaders = string.Join(
+ Environment.NewLine,
+ allHeaders.Select(pair => $"{pair.Key}: {pair.Value.First()}").ToArray());
+ }
+ catch (Exception ex)
+ {
+ if (ex is AggregateException)
+ {
+ ex = ex.InnerException;
+ }
+ responseStatusCode = HttpStatusCode.SeeOther;
+ responseBody = ex.Message + Environment.NewLine + ex.StackTrace;
+ }
+
+ StateHasChanged();
+ }
+
+ void AddHeader()
+ => requestHeaders.Add(new RequestHeader());
+
+ void RemoveHeader(RequestHeader header)
+ => requestHeaders.Remove(header);
+
+ class RequestHeader
+ {
+ public string Name { get; set; }
+ public string Value { get; set; }
+ }
+}
diff --git a/test/testapps/BasicTestApp/RouterTest/TestRouter.cshtml b/test/testapps/BasicTestApp/RouterTest/TestRouter.cshtml
index c628df304d..7f16328038 100644
--- a/test/testapps/BasicTestApp/RouterTest/TestRouter.cshtml
+++ b/test/testapps/BasicTestApp/RouterTest/TestRouter.cshtml
@@ -1,4 +1,4 @@
@using Microsoft.AspNetCore.Blazor.Routing
+ PagesNamespace=@nameof(BasicTestApp)
+ DefaultComponentName=@("Default") />
diff --git a/test/testapps/BasicTestApp/wwwroot/index.html b/test/testapps/BasicTestApp/wwwroot/index.html
index 97a440d873..c0e976bb97 100644
--- a/test/testapps/BasicTestApp/wwwroot/index.html
+++ b/test/testapps/BasicTestApp/wwwroot/index.html
@@ -6,16 +6,44 @@
+
+ Select test:
+
+
+
+
+
+
Loading...