How to create a SecondaryTile on Windows Phone 8.1? - windows-phone

I'm trying to create a Tile on the Windows Phone start screen. The following code used to work but now it doesn't. I didn't change anything.
private async static void CreateTile()
{
try
{
SecondaryTile tileData = new SecondaryTile()
{
TileId = "MyTileID",
DisplayName = "My App Name",
TileOptions = TileOptions.ShowNameOnLogo,
};
tileData.VisualElements.Square150x150Logo = new Uri("ms-appx:///Resources/Images/Tiles/150150.png", UriKind.Absolute);
tileData.VisualElements.ShowNameOnSquare150x150Logo = true;
await tileData.RequestCreateAsync();
}
catch (Exception ex)
{
}
}
Now it's failing with the error message:
The parameter is incorrect.
and the following Stack Trace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at My.Namespace.SplashPage.<CreateTile>d__f.MoveNext()
I even get the error when I comment everything out, for example:
SecondaryTile tileData = new SecondaryTile()
{
//TileId = "MyTileID",
//DisplayName = "My App Name",
//TileOptions = TileOptions.ShowNameOnLogo,
};
//tileData.VisualElements.Square150x150Logo = new Uri("ms-appx:///Resources/Images/Tiles/150150.png", UriKind.Absolute);
//tileData.VisualElements.ShowNameOnSquare150x150Logo = true;
await tileData.RequestCreateAsync();
So I don't know what parameter is incorrect. What could be causing this? How can I fix it?

Try something like this:
if (SecondaryTile.Exists(tileID)) await tileData.UpdateAsync();
else await tileData.RequestCreateAsync();

Related

A possible object cycle was detected. in both System.Text.Json and Newtonsoft.Json

I have been pulling my hair out with this one.
I have a very simple test class that throws this error:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.
It doesn't seem to break much, as the put request is successful and the serialize is also successful.
EDIT
I have chased the serialize exception out if it was ever really there. I am starting to think it is a problem with typed HttpClient. It throws the exception that comes out on the console and in the response on Postman. However, it doesn't allow me to catch the exception in the code and the PUT call works. So the exception is happening after the PUT request and is handled before it returns control to my app.
I am going to try to use a standard HttpClientFactor instead of a typed client and see if that works. I know that the JSON exception is a red herring, but it is ugly and breaking the response.
Any suggestions would be welcome.
public virtual async Task<CouchResponse> Create(string id, string db, TObj info)
{
CouchResponse ret = new() { Reason = "Unknown and unExpected error", Ok = false };
HttpResponseMessage rc = null;
if (id is null)
{
return new CouchResponse() { Id = "missing", Ok = false, Rev = "missing" };
}
string url = $"{db}/1";
try
{
// login to Couchdb servwer
await CouchLogin();
try
{
//var jsonInfo = JsonUtils.Serialize<TestJson>(jTest);
var jsonInfo = JsonSerializer.Serialize<TObj>(info, options);
HttpContent content = new StringContent(jsonInfo, Encoding.UTF8,
"application/json");
rc = await client.PutAsync(url, content);
}
catch (Exception eNewton)
{
Console.WriteLine($"Json Exception: {eNewton.Message}");
}
if (rc is not null)
{
var str = await rc.Content.ReadAsStringAsync();
var ret = JsonSerializer.Deserialize<CouchResponse>(str,options);
rc.EnsureSuccessStatusCode();
}
return ret;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//return ret;
}
return ret;
}
Suggestions?
What a crazy bug. The diagnostic was very missing leading. Everything I was doing in the create method was correct.
What is missed was an await when I called the create method. This made it appear that the sendAsync was having the issue when it was really the controller trying to format the task return as a response. This caused the stack trace in the response message. Thanks for all the help.
Change this
var jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore
};
To this
var jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
MaxDepth = null,
};

Using GlobalExceptionHandler and custom Middleware in AspNetCore

I am using app.UseExceptionHandler(GlobalErrorHandler) in AspNetCore and after that a custom middleware. When using this separately they work fine but when using them simultaneous the exception is thrown inside my custom middleware and crashes the call. This happens on await _next.Invoke(context). I also tried to use an ExceptionFilter but the results where the same. My global exception handling looks like this. Is there a way to stop the exception from bubbling up?
app.UseCustomMiddleware();
app.UseExceptionHandler(GlobalErrorHandler);
app.UseMvc();
private void GlobalErrorHandler(IApplicationBuilder applicationBuilder)
{
applicationBuilder.Run(
async context =>
{
context.Response.ContentType = "text/html";
var ex = context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
string errorMessage;
var webFault = ex.Error as WebFaultException<string>;
if (webFault != null)
{
context.Response.StatusCode = (int)webFault.StatusCode;
errorMessage = webFault.Detail;
}
else
{
if (ex.Error is UnauthorizedAccessException)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
errorMessage = string.Empty;
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
errorMessage = ex.Error.Message + new StackTrace(ex.Error, true).GetFrame(0).ToString();
}
_logger.Error(errorMessage, ex.Error);
}
await context.Response.WriteAsync(errorMessage).ConfigureAwait(false);
}
});
}
The problem is with the order in which you add middlewares to the application. Since you add exception handler after the custom middleware, any exception thrown by this middleware will not be covered by the exception filter.
The fix is very simple. Just change the order of middleware registration, so that exception filter is registered first:
app.UseExceptionHandler(GlobalErrorHandler);
app.UseCustomMiddleware();
app.UseMvc();
Now the exception thrown from the custom middleware will be successfully processed by the exception handler.

