Microsoft.DotNet.Props directory does not exist for building xproj - msbuild

We are trying to build an xproj project and an error about not being able to find the Microsoft.DotNet.Props file because it seems like its looking at the wrong directory.
Taking a look at the xml MSBuildExtensionsPath32 references C:\Program Files\dotnet\sdk\1.1.4\ where the directory Microsoft\VisualStudio\.. does not exist ... but the normal MSBuild directory C:\Program Files (x86)\MSBuild does have the directory for Microsoft.DotNet.Props file C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Props
Here is the part of the XML
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
The error I see while building is:
error MSB4019: The imported project "C:\Program Files\dotnet\sdk\1.1.4\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
If anyone has any idea what is happening, help would be great
EDIT:
The build is invoked from a Jenkins project on Windows Server 2012 R2.
The VM image is from Azure market place "MicrosoftVisualStudio / VisualStudio / VS-2015-Comm-VSU3-AzureSDK-29-WS2012R2 / 2017.10.12" - which comes with Visual Studio 2015 community edition with update 3.
Azure SDK 2.9. Upgraded Node from old v0.12 to v8.x. Upgraded .NET core from not sure what was installed to 1.1.4.
The xproj itself has no code - except small amount in Startup.cs to serve static files (code at bottom of post).
The application is also used in a Service Fabric project. The error does not come from building the .sln but when packaging up the .sfproj (it might be its not set to build in the sln but packaging will need to build it).
Startup.cs:
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Website
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", true, true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404
&& !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = "/index.html";
await next();
}
});
app.UseStaticFiles();
}
}
}
Edit: here is the whole xproj xml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
<ProjectGuid>17107df8-0cfa-6946-917a-a9b8765cf9ea</ProjectGuid>
<RootNamespace>Website</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
</PropertyGroup>
<ItemGroup>
<DnxInvisibleContent Include="bower.json" />
<DnxInvisibleContent Include=".bowerrc" />
</ItemGroup>
<ItemGroup>
<DnxInvisibleFolder Include="wwwroot\Angular\dist\" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b69-4b1e-b82e-3ada8210c987}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet.Web\Microsoft.DotNet.Web.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

You are trying to use a preview tooling (xproj) with the 1.1.4 version of the .NET Core Sdk. The preview tooling available in VS 2015 does not work with the 1.0+ stable tooling for .NET Core.
Make sure that a preview2 version of the .NET Core SDK is installed both on your development machines and Jenkins server - e.g. 1.0.0-preview2-003156 - and that a global.json file exists your solution directory to tell VS to use this preview version of the SDK:
{
"sdk": {
"version": "1.0.0-preview2-003156"
}
}
As a long-term solution I recommend moving to the stable and supported .NET Core tooling by migrating to VS 2017.

Related

Localhost not found after migrating application from .net 5 to .net 6

