Unable to Debug Dynamics C# Plugin in Plugin Registration Tool - c#

Background
I have a C# plugin in Dynamics 2016 on-premise that uses a library to make calls to other systems. Part of that library is a call to dynamics using the Web API. The Plugin is taking action as I can see the changes in dynamics, however I am expecting it to take a different action than it is taking. When I try to debug the plugin using the Plugin Registration tool, I am running into some issues. When I profile the plugin using the Exception method, I get an exception file that I am able to debug through to a point. When I get to the below code, the Plugin Registration Tool crashes without an error message. When I debug using the Persist to Entity Method, my plugin appears to succeed, but no Profiles are logged in the Plugin Registration Tool. My plugin is fired from an action which is triggered from a workflow that is attached to the completion of a Business Process Flow (this is based on this article). My initial question is here which led to this question. Any thoughts on getting the debugger to work with my code?
Code
HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("admin", "password", "DOMAIN") });
client.BaseAddress = new Uri(Helpers.GetSystemUrl(COHEN.APIConnector.Application.Dynamics));
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
HttpResponseMessage responseMessage;
string url = "ccseq_clients";
responseMessage = client.GetAsync(url).Result;

I remember this issue, when I was debugging SharePoint online REST API calls it will always crash. Then I added tracing service & logged checkpoints to verify the code execution path. Instead of debugging, I will download the Profiler trace log & replay in PRT to see success or failure branch.
When you configure plugin tracing to log All under system settings, it’s Dev mode & will be super helpful.
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Attempting to obtain Phone value...");
phone = account["telephone1"].ToString();
}
catch(Exception error)
{
tracingService.Trace("Failed to obtain Phone field. Error Details: " + error.ToString());
throw new InvalidPluginExecutionException("A problem has occurred. Please press OK to continue using the application.");
}
Reference
In your case:
if(responseMessage != null)
{
tracingService.Trace("API call success & got responseMessage.");
}
else
{
tracingService.Trace("responseMessage was empty.");
}

Related

Error: Twilio.Exceptions.AuthenticationException: 'Username can not be null'