Unit testing using Fakes gives IConvertible exception

What I have
The interface:
public interface IDocDbRepository
{
Task<JObject> UpdateDocumentAsync(JObject updatedDocument);
}
The implementation:
public async Task<JObject> UpdateDocumentAsync(JObject updatedDocument)
{
if (updatedDocument == null)
{
throw new ArgumentNullException(nameof(updatedDocument));
}
var response = await this.documentDBClient.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(this.dbName, this.collectionName, updatedDocument["id"].Value<string>()), updatedDocument).ConfigureAwait(false);
return JObject.Parse(response.Resource.ToString());
}
The exception occurs in the await line.
The Unit Test:
static Guid docGuid = Guid.NewGuid();
[TestMethod]
public async Task TestMethod2()
{
var jObject = new JObject { { "id", docGuid }, { "studentId", "1" }, { "courseId", "Ph" } };
// Arrange
var docClient = new ShimDocumentClient();
ShimDocumentClient.AllInstances.CreateDocumentAsyncUriObjectRequestOptionsBoolean =
(instance, uri, document, options, disableAutomaticGeneration) => Task.FromResult(new ResourceResponse<Document>(new Document() { Id = docGuid.ToString() }));
// Act
var documentRepository = new DocDbRepository(endPointUri, accountKey, dbName, collectionName);
try{
var response = await documentRepository.UpdateDocumentAsync(jObject).ConfigureAwait(false);
}
catch(Exception ex){}
// Assert
Assert.AreEqual(response.Count, 1);
}
The test does not go beyond the UpdateDocumentAsync part and exits with this message:
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Newtonsoft.Json.Linq.Extensions.Convert[T,U](T token)
at Newtonsoft.Json.Linq.Extensions.Value[T,U](IEnumerable`1 value)
at Newtonsoft.Json.Linq.Extensions.Value[U](IEnumerable`1 value)
at Common.DataAccess.DocumentDb.DocDbRepository.<UpdateDocumentAsync>d__12.MoveNext() in C:\Common\Common.DataAccess.DocumentDb\DocDbRepository.cs:line 196
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Common.DataAccess.DocumentDb.Tests.DocDbUtilityTests.<TestMethod2>d__9.MoveNext() in C:\Common\Common.DataAccess.DocumentDb.Tests\DocDbUtilityTests.cs:line 113
This is my first time with Fakes framework.
Any help is greatly appreciated.
Thanks in advance.
Regards.
This appears to be a problem with your serialization code. Specifically, this statement:
updatedDocument["id"].Value<string>()
The Value extension method appears to require that the source implement the IConvertible interface, which is not implemented by Guid.

Unexpected end of stream at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream

