StackOverflowException in Microsoft.Html.MainHtmlController on Merge, Annotate, - c#

I am extending VisualStudio 2015 Html Editor. I've decorated my IOleCommandTarget implementing command filter with [TextViewRole(PredefinedTextViewRoles.PrimaryDocument)] attribute. This way my commands will not be run in Annotate and Merge TextViews. However I've ran into problem that MainHtmlController starts to loop on itself as soon as I open Annotate or Merge window. This is my stacktrace:
I have no idea what information could be of help here. My contentype definition looks like this. There is 'htmlx' so that html editor handles the file type.
public class DothtmlContentTypeDefinition
{
public const string ContentTypeName = "dothtml";
//public const string JavaScriptContentType = "JavaScript";
//public const string CSharpContentType = "cs";
[Export(typeof(ContentTypeDefinition))]
[Name(ContentTypeName)]
[BaseDefinition("htmlx")]
public ContentTypeDefinition DothtmlContentType { get; set; }
[Export(typeof(FileExtensionToContentTypeDefinition))]
[FileExtension(".dothtml")]
[ContentType(ContentTypeName)]
public FileExtensionToContentTypeDefinition DothtmlFileExtensionDefinition { get; set; }
...
}
In my desperation I've tried this:
if (textView.Roles.Any(r => r == "VSMERGEDEFAULT_LEFT" || r == "VSMERGEDEFAULT_RIGHT" || r == "ANNOTATE")) {
ServiceManager.RemoveService<HtmlMainController>(textView);
return; }
But that is the most ugly solution ever. And it causes null exceptions somewhere in CommandTargetToOleShim which does not look good. These however are non-fatal and dont take whole visualstudio down. Merge and Annotate are atleast usable.
If needed I will provide more info, but I have no idea what may be relevant.

Related

Can DisplayNameAttribute extension with XML source update in runtime?

This might be more of a question related to how .NET Framework works, than looking for an actual solution. Reason is I would like to know if this is something I should pursue in fixing, or try something else entirely. I did some searching, but couldn't find the right answer in my opinion.
I am working on an ASP.NET MVC5 application that utilizes a translation provider with an XML file as it source. In some scenarios I use a DisplayNameAttribute extension to decorate model properties to provide translations. It is made by referencing the solution here: https://stackoverflow.com/a/9723620/1501132
This is my implementation:
[AttributeUsage(AttributeTargets.Property)]
public sealed class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
public LocalizedDisplayNameAttribute(string key, string page = null) : base(FormatMessage(key, page))
{
}
private static string FormatMessage(string key, string page = null)
{
if (!string.IsNullOrWhiteSpace(key) && string.IsNullOrWhiteSpace(page))
{
return TextGetter.GetText(key);
}
else if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(page))
{
return TextGetter.GetText(key, page);
}
else
{
return string.Empty;
}
}
}
The "TextGetter" is a separate library that handles fetching strings from the XML data source.
The attribute extension is used like so:
[LocalizedDisplayName("Timestamp", "/report")]
public DateTimeOffset Timestamp { get; set; }
The website also has a feature where a super user can edit the translation XML file, in case some translations are wrong or missing. Usually an edit in the XML file is visible immediately, except for properties with this particular attribute. I know that normally when using DisplayName attribute with a hardcoded value can not be changed because it is compiled, though I was under the assumption that since this uses an XML file as reference, I believed that if the XML was changed it would be reflected immediately in this case as well. But that seems not to happen.
Being able to change translations on the fly is an important feature; should I seek some other solution? I can set the property names with translations in the views, which is working, but that will entail a LOT of refactoring, and keeping it as annotations is just more neat.
I don't really know where to take it from here.
Found a solution in the meantime, and just putting it out there if anyone stumbles across it. So this is what you should do, if you want to make an attribute that derives from DisplayName used for localization, and on top of that have a localization source that can change and update during runtime:
[AttributeUsage(AttributeTargets.Property)]
public sealed class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
private readonly string _key;
private readonly string _page;
public LocalizedDisplayNameAttribute(string key, string page = null) : base(key)
{
this._key = key;
this._page = page;
}
public override string DisplayName => this.FormatMessage(this._key, this._page);
private string FormatMessage(string key, string page = null)
{
if (!string.IsNullOrWhiteSpace(key) && string.IsNullOrWhiteSpace(page))
{
return TextGetter.GetText(key);
}
else if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(page))
{
return TextGetter.GetText(key, page);
}
else
{
return string.Empty;
}
}
}
The contents of "FormatMessage" can be whatever you want really, just insert there whatever code you need to fetch your translated string.