I'm trying to create a Twilio app in C#, I took the code on the official documentation. I installed all the packages that the doc ask, for and try to run the app, but the following message error appears:
Code:
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
TwilioClient.Init(
Environment.GetEnvironmentVariable("********"),
Environment.GetEnvironmentVariable("********")
);
var message = MessageResource.Create(
from: new PhoneNumber("whatsapp:********"),
to: new PhoneNumber("Whatsapp:********"),
body: "Test"
);
Console.WriteLine("Message SID: ", message.Sid);
Error:
Unhandled exception. Twilio.Exceptions.AuthenticationException: Username can not be null
at Twilio.TwilioClient.SetUsername(String username)
at Twilio.TwilioClient.Init(String username, String password)
at Program.<Main>$(String[] args) in
line 5
I tried to implement the code line that appears in the error message, but the error is still there
Code:
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
TwilioClient.Init(
Environment.GetEnvironmentVariable("*********"),
Environment.GetEnvironmentVariable("*********")
);
Twilio.TwilioClient.SetUsername(
username: "*********#gmail.com"
);
Twilio.TwilioClient.Init(
username: "*********#gmail.com",
password: "*********"
);
var message = MessageResource.Create(
from: new PhoneNumber("whatsapp:*********"),
to: new PhoneNumber("Whatsapp:*********"),
body: "Teste"
);
Console.WriteLine("Message SID: ", message.Sid);
Something important to mention is that I create and set my account on Twilio, so everything is all right
This happens when I debug:
Debug
Please try the following code snippet:
Set Twilio Account SID (String Identifiers at Twilio) as username twilio.com/docs/glossary/what-is-a-sid and
Set Twilio Auth Token as a password
var sid = "34digitSID";
var authToken = "authToken";
TwilioClient.Init(sid, authToken);
For security reasons we can save this in appsettings.json file in asp.net MVC and read it as follows:
var sid = Configuration.GetValue<string>("AppSettings:Twilio:AccountSID");
var authToken = Configuration.GetValue<string>("AppSettings:Twilio:AuthToken");
TwilioClient.Init(sid, authToken);
Twilio tutorials and samples will usually use environment variables, but you have to make sure you set the environment variables first.
This is to avoid hard coding sensitive information like Account SID and Auth Token, which could then be accidentally committed to source control.
You're currently passing null to the first parameter of TwilioClient.Init which is why the error occurs. The reason that you're passing null is that the environment variable you're trying to pull isn't configured yet.
If you're running your .NET project from the .NET CLI, before running the project, configure the environment variables like this:
If you're using a bash or bash-like shell (mac/linux/unix):
export TwilioAccountSid=[TWILIO_ACCOUNT_SID]
export TwilioAuthToken=[TWILIO_AUTH_TOKEN]
If you're using PowerShell:
export TwilioAccountSid=[TWILIO_ACCOUNT_SID]
export TwilioAuthToken=[TWILIO_AUTH_TOKEN]
If you're using CMD:
set "TwilioAccountSid=[TWILIO_ACCOUNT_SID]"
set "TwilioAuthToken=[TWILIO_AUTH_TOKEN]"
Once you close your shell, the environment variables are lost and you'll need to set them again next time.
If you're not running the project from the CLI, but from an IDE, the IDE may also let you configure environment variables, but depending on the IDE, it may be stored in a plain text file inside of your project, which introduces the same risk of accidentally putting it into source control and leaking the sensitive tokens.
You can also set environment on Windows, profile or system wide using their built-in UI.
Lastly, the samples use Environment Variables because they are universally available (on all OS's and infrastructure) and are the simplest way to safely get started, but .NET has a much better way of configuring applications.
Here's an article that will take you from using environment variables to the .NET Configuration Builder and some of its features.
PS, let us know how you're running your project, like what IDE, what shell, etc. and also what Operating System you're using, so we can provide more specific instructions.

What is a Difference between DevOps Interface from VS19 Debug Mode to published Website?

I have a web application which is published on a same PC where I do coding and debugging.
One of the functionalities is an interface to company's Azure DevOps server to read or write WorkItems.
I am working with VS19. If I am in debug mode started from VS (F5 or ctrl+F5), communication to DevOps is working great, I can read and write WorkItems. If I try to do same from published site with debug configuration, which is hosted on same PC, I get response, that my request is refused.
To test my connection state I implemented a small test connection method according to guidelines
Authentication is realized with PAT. PAT is correct and authentication is working.
public async Task<ConnectionStatus> CheckAzureConnection()
{
string url = _uri + "/_apis/connectionData?api-version=5.1-preview";
ConnectionStatus status = new ConnectionStatus();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "My User Name", _personalAccessToken))));
using (HttpResponseMessage response = await client.GetAsync(url))
{
status.Status = response.StatusCode.ToString();
return status;
}
}
}
catch (Exception ex)
{
status.Status = "Not OK";
return status;
}
}
This code is working during debug, but not in published website. Site is published on IIS Webserver. An internal valid certificate is bound to site. IIS Basic authentication is switched of according to Microsoft. Honestly, I tried to switch it on and off.
First site was published with release configuration, but actually because of issue I switched to debug configuration, without success to issue.
Do anyone have any ideas what I did forget? Why my request get declined?
Issue was in IIS configuration. As I mentioned in my question, site is running in company network. I configured application pool to be executed by a local user. After I changed local user to a network user it worked.
As I know, VS has its own IIS and this is running with signed network user. This was a difference to IIS on host.

Deployed on Azure bot does not response

I start investigating BotFramework and encountered one annoying issue.
Created "Hello world" bot.
Here if the code
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters");
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
It works fine locally
Deployed it on Azure.
Set correct BotId, MicrosoftAppId and MicrosoftAppPassword parameters in web.config.
URL with my bot is http://funnyskypebot20171026010946.azurewebsites.net and it looks it works
But when i try to "communicate" with bit via Bot Framework Channel Emulator i do not receive any messages back ...
What could be wrong ? Please advise.
I assume you already followed the steps in https://learn.microsoft.com/en-us/bot-framework/deploy-dotnet-bot-visual-studio for deployment to Azure.
Have you seen this https://learn.microsoft.com/en-us/bot-framework/debug-bots-emulator with regards to debugging remotely using ngrok?
If you are using Visual Studio, on the toolbar, you can click on 'View -> Server Explorer'. Under 'Azure -> App Service', you should see your resource group there. Under your resource group, you should see your app service. Right-click and select 'Attach Debugger' so that you can view the output ('View -> Output') and debug your deployed app service.
Internal server error generally means there is some sort of issue with your code. Try debugging locally using ngrok. You can change your endpoint in the dev portal to the one that ngrok generates when you use this command ngrok http 3979 -host-header="localhost:3979" change to the port your bot runs on.
More info:
Blog Post
Blog Post

ASP.NET Web Application - on deploy, System.Speech.dll object not getting set to an instance of an object