System.IO.IOException: Unexpected end of stream.
at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.<ReadAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.<DrainAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.WebUtilities.MultipartReader.<ReadNextSectionAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at AspNetCoreFileUpload.Controllers.FileUploadController.<Index>d__0.MoveNext()
in C:\\GitHub\\StackOverflow\\LargeFileUploadController\\FileUploadController.cs:line 29
Repro: https://github.com/bigfont/StackOverflow/tree/master/LargeFileUploadController
Form
<form action = ""/FileUpload"" method=""post"" enctype=""multipart/form-data"">
<label for=""myfile1"">File</label>
<input type=""file"" name=""myFile1"" />
<label for=""myfile2"">File</label>
<input type=""file"" name=""myFile2"" />
<input type=""submit"" value=""Send"" />
</form>
Controller
public class FileUploadController : Controller
{
[HttpPost]
public async Task<IActionResult> Index()
{
var boundary = GetBoundary(Request.ContentType);
var reader = new MultipartReader(boundary, Request.Body);
try
{
var section = await reader.ReadNextSectionAsync();
}
catch (System.Exception ex)
{
return new OkObjectResult(new { ex = ex.ToString() });
}
return new OkObjectResult(new { message = "Done" });
}
private static string GetBoundary(string contentType)
{
var elements = contentType.Split(' ');
var element = elements.Where(entry => entry.StartsWith("boundary=")).First();
var boundary = element.Substring("boundary=".Length);
// Remove quotes
if (boundary.Length >= 2 &&
boundary[0] == '"' && boundary[boundary.Length - 1] == '"')
{
boundary = boundary.Substring(1, boundary.Length - 2);
}
return boundary;
}
}
I got almost the same exception recently. I'm saying almost because they actually renamed the exception to Unexpected end of Stream, the content may have already been read by another component., which actually means that something already consumed the body stream. The comments of the following change gives us the understanding of what's happening:
Tratcher commented on Mar 23
...The MVC model binder reads the form and buffers the multipart segments
for you, so there's no point in re-parsing request body with the
MultipartReader...
So, the question is how to disable the default form binding (reading the request form)?
I found the DisableFormValueModelBindingAttribute attribute in this Mvc.FileUpload sample which disables the form binding and this is what it looks like:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var formValueProviderFactory = context.ValueProviderFactories
.OfType<FormValueProviderFactory>()
.FirstOrDefault();
if (formValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(formValueProviderFactory);
}
var jqueryFormValueProviderFactory = context.ValueProviderFactories
.OfType<JQueryFormValueProviderFactory>()
.FirstOrDefault();
if (jqueryFormValueProviderFactory != null)
{
context.ValueProviderFactories.Remove(jqueryFormValueProviderFactory);
}
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
If you want some more information, you can check out the following:
Create a filter/sample that shows how to remove the form value providers (rynowak opened this issue on Apr 26)
Sample: Issues with Antiforgery + Form + File Uploads (rynowak opened this issue on Apr 26)
Just for info - as commented before, the MVC model binder reads the form, but where can one find the results. The results can be found in the HttpRequest.Form, which has Files.
Don't know if this might help you but I came across simular issue "Unexpected end of Stream, the content may have already been read by another component".
app.Use(async (context, next) => {
context.Request.EnableRewind();
await next();
});
Code above were added in Startup.cs Configure method.
Hope it helps
I created a MemoryStream, copied stream from body there and it was working like a charm :) Point is you cannot read Stream twice. However, this is not a case for MemoryStream. Of course, you have to be sure about scaling, I don't think this will work for really big files uploaded. I didn't tested this.
I rewrote example from Microsoft site: enter link description here
Here is part of it:
while (section != null)
{
ContentDispositionHeaderValue contentDisposition;
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
if (hasContentDispositionHeader)
{
if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
{
var ms = new MemoryStream();
var fileSection = section.AsFileSection();
await fileSection.FileStream.CopyToAsync(ms);
ms.Position = 0;
documentUpload.Attachments.Add(new SimpleFileInstance { FileName = fileSection.FileName, FileStream = ms });
}
else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
{
// Content-Disposition: form-data; name="key"//
// value
// Do not limit the key name length here because the
// multipart headers length limit is already in effect.
var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
var encoding = GetEncoding(section);
using (var streamReader = new StreamReader(
section.Body,
encoding,
detectEncodingFromByteOrderMarks: true,
bufferSize: 1024,
leaveOpen: true))
{
// The value length limit is enforced by MultipartBodyLengthLimit
var value = await streamReader.ReadToEndAsync();
if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
{
value = string.Empty;
}
formAccumulator.Append(key, value);
if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
{
throw new InvalidDataException($"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
}
}
}
}
section = await reader.ReadNextSectionAsync();
}
documentUpload is our DTO to work further with files. In our case, some documents gets uploaded to SharePoint.

Read file local storage windowsphone

I try to read xml files from my windows application.
In this one, I add a folder in Assets/Mocks/clubic.xml (build action : content) to use the data in the xml file as a mock.
So I try to use the following code
var package = Windows.ApplicationModel.Package.Current;
var installedLocation = package.InstalledLocation;
try
{
StorageFile sampleFile = await installedLocation.GetFileAsync("Assets/Mocks/clubic.xml");
}
catch (Exception ex)
{
throw ex;
}
try
{
StorageFile sampleFile = await installedLocation.GetFileAsync("ms-appx:///Assets/Mocks/clubic.xml");
}
catch (Exception ex)
{
throw ex;
}
I obtain for the two cases, the same exception
System.ArgumentException: Value does not fall within the expected range.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at FileReadWrite.MainPage.d__17.MoveNext()}
I try to use this code
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
// Get the DataFolder folder.
var dataFolder = await local.GetFolderAsync("Assets/Mocks");
// Get the file.
var file = await dataFolder.OpenStreamForReadAsync("clubic.xml");
// Read the data.
using (StreamReader streamReader = new StreamReader(file))
{
this.textBlock1.Text = streamReader.ReadToEnd();
}
}
I still obtain the same issue.
Can you help me.
best regards,
Alexandre
Try this
StorageFile sampleFile = await installedLocation.GetFileAsync(#"Assets\Mocks\clubic.xml");
Here's what I've done in an app of mine to read a file that's built as Content:
var resource = System.Windows.Application.GetResourceStream(new Uri(#"Assets\Mocks\clubic.xml", UriKind.Relative));
using (StreamReader sr = new StreamReader(resource.Stream)) {
this.textBlock1.Text = await sr.ReadToEndAsync();
}