0

I have a Default.aspx that is defined like this and which I debug using Chrome (which is started from within VS2017 by clicking "Show in browser (Google Chrome)".

<%@ Page Language="C#" CodeBehind="Default.aspx.cs" Inherits="DevelopmentWithADot.AspNetSpeechSynthesizer.Test.Default" %>
<%@ Register Assembly="DevelopmentWithADot.AspNetSpeechSynthesizer" Namespace="DevelopmentWithADot.AspNetSpeechSynthesizer" tagPrefix="web" %>
<%@ Register Assembly="System.Speech, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Speech" TagPrefix="web" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script>

        function onSpeak(text)
        {
            //document.getElementById('synthesizer').speak(text);
            var nSynth = document.getElementById('synthesizer');

            if (nSynth == null)
            {
                debugger; //In internet explorer debugger will be hit directly (if you put a breakpoint). In google chrome, debugger will be hit if the developper tools is open.
                alert('Synthesizer is null!');
            }

            nSynth.speak(text);// I would like to debug what's going on here, but VS doesn't step into my breakpoints in "SpeechSynthesizer.cs"
        }

    </script>
</head>
<body>
    <form runat="server">
    <div>
        <web:SpeechSynthesizer runat="server" ID="synthesizer" Age="Adult" Gender="Male" Culture="en-US" Rate="0" Volume="100" />
        <input type="text" id="text" name="text"/>
        <input type="button" value="SpeakIt" onclick="onSpeak(this.form.text.value)"/>
    </div>
    </form>
</body>
</html>

I would now like to debug what's going on in SpeechSynthesizer.cs (because I don't hear any output, and I would like to find out why).

So the first thing that came to my mind was that I need to step into SpeechSynthesizer.cs which is defined like this:

using System;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Speech.Synthesis;
using System.Threading;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace DevelopmentWithADot.AspNetSpeechSynthesizer
{
    [ConstructorNeedsTag(false)]
    public class SpeechSynthesizer : HtmlGenericControl, ICallbackEventHandler
    {
        private readonly System.Speech.Synthesis.SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer();

        public SpeechSynthesizer() : base("audio")
        {
            this.Age = VoiceAge.NotSet;
            this.Gender = VoiceGender.NotSet;
            this.Culture = CultureInfo.CurrentCulture;
            this.VoiceName = String.Empty;
            this.Ssml = false;
        }

        [DefaultValue("")]
        public String VoiceName { get; set; }

        [DefaultValue(100)]
        public Int32 Volume { get; set; }

        [DefaultValue(0)]
        public Int32 Rate { get; set; }

        [TypeConverter(typeof(CultureInfoConverter))]
        public CultureInfo Culture { get; set; }

        [DefaultValue(VoiceGender.NotSet)]
        public VoiceGender Gender { get; set; }

        [DefaultValue(VoiceAge.NotSet)]
        public VoiceAge Age { get; set; }

        [DefaultValue(false)]
        public Boolean Ssml { get; set; }

        protected override void OnInit(EventArgs e)
        {
            AsyncOperationManager.SynchronizationContext = new SynchronizationContext();

            var sm = ScriptManager.GetCurrent(this.Page);
            var reference = this.Page.ClientScript.GetCallbackEventReference(this, "text", String.Format("function(result){{ document.getElementById('{0}').src = result; document.getElementById('{0}').play(); }}", this.ClientID), String.Empty, true);
            var script = String.Format("\ndocument.getElementById('{0}').speak = function(text){{ {1} }};\n", this.ClientID, reference);

            if (sm != null)
            {
                this.Page.ClientScript.RegisterStartupScript(this.GetType(), String.Concat("speak", this.ClientID), String.Format("Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function() {{ {0} }});\n", script), true);
            }
            else
            {
                this.Page.ClientScript.RegisterStartupScript(this.GetType(), String.Concat("speak", this.ClientID), script, true);
            }

            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            this.Attributes.Remove("class");
            this.Attributes.Remove("src");
            this.Attributes.Remove("preload");
            this.Attributes.Remove("loop");
            this.Attributes.Remove("autoplay");
            this.Attributes.Remove("controls");

            this.Style[HtmlTextWriterStyle.Display] = "none";
            this.Style[HtmlTextWriterStyle.Visibility] = "hidden";

            base.OnPreRender(e);
        }

        public override void Dispose()
        {
            this.synth.Dispose();

            base.Dispose();
        }

        #region ICallbackEventHandler Members

        String ICallbackEventHandler.GetCallbackResult()
        {

            using (var stream = new MemoryStream())
            {
                this.synth.Rate = this.Rate;
                this.synth.Volume = this.Volume;
                this.synth.SetOutputToWaveStream(stream);

                if (String.IsNullOrWhiteSpace(this.VoiceName) == false)
                {
                    this.synth.SelectVoice(this.VoiceName);
                }
                else
                {
                    this.synth.SelectVoiceByHints(this.Gender, this.Age, 0, this.Culture);                  
                }

                if (this.Ssml == false)
                {
                    this.synth.Speak(this.Context.Items["data"] as String);
                }
                else
                {
                    this.synth.SpeakSsml(this.Context.Items["data"] as String);
                }

                return (String.Concat("data:audio/wav;base64,", Convert.ToBase64String(stream.ToArray())));
            }
        }

        void ICallbackEventHandler.RaiseCallbackEvent(String eventArgument)
        {
            this.Context.Items["data"] = eventArgument;
        }

        #endregion
    }
}

However, neither Google Chrome nor VS2017 let me step into SpeechSynthesizer.cs.

How could I debug what's going in there?

Thank you for any advice.

ps: This is the project hierarchy: enter image description here

1 Answer 1

1

You can't step into it from the JavaScript side, but in VS2017 you can set a breakpoint on any of the constructors/methods of SpeechSynthesizer (or any other of your server-side classes). When you make the request from Chrome that uses that constructor/method, VS2017 will stop on the breakpoint, letting you step through the logic.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you. Can you tell me where you'd put a breakpoint? I put breakpoints anywhere, but VS2017 doesn't break there. Perhaps I just put them in the wrong position?
I've added a screenshot of my project hierarchy to the posting. Does that reveal any reason why it might fail to hit my breakpoints? I don't have to upload the first project to the server, right? I guess I couldn't, but I wanted to ask anyway. Also, I can't attach the first project to chrome.exe, it says something like "Invalid in current situation".
@tmighty: You wouldn't normally use the server, you'd use the integrated "IIS Express" in VS2017. It should be simply: Set a breakpoint and press F5 to start the project (assuming you have a web project set as the startup project). With a standard config, that will launch your registered browser with the project's entry point, and when the code reaches a line you have a breakpoint on (in response to a request from the browser), it'll stop on the breakpoint.
@tmighty: Why would a non-web project have Default.aspx, Global.asax, or Web.config? I think you need to take a step back and make sure you have things structured correctly.
Ahhh, thanks. You pointed me to my mistake. The web project wasn't the start project, I didn't notice that. Now it works, thank you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.