How do I change the default validation error of `System.ComponentModel.DataAnnotations.ValidationAttribute`

I have a class like below (simplified) and I like to replace the default validation error with my own messages. I know I can set the message directly when I am adding the attribute, but it is too much pain and it is error prune to add the same message 10,000 time in the same code.
Public class CreateUser
{
[Required(ErrorMessage = "A specific message")]//Don't like to do this
[MinLength(10)]// Like to write specific text
public string Name { get; set; }
}
I have looked into their code and apparently they are using ResourceManager to set the actual message from the key. The documentation just describes the way to handle windows applications. How do I add the resources in Asp.net core application and overwrite the default values?
Update
From the code it seems like a small change if one knows how to set the ResourceManager, but from the comments it seems like a hard job. I don't understand why. For MinLenghtAttribute we have
public class MinLengthAttribute : ValidationAttribute
{
public MinLengthAttribute(int length)
: base(SR.MinLengthAttribute_ValidationError)
{
Length = length;
}
// The rest of the code
}
The SR is as below :
namespace System
{
internal static partial class SR
{
internal static string MinLengthAttribute_ValidationError =>
GetResourceString("MinLengthAttribute_ValidationError");
// The rest of the code
}
}
One should be able to chance the value in GetResourceString and achieve my goal. Right?

Visual studio for Mac looks into different class than referenced

After accidentally hitting rename of my skv_match class to skv_player class I have issue with my ReadMatches method. The Visual studio keeps telling me, there is no definition of methods in class skv_player when I use class skv_match instead (after I renamed the class back to skv_match).
I am desperate and don't know if I am doing something wrong or Visual studio for Mac is. Does anybody know how to solve this or did I miss something in the code?
I tried to restart the app and laptop, rebuild and clean project. I also tried deleting the figuring classes, creating them again and pasting the original content in them.
public string ReadMatches()
{
var matches = _context.skv_match.AsNoTracking();
StringBuilder sb = new StringBuilder();
if (matches == null)
{
return "No matches found";
}
else
{
foreach (var skv_match in matches)
{
sb.Append($"Match id: {skv_match.id }\r\n");
sb.Append($"Match results: {skv_match.home_team}");
sb.Append($"{skv_match.home_score }:");
sb.Append($"{skv_match.visitor_score } ");
sb.Append($" {skv_match.visitor_team }\r\n");
}
}
return sb.ToString();
}
public class skv_match
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public int id { get; set; }
public string home_team { get; set; }
public string visitor_team { get; set; }
public int home_score { get; set; }
public int visitor_score { get; set; }
}
I get error: "'skv_player' does not contain a definition for 'home_team' and no accessible extension method 'home_team' accepting a first argument of type 'skv_player' could be found (are you missing a using directive or an assembly reference?)" and same for other methods
I expect the app to just take this without any errors, yet I get error that class I am not referencing misses methods. Before I accidentally hit rename the class everything worked just fine.
Ok my apologies to everyone who took time trying to help me. There was issue in Entity framework DbContext. I don't know if I was just tiredly stupid, or mentioned missclick changed it.
For anyone trying to solve this issue, try Right click on the declaration and "Go to declaration". It will point you to the part where you define it.
To be specific, I clicked on part skv_match at var matches = _context.skv_match.AsNoTracking();

Microsoft Bot Receive attachments from user using FormFlow

