Xamarin App - Resource file, how to include an audio file into the AppResources.Designer.cs - xamarin.forms

I am working on a Xamarin Form App and we use .resx files for the localizations.
I have got a problem where to my Resources folder I would like to add an audio file called Beep.wav.
Previously in the AppResources.Designer.cs I used to have something like this:
/// <summary>
/// Looks up a localized resource of type System.IO.UnmanagedMemoryStream similar to System.IO.MemoryStream.
/// </summary>
internal static System.IO.UnmanagedMemoryStream Beep
{
get
{
return ResourceManager.GetStream("Beep", resourceCulture);
}
}
but for some reason is not there anymore and when I regenerate that file by adding/removing a string in AppResources.resx file, still it is not there. It does work if I add that manually but everytime we add a new string it gets wiped away.
I am adding some screenshots to give a bit better meaning to what I am trying to achieve:
My resources folder:
My .csproj file for that project
My AppResources.Designer.cs file which should include the piece of code I have typed earlier
How do I get my Beep.wav file included in there?
This is where it is failing as it cannot find "Beep"
private static readonly ISimpleAudioPlayer _beepPlayer;
static MediaPlayerHelper()
{
_beepPlayer = CrossSimpleAudioPlayer.CreateSimpleAudioPlayer();
_beepPlayer.Load(Resources.AppResources.Beep); <--Error
}
Thanks

After creating the .resx file, change Strings to Audio.
Click Add Resource to add the .wav file.
After that, it would generate the code below in AppResources.Designer.cs.
/// <summary>
/// Looks up a localized resource of type System.IO.UnmanagedMemoryStream similar to System.IO.MemoryStream.
/// </summary>
internal static System.IO.UnmanagedMemoryStream WAV_1MG {
get {
return ResourceManager.GetStream("WAV_1MG", resourceCulture);
}
}

Related

in ASP.NET core (.NET5) how can i write logs for each request on separate files? Using Serilog or other