I am unable to run my web application project in IIS Express after migrating from .net 5 to .net 6. I get an error stating that "the localhost page can't be found."
From what I've been able to learn, I have gone through the proper steps to migrate between target frameworks. I have changed the target framework to .net 6 in application properties, and I have updated all affected NuGet packages using the NuGet Pkg Manager. No errors are shown when I build the project, and I have ensured Visual Studio is updated to the latest version, 17.2.5 as of this writing.
The IIS Settings in my launchsettings.json file are as follows:
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:35317",
"sslPort": 44352
}
}
and I do have an Index view return in my home controller. Yet I still get the error that
No webpage was found for the web address: https://localhost:44352/
when I run the application.
I am retaining the "old" hosting model of Startup.cs and Program.cs from the .Net 5 build to save time, as I understand per Microsoft that this is acceptable. No changes have been made to the code in either of those files.
What am I missing?
EDIT: My Program.cs code is below, by request of #adrianMoskal
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
EDIT 2:
Per #adrianMoskal, I updated my Program.cs file to .NET 6 standard. It now looks like this:
var builder = WebApplication.CreateBuilder(args);
// Add DB Contexts and Services here
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Unfortunately, the error persists.
I created a new project to migrate from .net 5 to .net 6, but no problem, it works fine, I will show you the complete steps:
.csproj:
change Version like below:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!--<TargetFramework>net5.0</TargetFramework>-->
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>_2022070802</RootNamespace>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.16" />-->
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.1" />
</ItemGroup>
</Project>
Then I delete Startup.cs and change Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Add DB Contexts and Services here
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
More detail information, see this link.
You can create a new empty project to migrate from .net 5 to .net 6 and see if the problem still exists.I think this may be the problem caused by some of your configuration, maybe you can check whether your path is correct?
Chen's answer is the correct migration step.
I tried to reproduce your issue. When I comment Index page method in HomeController. And I face the same issue.
So you probably deleted your "Index" action in HomeController.
The answer appears to be "screw you, start over."
I've tried copying my project code to a new .net 6 project -- that is, copying all the views, controllers, and whatnot to the new project and updating the new Program.cs file accordingly -- and I still got the same error. I then tried converting a different .net 5 project to .net 6, and got the same error again. So apparently, converting just doesn't work.
So be it. I quit. I've got too much else to do to worry about this. Thanks to those who responded to this post for trying to help resolve it, anyway.

Disable precompiled views on development when using "AddControllersWithViews()"

I am developing ASP.NET Core 5.0.1 project and I want to know how can I disable precompiled views while I developing. It takes long time to reload page if I change some html code and I don't want that. I know it is useful at product but I want to disable on development.
Anyone can help me?
UPDATE
app.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services, IWebHostEnvironment env)
{
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(routes =>
{
routes.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"
);
});
}
}
Finally I've found the answer. When using AddControllersWithViews() on ASP.NET Core 3.1 and ASP.NET Core 5.0, the following solutions are not working:
Official Document
StackOverFlow Solution
The solution is simple than I think actually.
Update .csproj file as follow, without any condition:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.1" />
</ItemGroup>
</Project>
Update ConfigureServices method as follow:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddRazorRuntimeCompilation();
}
It's done. When debug, program will not wait to compile view files.

UseSerilog unknown reference in ConfigureWebHostDefaults

i followed few tutorials and im stuck building the default dotnet 3.1 with serilog
in program.cs
this line wont build
here is the code
https://github.com/guymalka/serilog-dotnetcore/blob/master/Program.cs
what reference do I need to add here?
First include nuget package reference in your .csproj file:
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
and dotnet restore your project.
After that import the Serilog namespace in your Program.cs file (you could do that in Startup as well):
using Serilog;
That should be enough for you to register Serilog like so:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Note that if you wish to configure other aspects, e.g., your sinks, with Serilog chances are you'll have to include separate packages:
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />

How do I get an Angular TS file to compile and update on save in a .Net Core project?

