I would like to ask you about parsing of XML, I try it by many ways but never get result what I "want/expect".
I would like to get ALL elements of specific name ("packageReference") and his attributes/children(elements). After that I will make collection and parse the result to get value of "include" attribute and value of element/atribute with name "version"
example of xml (my elements which I am interest is on bottom):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="Launch.cs" />
<Compile Include="Launch.designer.cs">
<DependentUpon>Launch.cs</DependentUpon>
</Compile>
<Compile Include="Main.cs" />
<None Include="Info.plist">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Model\Project.Model.csproj">
<Project>{0511395F-513C-4F56-BF87-718CA49BB13B}</Project>
<Name>Project.Model</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper">
<Version>7.0.1</Version>
</PackageReference>
<PackageReference Include="GMImagePicker.Xamarin">
<Version>2.5.0</Version>
</PackageReference>
<PackageReference Include="IdentityModel">
<Version>4.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Analytics">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>4.3.0</Version>
</PackageReference>
<PackageReference Include="Package.Test" Version="1.1.21" />
</ItemGroup>
<ItemGroup />
</Project>
The result should be:
AutoMapper;7.0.1
GMImagePicker.Xamarin;2.5.0
...
...
Package.Test;1.1.21
My code:
var text = System.IO.File.ReadAllText(#"C:\MyGit\TestXML3.csproj");
var root = XElement.Parse(text);
var packageReferencesElements = root.Descendants("PackageReference");
var packageReferencesElementsAndSelf = root.DescendantsAndSelf("PackageReference");
var packageReferencesElementsOffElement = root.Elements().DescendantsAndSelf("PackageReference");
I tried many ways and few of them you can see in code.
I dont want to "go" into every element which have child and checking in loop if there is something what I can be interest. There must be better way. And point there is that I am not sure if my elements which I am looking for is in 2 layer or even deeper.
Update: this code is working to get my information, when I know how deep they are... But when I dont know how deep it should be?
var root = XElement.Parse(fileString);
var itemGroupsELements = root.Elements().Where(x => x.Name.LocalName == "ItemGroup");
var packageReferenceElements = itemGroupsELements.Elements().Where(x => x.Name.LocalName == "PackageReference");
foreach (var packageReference in packageReferenceElements)
{
string packageName = packageReference.Attribute("Include").Value;
string version = (packageReference.Attribute("Version") != null)
? packageReference.Attribute("Version").Value
: packageReference.Value;
_packageList.Add(new Package(){App = app, PackageName = packageName, PackageVersion = version, Project = projectName});
}
Any idea what I am doing wrong?
Thank you!
PackageReference (like all the other elements in the file) is in the XML namespace "http://schemas.microsoft.com/developer/msbuild/2003". You have to specify the namespace in your call to Descendants:
XNamespace build = "http://schemas.microsoft.com/developer/msbuild/2003";
var packageReferencesElements = root.Descendants(build + "PackageReference");
Related
I am trying to get some values from the appsettings.json. But whatever I try with the AdditionalTextsProvider doesn't work. Here is my code
IncrementalValuesProvider<AdditionalText> textFiles = context.AdditionalTextsProvider.Where(static file => file.Path.Contains("appsettings.json")); // tried many things here, like EndsWith(".json") etc..
IncrementalValuesProvider<(string name, string content)> namesAndContents = textFiles.Select((text, cancellationToken) => (name: Path.GetFileNameWithoutExtension(text.Path), content: text.GetText(cancellationToken)!.ToString()));
context.RegisterSourceOutput(namesAndContents, (spc, nameAndContent) =>
{
nameAndContent.content; //always empty
nameAndContent.name; //always empty
});
From the other hand, when I implement the ISourceGenerator (same solution, same projects) this line of code just works!
var file = context.AdditionalFiles.FirstOrDefault(x => x.Path.Contains("appsettings.json"));
The project which is referencing the code generator:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Scrutor" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\myproject\myproject.csproj" />
<ProjectReference Include="..\myproject.EFCore\myproject.EFCore.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="appsettings.json" />
</ItemGroup>
</Project>
Code generator project :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- Generates a package at build -->
<IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<!-- Generator dependencies -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup> <GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>
<Target Name="GetDependencyTargetPaths">
<ItemGroup>
<TargetPathWithTargetPlatformMoniker Include="$(PKGNewtonsoft_Json)\lib\netstandard2.0\Newtonsoft.Json.dll" IncludeRuntimeDependency="false" />
</ItemGroup>
</Target>
<ItemGroup>
<!-- Package the generator in the analyzer directory of the nuget package -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<!-- Package the props file -->
</ItemGroup>
</Project>
If you combine the additional text provider with the compilation it works for me (inspired by this great post):
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var files = context.AdditionalTextsProvider
.Where(a => a.Path.EndsWith("appsettings.json"))
.Select((a, c) => (Path.GetFileNameWithoutExtension(a.Path), a.GetText(c)!.ToString()));
var compilationAndFiles = context.CompilationProvider.Combine(files.Collect());
context.RegisterSourceOutput(compilationAndFiles, (productionContext, sourceContext) => Generate(productionContext, sourceContext));
}
void Generate(SourceProductionContext context, (Compilation compilation, ImmutableArray<(string, string)> files) compilationAndFiles)
{
//emit generated files...
}
Update:
Tested again with Visual Studio 17.4. and combination with compilation seems not to be necessary anymore. Generator is called as expected when appsettings.json changes with only AdditionalTextsProvider registered.
I have tried replicate but everything works for me.
I define my source generator as this
namespace ConsoleAppSourceGenerator
{
[Generator]
public class TxtGenerator : IIncrementalGenerator
{
private static int counter;
public void Initialize(IncrementalGeneratorInitializationContext initContext)
{
IncrementalValuesProvider<AdditionalText> textFiles = initContext.AdditionalTextsProvider
.Where(static file => file.Path.EndsWith(".txt"));
IncrementalValuesProvider<(string name, string content)> namesAndContents = textFiles
.Select((text, cancellationToken) => (name: Path.GetFileNameWithoutExtension(text.Path), content: text.GetText(cancellationToken)!.ToString()));
initContext.RegisterSourceOutput(namesAndContents, (spc, nameAndContent) =>
{
spc.AddSource($"TxtFile.{nameAndContent.name}.g.cs", $#"
// Counter {Interlocked.Increment(ref counter)}
public static partial class TxtFile
{{
public const string {nameAndContent.name} = ""{nameAndContent.content}"";
}}");
});
}
}
}
and source generator project as this
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>Latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" />
</ItemGroup>
</Project>
Then in another project, where I have made a dummy foo.txt file I have
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConsoleAppSourceGenerator\ConsoleAppSourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="foo.txt"/>
</ItemGroup>
</Project>
If I through Visual Studio look at Dependencies->Analyzers->ConsoleAppSourceGenerator>TxtFile.foo.g.cs then it correctly increase the counter on every change I to in the file (see step 9).
I store generated files in path ConsoleApp/Generated/ConsoleAppSourceGenerator/ConsoleAppSourceGenerator.TxtGenerator and whenever I rebuild the project it correctly updates the files.
Have you remembered to add the [Generator] attribute to the IIncrementalGenerator?
Could you test this out and validates this doesn't either work for you?
"AdditionalFiles" in your consuming project file is the key to ensuring these files are captured by your source/incremental generator.
Found out that using a "<AdditionalFiles Include='...' />" is not necessary in some projects such as ASPNET Core projects for Source/IncrementalGenerators. The .cshtml files are included as additional files by default.
Also, file globbing patterns work with the "Include" parameter.
When I send an HTTP request to the function, It shows this error on console output, and returns HTTP 500 status code without hitting the the break point of function's first line.
Executed 'Validate' (Failed, Id=548b4612-42f8-4e49-886a-da6888045c32,
Duration=343ms) System.Net.Primitives: Value cannot be null.
(Parameter 'host') An unhandled host error has occurred.
System.Net.Primitives: Value cannot be null. (Parameter 'host').
Function
[FunctionName("Validate")]
public async Task Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] string req,
[SignalR(HubName = "PubSub")] IAsyncCollector<SignalRMessage> signalRMessageQueue)
{
...
}
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingExcludedTypes": "Request",
"samplingSettings": {
"isEnabled": true
}
}
}
.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<RootNamespace>ZulaMobile.Lobby.StoreValidation</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.30" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.SignalRService" Version="1.6.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.21" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\zulamobile-azure-lobby-common\zulamobile-azure-lobby-common.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Functions\CafeBazaar\" />
<Folder Include="Huawei\" />
</ItemGroup>
</Project>
I tried to reproduce the same issue but it worked fine at my end.
Followed by this MS DOC & demo GitHub project ,
Created a Signal IR in Azure portal .
Open the download folder from my VS Code-
And added the following packages into my local here is my .csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.SignalRService" Version="1.6.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
</ItemGroup>
<ItemGroup>
<None Update="content\index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
And make sure that you have added your connection string in your local settings.json which have to copy from portal from Azure signalIR > Keys>Connection string.
Here are some screenshot for reference output:
Note: If still facing the same issue you can try to Un install the Azure function V3 and install it again .
For more information please refer this SO THREAD .
I am trying to make a console application so as to troubleshoot my question here
I have put the source on Git Hub
The console application project file is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\mopcore\MopCore.csproj" />
<ProjectReference Include="..\MopFW\MopFW.csproj" />
</ItemGroup>
</Project>
Program.cs is
using System;
using System.Linq;
using MopCore;
using MopFW; // error shows here
namespace ConsoleAppCore2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
CountMopsCore();
CountMopsFramework();
}
private static void CountMopsCore()
{
Console.WriteLine($"Hi");
using (var context = new MopContext())
{
var num = context.Mops.Count();
Console.WriteLine($"There are {num} mops \r\n providern {context.Database.ProviderName}");
}
Console.ReadKey();
}
private static void CountMopsFramework()
{
Console.WriteLine($"Hi");
using (var context = new MopFW.MopContext())
{
var num = context.Mops.Count();
Console.WriteLine($"There are {num} mops \r\n in {context.Database.Connection.ConnectionString}");
}
Console.ReadKey();
}
}
}
The netcoreapp3.1 project file is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>MopCore</AssemblyName>
<RootNamespace>MopCore</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.4" />
</ItemGroup>
</Project>
The framework project file is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EntityFramework" Version="6.4.4" />
</ItemGroup>
</Project>
I get build errors
Error NU1201 Project MopCore is not compatible with net472 (.NETFramework,Version=v4.7.2). Project MopCore supports: netcoreapp3.1 (.NETCoreApp,Version=v3.1) ConsoleAppCore2 C:\Users\kirst\source\repos\MopData\ConsoleAppCore2\ConsoleAppCore2.csproj 1
[Update]
I understand that the best way would be to use .netstandard
However I want to explore just getting .netcore and .net472 to work together.
After correcting the console project to be
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
<ProjectReference Include="..\mopcore\MopCore.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<ProjectReference Include="..\MopFW\MopFW.csproj" />
</ItemGroup>
</Project>
I still get build errors in program.cs
You need conditional references.
In your csproj:
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
<ProjectReference Include="..\mopcore\MopCore.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<ProjectReference Include="..\MopStandard\MopFW.csproj" />
</ItemGroup>
OR you need to make MopCore also compatible for net472. E.g. implement netstandard2.0.
I'm trying to load a ViewComponent from a different assembly but in the main project I'm getting the error below
InvalidOperationException: A view component named 'Pro.ItemViewComponent' could not be found. A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. A view component must not be decorated with 'NonViewComponentAttribute'.
Library.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None
Remove="Views\Shared\Components\ContainerViewComponent\Default.cshtml"/>
<None Remove="Views\Shared\Components\ItemViewComponent\Default.cshtml" />
<None Remove="Views\Shared\_ViewImports.cshtml" />
</ItemGroup>
<ItemGroup>
<Content
Include="Views\Shared\Components\ContainerViewComponent\Default.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>$(IncludeRazorContentInPack)</Pack>
</Content>
<Content Include="Views\Shared\Components\ItemViewComponent\Default.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>$(IncludeRazorContentInPack)</Pack>
</Content>
<Content Include="Views\Shared\_ViewImports.cshtml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>$(IncludeRazorContentInPack)</Pack>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Views/**/*.cshtml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.1" />
</ItemGroup>
Startup.cs in main project.
var assembly = typeof(Pro.ItemViewComponent).Assembly;
var embeddedFileProvider = new EmbeddedFileProvider(
assembly,
"Pro"
);
services.Configure<RazorViewEngineOptions>(options =>
{
options.FileProviders.Add(embeddedFileProvider);
});
I have followed many articles and some questions and answer in StackOverflow but I didn't find any solution, What should I do to share the ViewComponent from a different assembly?
The problem was really simple in the configuration in Startup.cs, I had to add services.AddMvc().AddApplicationPart(myAssembly); the full configuration is below.
var myAssembly = typeof(MyViewComponent).Assembly;
services.AddMvc().AddApplicationPart(myAssembly);
services.Configure<RazorViewEngineOptions>(options =>
{
options.FileProviders.Add(new EmbeddedFileProvider(myAssembly, "ComponentLib"));
});
I'm compiling a projet both for net462 and dotnetcore2.0.
I have set the net462;dotnetcore2.0
It seems to work but I need to load an embedded resource like this:
using (var stream = assembly.GetManifestResourceStream("Alcuin.Admin.Api.Beans.TypeTraduction.json"))
using (var reader = new StreamReader(stream))
result = reader.ReadToEnd();
It gives me back a null stream.
Here is my csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net462</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<None Remove="Beans\TypeTraduction.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Beans\TypeTraduction.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Common\Alcuin.Common.Basics\Alcuin.Common.Basics.csproj" />
<ProjectReference Include="..\..\..\..\Common\Alcuin.Common.Graph\Alcuin.Common.Graph.csproj" />
</ItemGroup>
</Project>
Does someone know how to make it work properly?
Thanks.
Nevermind... I just had to remove this section :
<ItemGroup>
<None Remove="Beans\TypeTraduction.json" />
</ItemGroup>
Problem solved.