I'm Designing a Bot using FormFlow in which one of the input will be asking user to attach a file to proceed further.
I Can see below link addresses the similiar problem.
https://github.com/Microsoft/BotBuilder/issues/570
The solution provided in the link is to use custom IRecognizer or as below
a) Put it into a private field/property that is not exposed to FormFlow.
b) Put it in as the value of field that is exposed to form flow.
c) Use the private property to dynamically generate a field that allows choosing between them.
I'm naive to the Bot Framework. Are there any examples to implement this on receiving the attachment from customer using FormFlow .
Below is my code snippet
enter code here
[Serializable]
public class DocBot
{
[Prompt("What's your name?")]
public string Name { get; set; }
[Prompt("Hey {&} , Choose the options below? {||}")]
public Service? shaun;
[Prompt("Attach the Document required for further processing?")]
public string Document { get; set; }
-- Need Suggestion on receiving documents attachment from the user here
[Prompt("What is your Job Title there?")]
public string JobTitle { get; set; }
[Prompt("What's the best number to contact you on?")]
public string Phone { get; set; }
public enum Service
{
Consultancy, Support, ProjectDelivery, Unknown
}
public static IForm<DocBot> BuildEnquiryForm()
{
return new FormBuilder<DocBot>()
.Message("Welcome to Doc BOT!!!")
.Field(nameof(Name))
// .Field(nameof(Document))
-- Need Suggestion on receiving documents attachment from the user here
.Build();
}
}
Update
Support for attachments in FormFlow was added in https://github.com/Microsoft/BotBuilder/pull/2870
There is a sample located here that demonstrates how to accomplish this. For the form itself, you will need to look at ImagesForm.cs
---------
Currently this is not supported. After going through the BotBuilder code, the only workaround I could offer implies rebuilding the BotBuilder library code as you will have to make some updates in the FormDialog to hack it a bit to get the Attachment url.
If you want to try the workaround (again, is workaround, I haven't fully tested this and this could have other implications that I'm not aware of), get the BotBuilder code, find the FormDialog class and then replace these two lines with the following code:
var message = toBot != null ? (await toBot) : null;
var toBotText = message != null ? message.Text : null;
var toBotAttachments = message != null ? message.Attachments : null;
var stepInput = (toBotAttachments != null && toBotAttachments.Any()) ? toBotAttachments.First().ContentUrl : (toBotText == null) ? "" : toBotText.Trim();
What this workaround does is checking if the incoming message has attachments. If it has, then it discards the text and uses the ContentUrl of the first attachment. Then, in your Form model property, you will get the attachment url.

Having NUnit console report test results during the test run, after each test

I run NUnit console on my test assembly but sometimes my NUnit crashes (I'm currently figuring out why). When nunit crashes no xml report is created and I effectively am left without any test report. The test run is very long and it's a bad situation if I lose the entire test run report.
Is there a way to tell NUNit to write the xml log file as it goes (after each test). Even if that means the xml file won't be closed properly.
I know it is possible to use NUnit TestListener. But is there a switch or something that does not include writing extra code myself.
You could invoke nunit-console with the /labels command-line switch. This will cause it to write out the (fully-qualified) name of each test to the console as it runs, though the output does not include the test result. However, it would show you which tests had run successfully.
The only other option is the one you have discounted, that of writing your own EventListener implementation. The documentation about that interface is a little light, but the NUnit documentation about writing an NUnit add-in assembly should be enough to get you started if you change your mind about that.
First of all in a near future it looks like such a logging will be provided by NUnit out of the box - this feature was already requested - Write partial results XML as tests happen instead of at the end.
Until its done we need to write some custom code and in case u use NUnit < 3.x its pretty simple:
1)You need to create an event listener which implements EventListener interface
2)This interface provides notifications for different states of test execution eg. RunStarted, RunFinished or TestFinished. All you need to is an implementation of logging relevant for your case. Snippet from my code:
public void RunStarted(string name, int testCount)
{
try
{
_instanceId = Environment.GetEnvironmentVariable("InstanceId");
_buildId = Environment.GetEnvironmentVariable("BuildId");
_browser = Environment.GetEnvironmentVariable("BrowserToTest");
_template = Environment.GetEnvironmentVariable("TemplateToTest");
}
catch { }
}
public void TestFinished(TestResult result)
{
if (result.ResultState == ResultState.Ignored)
{
return;
}
var r = new TestingWorkerData
{
BuildId = _buildId,
InstanceId = _instanceId,
TestName = result.FullName,
Success = result.IsSuccess,
TimeTaken = result.Time.ToString(CultureInfo.InvariantCulture),
Message = result.Message,
StackTrace = result.StackTrace,
Browser = _browser,
Template = _template
};
File.AppendAllLines(#"z:\\results.txt", new[] {JsonConvert.SerializeObject(r)});
}
public class TestingWorkerData
{
public string TestName { get; set; }
public bool Success { get; set; }
public string TimeTaken { get; set; }
public string Message { get; set; }
public string StackTrace { get; set; }
public string InstanceId { get; set; }
public string Browser { get; set; }
public string Template { get; set; }
public string BuildId { get; set; }
}
3)The last thing is creation of NUnit addin:
[NUnitAddin]
public class ProgressReporterNugetAddin : IAddin
{
public bool Install(IExtensionHost host)
{
var listeners = host.GetExtensionPoint("EventListeners");
listeners.Install(new ProgressReporterEventListener());
return true;
}
}
Note:There is a pretty good article http://jimmykeen.net/2015/02/28/logging-test-results-with-nunit/ which covers similar approach and more.Unfortunately it works for NUnit < 3.x ONLY since NUnit3 was heavily rewritten - eg. no EventListener interface anymore.

Categories