swagger-ui returns 500 after deployment - c#

Out of the box configuration works perfectly on my machine, no problems at all.
But when I deploy to our test environment - I get the following message
500 : { "Message": "An error has occurred." } /api/swagger/docs/v1
The deployment is to default web site/api
Im guessing it has something to do with the baseUrl or something like that,
but I have no idea of even where to begin.
My routes work fine within the project - I can call all my webapi endpoints and they respond correctly.
any help would be much appreciated

When debugging I was using the debug config (Which I had generated XmlComments for: Properties -> build tab -> Output -> XML Documentation File)
I had not done this for my release configuration (duh...) - now everything works

thank you #VisualBean.
As it was not so obvious for me .... how to... a simple image.
In Project > Your Project properties > Build Tab

Swashbuckle is hiding the real error message due to your customErrors setting in web.config. If you set customErrors to off you should get a better error message.
<system.web>
<customErrors mode="Off"/>
</system.web>

As stated in the accepted answer you have to make sure the XML documentation file output is in bin and not bin\Debug or bin\Release (verify this for all build configurations).
I still got the 500 response because I use multiple XML documentation files.
In my SwaggerConfig implementation I include XML documentation files from two projects (the WebApi project itself and a class library that is referenced by the WebApi project):
c.IncludeXmlComments(string.Format(#"{0}\bin\MyWebApiProject.xml", System.AppDomain.CurrentDomain.BaseDirectory));
c.IncludeXmlComments(string.Format(#"{0}\bin\ReferencedProject.xml", System.AppDomain.CurrentDomain.BaseDirectory));
The XML documentation file of the WebApi project was published correctly to the bin folder of the site, however the XML documentation file of the referenced project was not (even though it appears in the bin folder of the compiled project).
So you need to modify the WebApi project file (.csproj) in a text editor and add the following sections at the bottom (replace ReferencedProject):
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\ReferencedProject\bin\ReferencedProject.xml" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>bin\%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
See How do you include additional files using VS2010 web deployment packages? for a full explanation.

The issue is that running dotnet publish with -r Release does not produce XML file. However, dotnet publish with -r Debug does in fact produce the file. This explains why people are only getting this issue when they are deploying to environments OTHER than locally, then kicking themselves when the find the exception only occurs on prod.(ITS THE RELEASE) In order to reporoduce, simply run those command locally and view output directory and you should see the issue.
(UPDATE) The fix for me was to actually go into .csproj file and add a line to ensure that the file was copied over always.
Diff shown below

The accepted answer should be the first thing you try.
However, I have my XML output set to go to App_Data\ and have my Swashbuckle configured to read from that directory, so, it doesn't matter which way it gets built: the xml files are going to 'be there'. Nevertheless, I was still getting the error...
I found over at MSDN's forums #enough2012's answer:
select "Remove additional files at destination" in the "File Publish Options" within the "Settings" pane of the Publish dialog.
Worked like a charm!

Related

How do I remove "multiple publish output files with the same relative path" in a dotnet core WinUI3 application?

First time poster, so please let me know if I forgot anything.
I've got a dotnet project I've been working on using WinUI3 in Visual Studio 2022. More or less it grabs some reports from Azure using Microsoft Graph.
When trying to package the application, for use on a different machine, I get the following error:
error NETSDK1152: Found multiple publish output files with the same
relative path:
C:\Users\McTwitch\source\repos\Heimdall\obj\x64\Release\net6.0-windows10.0.19041.0\win10-x64\MsixContent\Microsoft.Web.WebView2.Core.dll,
obj\x64\Release\net6.0-windows10.0.19041.0\win10-x64\R2R\Microsoft.Web.WebView2.Core.dll.
I've added
<PropertyGroup>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
</PropertyGroup>
to my .csproj file, and that gives me a different error:
Severity Code Description Project Path File Line Source Suppression State
Error APPX1101 Payload contains two or more files with the same destination path 'Microsoft.Web.WebView2.Core.dll'. Source files:
C:\Users\McTwitch\source\repos\Heimdall\obj\x64\Release\net6.0-windows10.0.19041.0\win10-x64\MsixContent\Microsoft.Web.WebView2.Core.dll
C:\Users\McTwitch\source\repos\Heimdall\obj\x64\Release\net6.0-windows10.0.19041.0\win10-x64\R2R\Microsoft.Web.WebView2.Core.dll SIEMGUI C:\Users\McTwitch\.nuget\packages\microsoft.windowsappsdk\1.2.221109.1\buildTransitive C:\Users\McTwitch\.nuget\packages\microsoft.windowsappsdk\1.2.221109.1\buildTransitive\Microsoft.Build.Msix.Packaging.targets 1504 Build
I've also checked Tools>NuGet Package Manager > Manage NuGet Packages for this Solution, but there aren't any entries under "Consolidate".
There was one post (Publish error: Found multiple publish output files with the same relative path) that mentioned adding some lines to the common.props file, but I haven't been able to locate the file, which is a tad frustrating.
Any and all help is appreciated, and I'll try to reply as quickly as I can to any additional questions or requests for information.

Xamarin: Getting error while building -> invalid file path 'obj\Debug\90\res\views\layouttest.xml'

While I'm trying to build my Xamarin App, it stops everytime with the error message "invalid file path 'obj\Debug\90\res\views\layouttest.xml'". I tried to delete the directory, rebuild or clean the solution and build it again.
The error comes from the Android Project.
The file that is marked from VS is in the directory:
Directory Output
Update:
As Land Lu - MSFT mentioned below, was an unused file the issue. Deleting the file and rebuilding the project worked just fine!
It seems there is a cache file named layouttest.xml in your project.
Try to remove the file there if you don't need it.
Delete the bin/obj folders of your project to make a full cleaning. Finally, rebuild your project to complete the compiling.
If you are finding this error after updating VS2019 to 16.7.2 please see the following articles:
https://developercommunity.visualstudio.com/content/problem/1156349/index.html
https://github.com/xamarin/xamarin-android/issues/5052
The TLDR is that android resources now have to be present in standard folders such as Resources/layout and Resources/drawable. Using random folders within your project will generate build errors.
Just to add to the fun, I had a resource that had somehow ended up as the dependent of another file.
<AndroidResource Include="Main.axml">
<DependentUpon>CanvasRenderContext.cs</DependentUpon>
</AndroidResource>
I had to edit the csproj file to remove the DependentUpon tag before I could move to Resources/layout folder. Hopefully you wont have an issue quite that weird.
For those hitting this from the MAUI side as I was - my issue was that I had an image resource file that was not added to the project correctly. Looked at the properties for the image in Solution Explorer and it was still an Android resource rather than a MAUI image. Guess this makes sense, was migrating the image from a Xamarin Android app. Had some lines in the project file explicitly removing it from the MAUI image category and adding it to the Android resource category. Looked something like this:
<ItemGroup>
<MauiImage Remove="Resources\Images\foo.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\Images\foo.png" />
</ItemGroup>
Removed those lines and the image was correctly recognized as a MAUI image, and the issue went away.

WPF Clickonce publish with Microsoft.Net.Sdk

I can successfully build a WPF application with the new csproj format using the Sdk="Microsoft.Net.Sdk".
However, it is a bit of a challenge to publish the said app. The option is definitely not available from the IDE. But what I find a bit puzzling is that the Publish target doesn't seem to be available when you call msbuild directly.
These are some of the top-level properties I set:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<LanguageTargets>$(MSBuildExtensionsPath)\$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
<OutputType>WinExe</OutputType>
<PlatformTarget>x86</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<!--<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>-->
</PropertyGroup></Project>
I also set the typical ones associated with the ClickOnce eg PublishUrl, etc. What can I do to get at/expose the Publish target the same way the LanguageTarget above enables "CoreBuild" for the other legacy C# build tasks outside Console, Web and plain libraries.
Further Thoughts:
So, it turns out that on further inspection, there is actually a Publish target. But it does a simple folder/xcopy deployment to a subfolder called Publish rather than creating an app.publish folder and doing the ClickOnce thing.
How does one work around this?
You can manually publish ClickOnce using the Mage.exe (command line) or MageUI.exe (gui) tools. It's not very convenient but it does seem to work if you get everything right. I'll outline what worked for me using MageUI.exe.
Choose the correct version of the utility for the .NET version you're using from:
C:\Program Files (x86)\Microsoft SDKs\Windows\
First publish your application files to a folder. Normally this would be something like:
\\server\share\MyApplication\Application Files\MyApplication_1_0_0_25\
NOTE: I had issues with the space in Application Files, where it would be converted to %20, but I don't think UNC paths support that value. I had to remove the space and renamed the folder to ApplicationFiles. (This will probably break previously published versions though.)
Then use MageUI.exe to create a new application manifest:
On the Name page, give it a name, version, and choose a processor architecture (x86).
On the Files page, enter the directory you published the files to, and then hit populate. It should load all the program files into the DataGridView below.
On the Permissions Required page, I was not able to get it working with anything less than FullTrust. Without FullTrust, when the application was run, nothing happened.
Save the manifest file as MyApplication.exe.manifest to the application folder. (You will be able to sign the manifest when you save it.)
Now create a new Deployment manifest:
On the Name page, enter the same name and version and choose the right processor architecture.
On the Description page, enter Publisher and Product.
On the Deployment Options page, I chose Online Only. I did not include a Start Location.
On the Application Reference page, choose Select Manifest and browse to the application manifest file you previously created.
Save the deployment manifest as \\server\share\MyApplication\MyApplication.application; (you can sign it when you save.)
NOTE: A glitch here seems to be that it will have inferred the wrong relative path when you select the application manifest file. After you've saved the deployment manifest the first time, go select the application manifest file again, and it will now infer the correct relative path. Then hit save again and you should be ok.
There are a lot of things that can go wrong and a lot of ways that the procedure can differ, but these are the steps that worked for me.
(Another thing I had to do during these steps was clear my ClickOnce Application Cache, by deleting the contents of c:\users\username\AppData\Local\Apps\2.0\. But that was probably just because of all the mistakes I made. I would only do this if you get stuck.)
Microsoft is finally adding ClickOnce functionality to SDK Style Winforms and WPF projects in .NET 5.
I was able to put ClickOnce in a WPF net48 project with new SDK style as before of moving to the new SDK.
It was necessary just to put this block in the end of my .csproj file:
<PropertyGroup>
<PublishProtocol>ClickOnce</PublishProtocol>
</PropertyGroup>
<Import Sdk="Microsoft.NET.Sdk.WindowsDesktop" Project="Sdk.props" />
<Import Sdk="Microsoft.NET.Sdk.WindowsDesktop" Project="Sdk.targets" />
<Target Name="ComputeAndCopyFilesToPublishDirectory" />
It does the following:
set SDK to not skip the import of Microsoft.NET.ClickOnce.targets. That is achieved by setting <PublishProtocol>ClickOnce</PublishProtocol>
set SDK to avoid bin/debug/**/* files to be copied to publish directory.
That is achieved by skipping the "ComputeAndCopyFilesToPublishDirectory" target execution. To do so, we've overriden it to an empty implementation.

ConfigurationManager.AppSettings getting null?

I did not realize that: 'have a web.config in a separate class library and' was reading the web.config app setting from different web application.
I am using VS2010 target framework 3.5
I don't know what is wrong here but I am getting null when I try to get ConfigurationManager.AppSettings["StoreId"];
private string _storeid = GetStoreId;
public static string GetStoreId
{
get
{
return ConfigurationManager.AppSettings["StoreId"];
}
}
web.config:
<appSettings>
<add key="StoreId" value="123" />
</appSettings>
If you are UNIT TESTING you need A COPY of the APP.CONFIG inside the UNIT TEST PROJECT
Update
You can have an AfterTargets in your CsProj file that copies the config:
<Target Name="CopyAppConfig" AfterTargets="Build" DependsOnTargets="Build">
<CreateItem Include="$(OutputPath)$(AssemblyName).dll.config">
<Output TaskParameter="Include" ItemName="FilesToCopy"/>
</CreateItem>
<Copy SourceFiles="#(FilesToCopy)" DestinationFiles="$(OutputPath)testhost.dll.config" />
</Target>
Problem
The usual cause for this is due to context.
Cause
When you have a solution with two projects, if the App/Web.Config is in the main project it wont work if the context of the running application is the second project such as a library, unit test, etc.
Conundrum
To read values from the config in other projects (with System.Configuration) you'll need to move/copy the config file to the project with the running context. Unfortunately duplicating files defeats the tenants of good programming; OOP, Source Code Management, SOLID, etc.
Cool Solution
A nifty solution is adding config file shortcuts in other projects so you only update one file:
It would be nice to divide the contents of config files across project's. Elegantly, like Sharing Assembly Files as per answer #2: https://stackoverflow.com/a/15319582/495455 but alas it's by context
Disclaimer ;) This post is not to answer OP as it is too late but definitely it would help the readers who end up to this page.
Problem I faced : ConfigurationManager.AppSettings["uName"] returning null in my C# web api project.
Basic Things I checked for :
1) In code ConfigurationManager.AppSettings["uName"] , I was using exact key 'uName' as I had in web.config file,
i.e
<appSettings>
<add key="uName" value="myValue" />
</appSettings>
Checked that I haven't mis typed as userName instead of uName etc.
2) Since it is a Web API project it would have a file as web.config instead of app.config , and that too in root folder of your project. [refer the image].
Solution :
The solution that worked for me ,
Changed ConfigurationManager.AppSettings["uName"] to WebConfigurationManager.AppSettings["uName"]
and
made sure that I had
<appSettings>
<add key="uName" value="myValue" />
</appSettings>
in the right file ie.
Right file is not web.config in View folder
neither the debug or release web.config
and:
<appSettings>
<add key="StoreId" value="123" />
</appSettings>
is located in the web.config file of your ASP.NET application and not in some app.config file you've added to your class library project in Visual Studio, right? You can't be possibly getting null if this is the case. If you've added this to an app.config of you class library project in Visual Studio then getting null is perfectly normal behavior.
I just got answer DLL are called from another project not in the project where there are create.so entries in App.config should b move to calling project config file.
For example i have 2 project in my solution one class library and other console application.i have added class library reference in Console application.So if i add app.config file in class library project it through null exception.it works when i added app.config in console application.Hope it works
App settings are loaded into ConfigurationManager.AppSettings, but User settings (in Properties settings in your project properties) are not.
In Visual Studio, right-click on the config file, select Properties, and then change "Copy to Output Directory" to either "Copy always" or "Copy if newer".
Alternatively, manually add the following section as a child of the element in your .csproj file (this one is for "Copy always" for file "App.config"):
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
I tried all of these solutions but none worked for me. I was attempting to use a 'web.config' file. Everything was named correctly and the files were in the proper location, but it refused to work. I then decided to rename my 'web.config' file to 'app.config' and just like that, it worked.
So if you are having this issue with a 'web.config' file be sure to rename it to 'app.config'.
This happened to me when I was testing a Class Library (.dll). They were both in the same project but the App.config for the library had the settings I needed. The App I had written to test needed the settings because it was running the library.
I got this problem as I copied a project from the file explorer and renamed the project. This copied the Debug folder and as I didn't have it set to 'Copy if newer' it didn't overwrite the old App.config file.
Just delete the Debug folder and rebuild. Hope that helps someone.
I agree with above answer and I would like to add few more points
you should make sure you don't put space before and after the :
see code below:
private static string Client_ID = ConfigurationManager.AppSettings["ida:ClientId"];
if you put space between ida: ClientId it will not work and will return null
make sure your key value names are correct
you can try WebConfigurationManager
Happened to me just now, only when calling it from another project.
Apparently, at the other project, the reference has not been defined as a Service Reference but rather as a Connected Service. I deleted the reference and added it again.
string setting = ConfigurationManager.AppSettings["Setting"];
Make sure config file is in the same folder as code referencing it. Create a
helper class if it is not. Duplicating this could cause confusion should
someone forget it exists in two places.
Keep app settings in an app.config and not a web.config for AppSettings.I had this issue with a key in the web.config.

Multiple .NET Configuration Files and Setup Project Problem

In order to handle settings for different deployment targets, I moved application settings from app.config to its own file and included that file in app.config via configSource. I also created a settings file for each target.Here is an illustration:
Project A
app.config (references settings.config)
settings.config
settings.Release.config
settings.Debug.config
During post-build, I copy the appropriate settings.{configuration}.config to the output directory. This is working fine so far and I can see settings.config file in the project output directory containing settings for the current build configuration: Release, Debug, etc.
However, I am having a problem with the setup project that I have for this project (Project A). Initially, it was not including settings.config file. So I set the build action for settings.config file as Content and I added content files from Project A to the setup project. This ensured that settings.config file was included in the setup. However, since the setup project appears to be picking settings.config file from the project directory instead of the output directory, settings.config file included in the setup is not what it should be. I want the one from the output directory to be included in the setup program since that one is the correct one for the current build configuration. I tried the following:
Added settings.config as a file to the setup project. However, it seems like I can only specify absolute path. So when I add it from the output directory of a particular build configuration (..bin\debug\settings.config), it does not work in other build configuration since (..bin\debug\settings.config) does exist in the directory specified. I looked into using relative paths or dynamic paths in the setup project where the build configuration could be specifed as part of the path but I could not find anything.
I considered using pre-build event to actually modify settings.config file in the project directory and then have it copied over the output directory by setting its 'Copy to Output Directory' to copy always or copy if newer. This should ensure that the appropriate settings.config is copied to the output directory just like the post-build based solution and should also ensure that the contents of settings.config file is updated before the setup project includes it. However, I don't like this solution because I would have to make sure settings.config file is writeable before I can make any changes since it is source controlled. If it is readonly, then I need to flip it to writeable, make changes, and then set it to readonly again. It is adding extra complexity.
I was wondering if anyone has a better idea or knows a setup project trick that allows me to include settings.config file appropriate for the current build configuration in the setup program.
Thanks
If I had to approach this problem, I'd start by asking the following question:
Why does settings.config have to be under source code control if settings.Debug.config or settings.Release.config provide the same information?
The answer, if I read your question correctly, is because you needed to force a settings.config file to appear as part of the build output. I'm guessing this is because your setup project is using the built in "Primary output" choice.
What you can do instead is add that file to your setup project as an explicit file reference. Right-click on the setup project and choose add / file, then select the file you want to include. As you'll notice (unless it's been fixed in VS2008 which sadly I'm not yet allowed to use at work), there is a very annoying limitation placed on manually added files - there is no way to make the path build configuration aware. You can work around that by copying the appropriate settings.config file to a common location (e.g. bin/Configuration) and picking it up from there. This does limit you to building Debug and Release versions sequentially, rather than in parallel, but for many this probably isn't a huge problem.
If you aren't required to use VS setup projects, I strongly encourage you to take a look at WiX (Windows Installer XML - see http://wix.sourceforge.net/ for more information). That will easily allow you to accomplish what is necessary, although if you are unfamiliar with the internal workings of Microsoft Installer the initial learning curve could be a little steep. Microsoft use WiX themselves for some pretty significant setup tasks (e.g. Office 2007, SQL Server, etc.). It had been hoped that WiX would become part of Visual Studio (for VS 2010), but sadly that is no longer the case.
I decided to go about achieving the same result (being able to have different configuration settings for different target environments) in a different way. So here is how I implemented it and it is working great. I read some of the posts here at SO about XmlMassUpdate task from MSBuild Community Tasks and decided to utilize it. Here is what I did:
1) For each project that needs to have different settings depending on the target environment, I added an xml file called app.config.substitutions.xml or web.config.substitutions.xml to the project. So, the project looked like
Project A
app.config
app.config.substitutions.xml
app.config.substitutions.xml file has the settings substitutions that XmlMassUpdate will process and apply to app.config file. Below is a sample substitution file that I use:
<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
<substitutions>
<Development>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="DevValue" />
</appSettings>
</Development>
<Test>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="TestValue" />
</appSettings>
</Test>
<Release>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="ReleaseValue" />
</appSettings>
</Release>
</substitutions>
</configuration>
For details on how to specify substitutions, take a look at the documentation for XmlMassUpdate or just do a search on it.
2) Now I need to run XmlMassUpdate as part of build automation (TeamBuild/MSBuild). So in BeforeCompile in TeamBuild build definition file (basically a proj file), I added the following to run XmlMassUpdate on config files that have a corresponding .substitution.xml file
<PropertyGroup>
<SubstitutionFileExtension>.substitutions.xml</SubstitutionFileExtension>
<TargetEnvironment>Test</TargetEnvironment>
</PropertyGroup>
<Target Name="BeforeCompile" Condition="'$(IsDesktopBuild)'!='true'">
<CreateItem Include="$(SolutionRoot)\**\app.config;$(SolutionRoot)\**\web.config">
<Output ItemName="ConfigurationFiles" TaskParameter="Include"/>
</CreateItem>
<CreateItem Include="#(ConfigurationFiles)" Condition="Exists('%(FullPath)$(SubstitutionFileExtension)')">
<Output ItemName="ConfigFilesWithSubstitutions" TaskParameter="Include"/>
</CreateItem>
<Message Text="Updating configuration files with deployment target specific settings..."/>
<XmlMassUpdate
ContentFile="%(ConfigFilesWithSubstitutions.FullPath)"
SubstitutionsFile="%(ConfigFilesWithSubstitutions.FullPath)$(SubstitutionFileExtension)"
ContentRoot="/configuration"
SubstitutionsRoot="/configuration/substitutions/$(TargetEnvironment)"/>
</Target>
Note that config files are read-only during the build, I make sure to set them writeable before running this task. I actually have another custom MSBuild task that runs before XmlMassUpdate that handles common settings throughout all of the config files such as connection strings. That task makes the config files writeable. I also don't check modified config files back to the source control. They're (appropriate config file for the deployment target) included in the installer.

Categories