I'm having some trouble understanding and getting the search contract to work in my Store app. I have been unable to find any sort of documentation or guide that explains the structure of using the contract. (I've looked at the quickstarts on MSDN, the Search Contract sample and the build video, but that only really deals with javascript)
So far I've been able to run a query and get a list (of Custom Objects) into my search contract page, and from there I try to assign that to defaultviewmodel.results, but no matter what query I type nothing shows up I on the page. Is there something else I need to set?
What I have so far is as follows (excerpts):
App.xaml.cs
protected override void OnSearchActivated(Windows.ApplicationModel.Activation.SearchActivatedEventArgs args)
{
SearchCharmResultsPage.Activate(args.QueryText, args.PreviousExecutionState);
SearchCharmResultsPage.ProcessSearchQuery(args.QueryText);
}
public async static void ProcessSearchQuery(string queryString)
{
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("recipeCustomObject Debug.WriteLine("Database exists, connecting");
SQLiteAsyncConnection connection = new SQLiteAsyncConnection("CustomObject_db");
List<CustomObject> resultsList = new List<CustomObject>();
string query = "SELECT * FROM CustomObjectDB";
resultsList = await connection.QueryAsync<RecipeRecord>(query);
}
catch (FileNotFoundException fnfExc)
{
Debug.WriteLine("FNFEXC: " + fnfExc.ToString());
}
}
I think it is possible that here lies the problem, though I'm not sure if it is, or how to change it.
the resultsList list is created here, but because the method it asynchronous, I can't return from the method. Because of this I'm guess that when I try to assign this.DefaultViewModel[Results] = resultsList; in the LoadStateMethod, the object doesn't exist (thought the program throws no error). When I try to add the same line in the ProcessSearchQuery method, i'm told that this is not valid in a static method, but I think I need the method to be static? My problem might just be a fundamental logic error?
Finally got it! found the solution here: http://jeffblankenburg.com/2012/11/06/31-days-of-windows-8-day-6-search-contract
For those looking for an answer in the future, the key is to make sure you have your search logic within the Filter_SelectionChanged method, which was something I wasn't doing. Look at the guide within the above link to get an idea of the structure.
Have you looked at the Search contract sample on the developer center? There's a C#/XAML version there as well.
My open source Win8 RSS Reader framework implements Search (and Share) have a look at the source and if you still got questions, I'll be happy to help http://win8rssreader.codeplex.com/
Related
The Allure framework is a really beautiful framework for test reporting.
Yet it has rather bad documentation for C#.
I want to add some things to my allure report:
Debug log (like all things I write to debug)
Screenshot
A file
How to do it? I have no idea, please help me if you know how to do it. It seems like AllureLifecycle class can help me but I'm not sure how to use it.
In case it matters I use Allure together with SpecFlow and MS test.
I searched more and seems I found the Truth.
And the Truth is it's possible to add all attachments I wanted but they can be added only as a file:
byte[] log = Encoding.ASCII.GetBytes(Log.GetAllLog());
AllureLifecycle.Instance.AddAttachment("DebugLog", "application/json", log, "json");
If you want to add a file from actually a path (location) you can do it with the same method but a different overload.
So just place this code in a "teardown\afterscenario" method or at any other place (for example at "afterstep" method) where you want to make this attachment. I use SpecFlow so if I add this to "AfterStep" hook then Allure displays those files attached to a specific step! That's amazing!)
it seems that allure has some events that can be used.
See : https://github.com/allure-framework/allure-csharp-commons/blob/master/AllureCSharpCommons.Tests/IntegrationTests.cs for more information.
haven't tried it myself, but something like this should work according to the documentation.
_lifecycle = Allure.DefaultLifecycle;
_lifecycle.Fire(new
MakeAttachmentEvent(AllureResultsUtils.TakeScreenShot(),
"Screenshot",
"image/png"));
_lifecycle.Fire(new MakeAttachmentEvent(File.ReadAllBytes("TestData/attachment.json"),
"JsonAttachment",
"application/json"));
Hope this helps.
Using this kind of code in AfterScenario method:
if (_scenarioContext.TestError != null)
{
var path = WebElementsUtils.MakeScreenshot(_driver);
_allureLifecycle.AddAttachment(path);
}
First it verifies, if Scenario passed, if not then
WebElementsUtils.MakeScreenshot(_driver)
method makes screenshot and returns it's path. Then this path I giving to Allure. As a second parameter in the same method I can give a name of the screenshot. As a result I am getting a screenshot in AfterScenario block in Allure report.
P.S. This is only for screenshots, about logs can't tell nothing.
With this example you can add an attachment exactly to the failed step
[AfterStep(Order = 0)]
public void RecordScreenFailure(ScenarioContext scenarioContext)
{
if (scenarioContext.TestError != null)
{
Allure.Commons.AllureLifecycle allureInstance = Allure.Commons.AllureLifecycle.Instance;
string screenshotPath = MagicMethodMakingScreenshotAndReturningPathToIt();
allureInstance.UpdateTestCase(testResult => {
Allure.Commons.StepResult failedStepRsult =
testResult.steps.First(step => step.status == Allure.Commons.Status.failed);
failedStepRsult.attachments.Add(new Allure.Commons.Attachment() {
name = "failure screen",
source = screenshotPath,
type = "image/png"
});
});
}
}
I use an IAutoTamper2 to colorcode relevant requests/responses to my application based on url and other information.
This is very helpful for debugging. However when someone sends me a saved .saz file, I no longer see my helpful colorcodes. How can I apply the IAutoTamper2 logic when a file is imported.
I looked at the ISessionImporter interface but you have to start from scratch. Is there a way to inherit from the default importer and add my logic that occurs in the IAutoTamper2?
I've looked at all the documentation about extensions on the telerik website but couldn't find anything relevant. Any ideas?
I figured out how to do it. There is a OnLoadSAZ event that I can use to change loaded sessions.
This is my code:
public void OnLoad()
{
FiddlerApplication.OnLoadSAZ += HandleLoadSaz;
}
private void HandleLoadSaz(object sender, FiddlerApplication.ReadSAZEventArgs e)
{
FiddlerApplication.UI.lvSessions.BeginUpdate();
foreach (var session in e.arrSessions)
{
OnPeekAtResponseHeaders(session); //Run whatever function you use in IAutoTamper
session.RefreshUI();
}
FiddlerApplication.UI.lvSessions.EndUpdate();
}
I hope that helps someone else.
What I'm trying to do, ultimately, is access the CacheSettingsPart so that I can programmatically add some ignored URLs to the output caching config.
The relevant admin controller already achieves this with:
var settings = Services.WorkContext.CurrentSite.As<CacheSettingsPart>();
settings.IgnoredUrls = model.IgnoredUrls;
I need something similar for my own method, but when I try and inject IOrchardServices, the WorkContext is null, meaning I don't have access to the CurrentSite.
I need suggestions of achieving this with an alternative approach or, ideally, a way of accessing the CurrentSite/CacheSettingsPart for me to amend the IgnoredUrls.
EDIT
var query = Services.ContentManager.Query<CacheSettingsPart>();
var cacheSettingsPart = query.List().First();
The above seems to be giving me what I need, I'll now test whether amending IgnoredUrls persists or not.
The WorkContext, as far as I can see, hasn't been created at the point of the Migration being run.
You could get the first SettingsPart as you suggest - it's probably not used for anything except the current site, though if you had multiple tenants, then I think you might run into trouble.
An alternative would be to inject ISiteService into your migrations class.
You can then do
var site = _siteService.GetSiteSettings();
var cacheSettings = site.As<CacheSettingsPart>();
var query = Services.ContentManager.Query<CacheSettingsPart>();
var cacheSettingsParts = query.Slice(1);
if(cacheSettingsParts.Any())
{
_signals.Trigger(CacheSettingsPart.CacheKey);
cacheSettingsParts.First().IgnoredUrls = "/dans-test";
}
The above works, but I appreciate it might not be the best approach so I'm open to other suggestions.
I am attempting to implement a Language Service in a VSPackage using the MPF, and it's not working quite as I understand it should.
I have several implementations already, such as ParseSource parsing the input file with a ParseRequest. However, when it finds an error, it adds it with AuthoringSink.AddError. The documentation for this implies it adds it to the Error List for me; it doesn't.
I also have a simple MySource class, a subclass of Source. I return this new class with an overridden LanguageService.CreateSource method. The documentation for OnCommand says it's fired 'when a command is entered'. However, it's not.
There's obviously some intermediate step which I haven't done correctly. I've already rambled enough, so I'll be glad to give any additional details by request.
Any clarification is much appreciated.
For the AuthoringSink error list question, I use this behavior in my Language Service. In ParseSource, the ParseRequest class has an AuthoringSink. You can also create a new ErrorListProvider if you want to work outside of the parser's behavior. Here is some example code:
error_list = new ErrorListProvider(this.Site);
error_list.ProviderName = "MyLanguageService Errors";
error_list.ProviderGuid = new Guid(this.errorlistGUIDstring.);
}
ErrorTask task = new ErrorTask();
task.Document = filename;
task.CanDelete = true;
task.Category = TaskCategory.CodeSense;
task.Column = column;
task.Line = line;
task.Text = message;
task.ErrorCategory = TaskErrorCategory.Error;
task.Navigate += NavigateToParseError;
error_list.Tasks.Add(task);
I hope this was helpful.
OnCommand should be firing every time there is a command, in your MySource class you can do something like this (pulled from working code):
public override void OnCommand(IVsTextView textView, VsCommands2K command, char ch)
{
if (textView == null || this.LanguageService == null
|| !this.LanguageService.Preferences.EnableCodeSense)
return;
if (command == Microsoft.VisualStudio.VSConstants.VSStd2KCmdID.TYPECHAR)
{
if (char.IsLetterOrDigit(ch))
{
//do something cool
}
}
base.OnCommand(textView, command, ch);
}
If that doesn't work double check that CodeSense = true in your ProvideLanguageService attribute when you setup your LanguageService package. A whole lot of what is cool to do in the LanguageService requires these attributes to be correctly turned on. Some even give cool behaviors for free!
Another thing to be careful of is that some behaviors like colorizer don't function correctly in the hive in my experience. I don't think these were ones that gave me trouble, but I implemented these a couple of years ago so I'm mostly just looking back at old code.
AuthoringSink.AddError only adds errors to the error list if ParseRequest.Reason is ParseReason.Check. When your ParseSource function attempts to add errors while parsing for any other ParseReason, nothing will happen.
It's possible that your language service is never calling ParseSource with this ParseReason. As far as I know, the only way to get a ParseReason of Check (outside of manually calling BeginParse or ParseSource yourself) is to proffer your service with an idle timer.
If anyone has come across the the Arcos sample code in the MRDS can you please let me know what the following code fragment does in the ArcosDrive.cs file. I am more interested in the lines "arcos.Update update = new arcos.Update(raw);" and "_arcosPort.Post(update);".
Thanks.
void VelocityHandler(Velocity velocity)
{
arcos.RawType raw = new arcos.RawType();
raw.Command = "Vel";
raw.Integer = (short)velocity.Body.Velocity;
raw.Flags = arcos.RawFlags.Integer;
arcos.Update update = new arcos.Update(raw);
_arcosPort.Post(update);
Activate(Arbiter.Choice(update.ResponsePort,
delegate(DefaultUpdateResponseType response)
{
velocity.ResponsePort.Post(DefaultSubmitResponseType.Instance);
},
delegate(Fault fault)
{
velocity.ResponsePort.Post(fault);
})
);
}
After taking a deep breath and careful thinking :P I managed to figure it out.
Seems that a PostUnknownType is like an automatic type casting whereby the type that is posted is recognized automatically without having to define multiple post types.
In the case of RawType, a RawType post eventually triggers a call to RawCommandHandler defined in the ArcosState class.
Hope someone finds this useful.