Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 生成Xml序列化程序集作为生成的一部分_C#_Xml_Xml Serialization - Fatal编程技术网

C# 生成Xml序列化程序集作为生成的一部分

C# 生成Xml序列化程序集作为生成的一部分,c#,xml,xml-serialization,C#,Xml,Xml Serialization,此代码生成FileNotFoundException,但最终运行时不会出现问题: void ReadXml() { XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); //... } 例外情况如下: mscorlib.dll中发生“System.IO.FileNotFoundException”类型的第一次意外异常 其他信息:无法加载文件或程序集“MyAssembly.XmlSerializers,Ve

此代码生成FileNotFoundException,但最终运行时不会出现问题:

void ReadXml()
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    //...
}
例外情况如下:


mscorlib.dll中发生“System.IO.FileNotFoundException”类型的第一次意外异常

其他信息:无法加载文件或程序集“MyAssembly.XmlSerializers,Version=1.4.3190.15950,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件


如果找不到序列化程序集,框架似乎会自动生成该程序集。我可以使用sgen.exe手动生成该程序集,从而缓解异常情况

如何让visual studio自动生成XML序列化程序集?



更新:Generate Serialization Assembly:On设置似乎没有任何作用。

查看解决方案的属性。在底部的build选项卡上有一个名为“Generate Serialization assembly”的下拉列表,这是我通过修改.CSPROJ文件中的MSBUILD脚本来实现的:

首先,将.CSPROJ文件作为文件而不是项目打开。滚动到文件底部,直到在项目标记关闭之前找到注释掉的代码:

<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->

现在,我们只需插入我们自己的后构建目标来删除任何现有的XmlSerializer,然后生成我们自己的XmlSerializer,如下所示:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
   <!-- Delete the file because I can't figure out how to force the SGen task. -->
   <Delete
     Files="$(TargetDir)$(TargetName).XmlSerializers.dll"
     ContinueOnError="true" />
   <SGen
     BuildAssemblyName="$(TargetFileName)"
     BuildAssemblyPath="$(OutputPath)"
     References="@(ReferencePath)"
     ShouldGenerateSerializer="true"
     UseProxyTypes="false"
     KeyContainer="$(KeyContainerName)"
     KeyFile="$(KeyOriginatorFile)"
     DelaySign="$(DelaySign)"
     ToolPath="$(TargetFrameworkSDKToolsDirectory)"
     Platform="$(Platform)">
      <Output
       TaskParameter="SerializationAssembly"
       ItemName="SerializationAssembly" />
   </SGen>
</Target>


这对我很有用。

这个问题的其他答案已经提到了项目属性->构建->生成序列化程序集设置,但默认情况下,只有在项目中存在“XML Web服务代理类型”时,才会生成程序集

了解Visual Studio确切行为的最佳方法是检查C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727**Microsoft.Common.targets**文件中的GenerateSerializationAssemblys目标

您可以从Visual Studio的“输出”窗口检查此生成任务的结果,并从“显示从输出”下拉框中选择“生成”。你应该看到一些类似的东西

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\sgen.exe/assembly:D:\Temp\LibraryA\obj\Debug\LibraryA.dll/proxytypes/参考:/编译器:/delaysign- LibraryA->D:\Temp\LibraryA\bin\Debug\LibraryA.dll

这里的关键点是/proxytypes开关。您可以阅读关于的各种开关

如果熟悉MSBuild,可以自定义GenerateSerializationAssemblys目标,以便SGen任务的属性为UseProxyTypes=“false”,而不是true,但 然后,您需要承担定制VisualStudio/MSBuild系统的所有相关责任。或者,您可以扩展构建过程,在不使用/proxytypes开关的情况下手动调用SGen


如果您阅读了SGen的文档,他们很清楚Microsoft希望限制此功能的使用。考虑到这个话题的喧嚣程度,很明显微软在记录VisualStudio体验方面做得并不好。这个问题甚至有一个条目,但响应不是很好。

如果以前一切正常后,其他人突然遇到这个问题:对我来说,这与“选项”菜单(选项->调试)中未选中“仅启用我的代码(仅管理)”复选框有关(安装.NET Reflector后自动关闭)