I'm new to .NET and to webservice development, so i'm not exactly sure how to implement the requirement i have.
My webservice gets a POST request with some data, which i need to
process to generate a pdf file: name_YYYYMMDDHHmmss.pdf.
For monitoring this i want to have a separate logfile for each request, named like the output file: name_YYYYMMDDHHmmss.log
I would like to avoid passing a config object into every class/function in which i need to add stuff to the log file
I've managed to install Serilog and it works for what i need, but not when i get concurrent requests. I'm also not exactly sure how simultaneous requests are handled in .NET (i have no thread specific code written so far), but as far as i can tell, when i change Global Logger file name, that object is shared across all threads so all of them write to the same file.
I've looked at a bunch of solutions, but i haven't managed to find nothing that suits this, and it seems most people have everything into 1 file...
Is there any clue or tips you can give me? I'm open to using something other than Serilog.
One way to have dynamic file names based on a specific context is by using the Serilog.Sinks.Map and then, via a middleware in the request pipeline, you can add a property to the log context that drives the file name to be used when writing to the log.
Examples of similar usage of Serilog.Sinks.Map to decide which file name to use at run-time:
Serilog - can not log to multiple files based on property
In Serilog dynamically changing log file path?
The best solution that I found to this problem was using Serilog.Sinks.Map. I configured my Logger something like this:
Log.Logger = new LoggerConfiguration()
.WriteTo.Map("Name", "Default", (name, wt) => {
var fileName = name == "Default" ? "log" : $"{log-{name}}"
wt.File($"./{fileName}-.txt");
}).CreateLogger();
Then on my controller, on each method where I needed this feature, I enclosed all the instructions inside a LongContext like this:
[HttpGet]
public IHttpActionResult Get() {
using (LogContext.PushProperty("Name", "theFileName") {
// ...
_myService.Method1();
// ...
}
}
public class MyService : IMyService {
// ...
public void Method1() {
// ...
Log.Information("This is what happened at this point…");
// ...
}
// ...
}
So all the Log's inside will use that context and it will write on a different file with the name you set for that context without having to modify any Log.Information/Error/Warning/etc that you already have on your code.
This is the ugly part... you have to define a context on a root place in order to make those Logs write on a different file. So for a controller method, the first thing you have to do is to enclose all with a LogContext.

Customizing auto generated Swagger definitions

I have swagger setup so that it generates the open Api Specification & Swagger Ui on project startup using NSwag based on the controllers in my WebApi.
I would like to enhance the swagger Ui to include
A summary/description for each endpoint
Example parameter inputs for endpoints that require them
Example request body for POST calls
An example access token that can be used only in the swagger documentation to easily authenticate and be able to try everything out (a bit like in this example https://petstore.swagger.io/)
I'm new to NSwag and unsure how to approach adding these enhancements to my code, like where to add them, what i need to use (annotations on controllers? XML comments? another way?) I've tried editing the specification in 'Swagger Editor' but don't see how this can be the way to go since this gets re-generated on every application startup.
I've read the NSwag documentation but that seems to be all about adding the ASP.NET Core middleware, which I already have configured.
Edit:
I now have a description at the top of the page, and have been able to add an example with the remarks tag in XML comments - is there a more elegant way to do this rather than using XML comments?
A description at the top of the page
To customize the API info and description using Nswag, in the Startup.ConfigureServices method, a configuration action passed to the AddSwaggerDocument method adds information such as the author, license, and description:
services.AddSwaggerDocument(config =>
{
config.PostProcess = document =>
{
document.Info.Version = "v1";
document.Info.Title = "ToDo API";
document.Info.Description = "A simple ASP.NET Core web API";
document.Info.TermsOfService = "None";
document.Info.Contact = new NSwag.OpenApiContact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = "https://twitter.com/spboyer"
};
document.Info.License = new NSwag.OpenApiLicense
{
Name = "Use under LICX",
Url = "https://example.com/license"
};
};
});
The Swagger UI displays the version's information as below:
A summary/description for each endpoint Example parameter inputs for
endpoints that require them Example request body for POST calls An
example access token that can be used only in the swagger
documentation to easily authenticate and be able to try everything out
(a bit like in this example https://petstore.swagger.io/)
You could add the description/example by adding the following elements to the action header.
Use the <summary> element to describe the Endpoint.
Use the <remarks> element to supplements information specified in the <summary> element and provides a more robust Swagger UI. The <remarks> element content can consist of text, JSON, or XML. You could also use it to add sample.
Use the <param> element to add the required parameters. Besides, you could also use the Data annotations attribute with the Model, it will change the UI behavior.
Use the <response> elements to describe response types.
sample code as below:
/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "id": 1,
/// "name": "Item1",
/// "isComplete": true
/// }
///
/// </remarks>
/// <param name="todoitem"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
#region snippet_CreateActionAttributes
[ProducesResponseType(StatusCodes.Status201Created)] // Created
[ProducesResponseType(StatusCodes.Status400BadRequest)] // BadRequest
#endregion snippet_CreateActionAttributes
#region snippet_CreateAction
[HttpPost]
public ActionResult<TodoItem> Create(TodoItem todoitem)
{
_context.TodoItems.Add(todoitem);
_context.SaveChanges();
return CreatedAtRoute("GetTodo", new { id = todoitem.Id }, todoitem);
}
The Swagger UI now looks as below:
More detail information, please check the following tutorials:
Customize API documentation using NSwag
Customize API info and description using Swashbuckle
Figured this out now, ended up using operation processors to configure the Swagger UI/OpenApi endpoint summary, request examples, path parameter example values and the possible UI response codes
There isn't a lot of documentation online for doing it this way (all i could find was the XML comment way of doing it so this took a lot of trial and error to get this working)
Posting my solution here for anyone else who would prefer not to clutter up their controllers with XML comments.
Apply OpenApiOperationProcessor attribute to the controller action
Create the Operation Processor and code the SwaggerUI customizations
Example values for path parameters can be filled out as so

Unit Testing for Websites or Webforms or .Aspx page: code coverage

I have one website which was made in Asp.Net. I want to have the code coverage for the website now.
Can anybody suggest me which are the possible ways to have the code coverage for the website? Suggestions on how to write unit test methods for Webform or .Aspx page are also welcome.
Try following steps to enable code coverage:
- Open the local.testsettings which you can access from Test -> Edit
Test Settings -> Local (local.testsettings)
- List item Select Data and Diagnostics from the list
- Select the Enabled checkbox on the Code Coverage row
- Double-click the Code Coverage row
- Select the assemblies you want to instrument
- Specify a re-signing key file if your assemblies are strong-named
- Click OK
- Click Apply
- Click Close
For unit test you can have seperate class library project in the same solution where you can create unit test method. For example :
/// <summary>
/// Holds test for MapRoles.
/// </summary>
[TestClass]
public class MapRolesTest
{
/// <summary>
/// Perform test on CompareUserRoles.
/// </summary>
[TestMethod]
public void CompareUserRolesTest()
{
//// The class which is inside actual asp.net web application.
MapRoles objMapRoles = new MapRoles();
//// Get role of the user1.
string user1Role = objMapRoles.GetUserRole("Jeet");
//// Get role of the user2.
string user2Role = objMapRoles.GetUserRole("Vishwajeet");
//// Assert.
Assert.AreEqual(user1Role, user2Role);
}
}

What does DotLess' "web" attribute do exactly?

The dotless documentation is quite limited. I can't find much information at all about the configsection options - especially what the "web" attribute does.
Can anyone enlighten me?
The code is normally pretty good documentation for open source projects ;)
Grab a copy of the code and look in dotless.Core > configuration > DotlessConfiguration.cs you will see some handy comments about all the config elements - this is the Web one
/// <summary>
/// Whether this is used in a web context or not
/// </summary>
public bool Web { get; set; }
Admittedly it doesn't tell you a great deal but find the references to that property and you come across only one place in the code where it is used -
if (!configuration.Web)
RegisterLocalServices(pandora);
Which starts to give you a better clue as to what it does which is this
protected virtual void RegisterLocalServices(FluentRegistration pandora)
{
pandora.Service<ICache>().Implementor<InMemoryCache>();
pandora.Service<IParameterSource>().Implementor<ConsoleArgumentParameterSource>();
pandora.Service<ILogger>().Implementor<ConsoleLogger>().Parameters("level").Set("error-level");
pandora.Service<IPathResolver>().Implementor<RelativePathResolver>();
}
So it sets up in memory caching, logging to the console etc (i.e services it uses if not in a web context)

How to dynamically load and switch the resource file in the web app (ASP.NET) without recompiling?

I would like to store the resource files (containing texts for labels etc.) for my web application in the database to be able to edit and create them dynamically later (probably in the UI). My idea was to store the whole resx file in an xml column and simply load it on demand - depending on the language and some other attributes of the current user when he is logging into the application or switching the context. The important thing is that the resources do not only depend on the culture info of the user but also on some context information that can be switched by user without logging off and on again (in our case called "group", not having anything to do with a group of users).
Is it possible somehow to load the contents of the resources from an external source and simply switch them without web application being recompiled by the server ? I know that there are some interfaces on which I could hook up and implement a custom resources provider which reads from the database directly but if it could work somehow with the resx files it would probably make things a lot easier..
Pretty late but since there is no answer as of yet.
System.Resources.ResourceReader resourceReader
= new System.Resources.ResourceReader("PathToResourceFile");
That's pretty much it. Now you can create resource files like en.resx or de.resx and load them depending on the users language. Something like
System.Resources.ResourceReader resourceReader
= new System.Resources.ResourceReader(HttpContext.Current.Request.UserLanguages[0]
+ ".resource");
Keep in mind to provide a default language (resource file) for a user with a language you don't support.
Edit:
Take a look at this link.
The question is 6 years old, but I'm still gonna answer it :)
To read .resx files, you need to use System.Resources.ResXResourceReader class from System.Windows.Forms.dll
This is nicely explained here. Just a quick sample for completeness:
using (ResXResourceReader resxReader = new ResXResourceReader(#".\CarResources.resx"))
{
foreach (DictionaryEntry entry in resxReader) {
// ...
}
}
Sure you can do this easily, and it works for straight XML files. You don't need to use a resx file.
/// <summary>
/// Sets or replaces the ResourceDictionary by dynamically loading
/// a Localization ResourceDictionary from the file path passed in.
/// </summary>
/// <param name="resourceDictionaryFile">The resource dictionary to use to set/replace
/// the ResourceDictionary.</param>
private void SetCultureResourceDictionary(String resourceDictionaryFile)
{
// Scan all resource dictionaries and remove, if it is string resource distionary
for ( int index= 0; index < Resources.MergedDictionaries.Count; ++index)
{
// Look for an indicator in the resource file that indicates the resource is
// swappable. For instance in our files the header contains this:
// <sys:String x:Key="ResourceDictionaryName">Resources-en-CA</sys:String>
if (Resources.MergedDictionaries[index].Contains("ResourceDictionaryName"))
{
if ( File.Exists(resourceDictionaryFile) )
{
Resources.MergedDictionaries.Remove(Resources.MergedDictionaries[index]);
}
}
}
// read required resource file to resource dictionary and add to MergedDictionaries collection
ResourceDictionary newResourceDictionary = new ResourceDictionary();
newResourceDictionary.Source = new Uri(resourceDictionaryFile);
Resources.MergedDictionaries.Add(newResourceDictionary);
}

Resources