So I was watching a channel 9 video on Angular CLI with .Net Core here: https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Angular-and-NET-Core
At position 8:15 he demos auto-syncing where updating a .ts file in the Angular CLI folder compiled on save, then later caused the view to update. I tried this an it does not update at all (unless I refresh the whole page).
I also noticed that the template does not work out of the box (big surprise). I managed to update it to the newer Angular version (and ran into an error where the template had incorrectly created "start": "ng serve --extract-css", to package.json where --extract-css is invalid and had to remove it). I also assumed that Visual Studio (2017) would compile Angular on its own, but it did not, so I added this to the project file:
<Target Name="NgDebug" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">
<!--Run Angular build in debug mode (NOTE: does not support symbolic links nor junction points)-->
<Message Importance="high" Text="Building the Angular code in debug (dev) mode ..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="ng build" />
</Target>
<Target Name="NgRelease" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Release' ">
<!--Run Angular build in prod mode (NOTE: does not support symbolic links nor junction points)-->
<Message Importance="high" Text="Building the Angular code in release (prod) mode ..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="ng build --prod" />
</Target>
Two questions here:
Is this sync feature expected to work today? Is there a configuration required?
Am I expected to setup the ng build step myself, or is there a different method I should be using for the ASP.Net Core (with Angular CLI) template?
Here is the app.UseSpa code:
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
So it appears the correct terminology is "Hot Module Replacement" (MHR - AKA "Live Reloading", or "Hot Updates/Reloading"). Following this answer got me part way there:
https://stackoverflow.com/a/50934814/1236397
The part missing was found here: https://github.com/aspnet/JavaScriptServices/issues/1654#issuecomment-430053872
Both of these links seem to suggest that the template Visual Studio creates is ready for production and not development. The two issues are:
The ClientApp\dist folder may get created at some point if you build outside Visual Studio. The existence of the manually created dist folder will break the live reloading. This folder must be deleted entirely.
The VS ASP.Net Core Angular CLI template is ready to serve static files in production mode. The template creator failed to wrap sections to prevent loading in dev mode.
For #2 change these lines:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
...
public IConfiguration Configuration { get; }
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
...
}
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseSpaStaticFiles();
...
}
to this:
public Startup(IHostingEnvironment env, IConfiguration configuration)
{
HostingEnvironment = env;
Configuration = configuration;
}
...
public IHostingEnvironment HostingEnvironment { get; private set; }
public IConfiguration Configuration { get; }
...
public void ConfigureServices(IServiceCollection services)
{
...
if (HostingEnvironment.IsProduction())
{
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
...
}
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
if (env.IsProduction())
{
app.UseSpaStaticFiles();
}
...
}
However, at this point the pages refresh in full. This is because HMR is not enabled by default. You'll have to follow the proper documentation here:
https://github.com/angular/angular-cli/wiki/stories-configure-hmr
If the link ever goes down, simply search for the documentation using the query configure HMR for angular CLI.
Tip: If you need IE9-11 support, take a look at the polyfills.ts file, and ignore the import 'classlist.js' line, unless you need it (otherwise run npm install --save classlist.js).

Customizing web.config for ASP.NET 5 (vNext) deployments

I'm using kpm pack to generate my deployment, which I deploy to Azure via ftp. I need to be able to serve static json files, so I need to add the following to my web.config:
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="text/html" />
</staticContent>
</system.webServer>
The problem is that kpm pack generates the web.config, so the only way to accomplish this is to add the config section to the web.config after it's been generated. Since I'm doing automated deployments via ci, this would require a bit of effort. Is there a better way to accomplish this?
You should add your configurations to the source of web.config, instead of the target.
If you don't have a web.config in root of the project being packed, please create one. Then add your static content configurations to [project_root]/web.config.
"kpm pack" will preserve all configurations in [project_root]/web.config, add some information needed by IIS, and then write it to wwwroot/web.config.
Important Update:
A change was introduced in "kpm pack": https://github.com/aspnet/KRuntime/pull/972
Please move your web.config from project root to the source of wwwroot.
The source of wwwroot folder can be specified with 'webroot' in project.json (https://github.com/aspnet/Home/wiki/Project.json-file#webroot).
You can also specify it with '--wwwroot' option of "kpm pack".
In ASP.NET Core you may be able to avoid web.config altogether by configuring the static file middleware options (StaticFileOptions) in code, providing a custom FileExtensionContentTypeProvider as its ContentTypeProvider:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddInstance<IContentTypeProvider>(
new FileExtensionConentTypeProvider(
new Dictionary<string, string>(
// Start with the base mappings
new FileExtensionContentTypeProvider().Mappings,
// Extend the base dictionary with your custom mappings
StringComparer.OrdinalIgnoreCase) {
{ ".json", "text/html" }
}
)
);
...
}
public void Configure(
IApplicationBuilder app,
IContentTypeProvider contentTypeProvider)
{
...
app.UseStaticFiles(new StaticFileOptions() {
ContentTypeProvider = contentTypeProvider
...
});
...
}