编辑:
当然,也就是说,这个异常以前发生过,但是当“仅启用我的代码”处于禁用状态时,调试助手(如果已启用),将在抛出时在此点停止。

正如Martin在中所解释的,通过项目属性启用序列化程序集的生成是不够的,因为SGen任务正在将
/proxytypes
开关添加到SGen.exe命令行

Microsoft有一个允许您禁用
/proxytypes
开关并使SGen任务生成序列化程序集,即使程序集中没有代理类型

Sgenuseproxitypes

一个布尔值,指示代理类型是否为 应该由SGen.exe生成。SGen目标使用此属性 设置UseProxyTypes标志。此属性默认为true,并且 没有可更改此的UI。若要为生成序列化程序集 非webservice类型,将此属性添加到项目文件并设置它 在导入Microsoft.Common.Targets或 C#/VB.targets

如文档所示,您必须手动修改项目文件,但您可以将
SGenUseProxyTypes
属性添加到配置中以启用生成。您的项目文件配置最终将显示如下内容:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <!-- Snip... -->
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <SGenUseProxyTypes>false</SGenUseProxyTypes>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <!-- Snip... -->
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <SGenUseProxyTypes>false</SGenUseProxyTypes>
  </PropertyGroup>

在…上
假的
在…上
假的

创建一个新的sgen任务定义打破了僵局。只需设置所需的变量即可使任务按预期工作。无论如何,microsoft文档缺少一些重要信息

预生成序列化程序集的步骤 (零件来自)

  • 在Visual Studio 2010中的解决方案资源管理器中,右键单击要为其生成序列化程序集的项目,然后单击卸载项目
  • 在解决方案资源管理器中,右键单击要为其生成序列化程序集的项目,然后单击Edit.csproj
  • 在.csproj文件中,在
    v?
    元素之后添加以下元素:

    false
    $(平台)

  • 在.csproj文件中,在每个平台配置中

    e、 g.

    添加follo
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    
    <Target
        Name="GenerateSerializationAssemblies"
        Condition="'$(_SGenGenerateSerializationAssembliesConfig)' == 'On' or ('@(WebReferenceUrl)'!='' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto')"
        DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
        Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
        Outputs="$(IntermediateOutputPath)$(_SGenDllName)">
    
        <SGen
            BuildAssemblyName="$(TargetFileName)"
            BuildAssemblyPath="$(IntermediateOutputPath)"
            References="@(ReferencePath)"
            ShouldGenerateSerializer="$(SGenShouldGenerateSerializer)"
            UseProxyTypes="$(SGenUseProxyTypes)"
            KeyContainer="$(KeyContainerName)"
            KeyFile="$(KeyOriginatorFile)"
            DelaySign="$(DelaySign)"
            ToolPath="$(SGenToolPath)"
            SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
            EnvironmentVariables="$(SGenEnvironment)"
            SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)"
            Platform="$(SGenPlatformTarget)"
            Types="$(SGenSerializationTypes)">
                <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/>
        </SGen>
    </Target>
    
    <!-- Check the platform target value and if present use that for a correct *.XmlSerializer.dll platform setup (default is MSIL)-->
    <PropertyGroup Condition=" '$(PlatformTarget)'=='' ">
      <SGenPlatform>$(Platform)</SGenPlatform>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(PlatformTarget)'!='' ">
      <SGenPlatform>$(PlatformTarget)</SGenPlatform>
    </PropertyGroup>
    
    <!-- Delete the file because I can't figure out how to force the SGen task. -->
    <Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" />
    <SGen
      BuildAssemblyName="$(TargetFileName)"
      BuildAssemblyPath="$(OutputPath)"
      References="@(ReferencePath)"
      ShouldGenerateSerializer="true"
      UseProxyTypes="false"
      KeyContainer="$(KeyContainerName)"
      KeyFile="$(KeyOriginatorFile)"
      DelaySign="$(DelaySign)"
      ToolPath="$(SGenToolPath)"
      SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
      EnvironmentVariables="$(SGenEnvironment)"
      Platform="$(SGenPlatform)">
      <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
    </SGen>
    
    "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" "$(TargetPath)" /force