I have an ASP.NET web application that uses System.Speech to transform text to a WAV file. It works fine locally but when I deploy it to the server, I get the below error message. This is using Windows Server 2012, ASP.NET 4.5, and IIS 8.5:
Object reference not set to an instance of an object.
System.Speech
at System.Speech.Internal.ObjectTokens.RegistryDataKey..ctor(String fullPath, RegistryDataKey copyKey)
at System.Speech.Internal.ObjectTokens.SAPICategories.DefaultDeviceOut()
at System.Speech.Internal.Synthesis.VoiceSynthesis..ctor(WeakReference speechSynthesizer)
at System.Speech.Synthesis.SpeechSynthesizer.get_VoiceSynthesizer()
at QuinnSDS.handlerTransform.<>c__DisplayClass6.<ProcessRequest>b__1()
The code which is generating this error message runs on the server:
if (context.Request.ContentLength > 0)
{
string line = new StreamReader(context.Request.InputStream).ReadToEnd();
// ********* generate wav file voicing the response *****************
// Using Microsoft voices
// initiate new instance of speech synthesizer
Thread t = new Thread(() =>
{
try
{
// The object creation works fine
System.Speech.Synthesis.SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer();
if (synth != null)
{
// The code breaks at synth.GetInstalledVoices() below. It will break any time I try to do anything with the synth object
foreach (System.Speech.Synthesis.InstalledVoice voice in synth.GetInstalledVoices())
{
System.Speech.Synthesis.VoiceInfo info = voice.VoiceInfo;
string voiceName = info.Name;
ws.WriteLine(voiceName);
}
}
}
catch (Exception e)
{
ws.WriteLine(e.Message);
ws.WriteLine(e.Source);
ws.WriteLine(e.StackTrace);
}
//... code continues...
It does not break when the Speech Synthesis object is created; it breaks whenever I try to use that object in any way.
I'm not sure if it's an access issue but I'm pretty new to ASP.NET and IIS and I can't figure out how to give the web app access to the GAC or if that's even what the problem is. I tried changing the property Local Copy for the System.Speech reference to True in Visual Studio, before I deploy the app, but that hasn't worked. I searched online and while the "object reference not set to an instance of an object" seems fairly common, I cannot find any similar issues where it is because of a .NET framework class library...I have run the text-to-speech code locally on the server and it ran fine. I have not run the entire app locally on the server because the web app requires speech input and there is not a microphone on the server.
Any ideas of anything to try would be most welcome!
What user account is the code running under when executed from ASP.NET? If the Speech API is touching the registry like the call stack suggests, it possibly has different permissions than the account you used to run the code manually.
If you can't just make the application pool for your site run with the same account you log into the machine with, I've had some success using Process Monitor to track down this kind of problem before. Basically, execute the code that fails while Process Monitor is running and look for 'ACCESS DENIED' in the 'Result' column (or anything else that looks suspicious). Quickly switching the application pool to use your standard user account will be the fastest way to rule out security or permission related problems though.

WebAuthBroker can't connect to service, but hand-posting in IE is succesful

I have a Windows 8 app that builds a string and posts to https: using WebAuthBroker. Relevant code is below.
The problem is that WebAuthBroker takes this URI and cannot connect, but when I hand=post this URI into IE, it works fine.
Running VS2012 on Windows 8.
In Package.appmanifest, have enabled Enterprise Authentication, Internet(Client), Internet(Client&Server), Private Networks(Client & Server), and Shared User Certificates.
async Task AuthenticateAsync()
{
var requestUriStr = string.Format("{0}?client_id={1}&response_type=token&redirect_uri={2}", logonUriString, clientId, redirectUriString);
requestUriStr += "&scope=stream";
var requestUri = new Uri(requestUriStr, UriKind.RelativeOrAbsolute);
var redirectUri = new Uri(redirectUriString, UriKind.RelativeOrAbsolute);
var result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, requestUri, redirectUri);
if (result.ResponseStatus != WebAuthenticationStatus.Success)
{
throw new Exception("Login failed: " + result.ResponseErrorDetail);
}
I found my problem. From: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/13d3742d-4b6b-444e-840e-a4db11462a08
Turns out that if you use Fiddler to debug your HTTP requests, it will
make WebAuthenticationBroker stop working. This may or may not be
related to the "Decrypt HTTPS traffic" options provided in this app,
but as soon as I closed Fiddler, WebAuthenticationBroker started
working again. I can replicate the bug at will by starting Fiddler
again, and resolve the problem by closing it.
I didn't make advanced researches as whether or not enabling or
disabling the HTTPS options of Fiddler will impact the use of the
WebAuthenticationBroker class and methods, but on first sight it looks
like barely disabling HTTPS will make it working again. I usually
close it personally to be on the safer side.
So I had Fiddler open the whole time I was writing / debugging. I closed Fiddler, and it worked the first time!

Categories