• WCF置于Mono下遇到的一些问题


      之前同事将Remoting服务程序置于Mono下调用成功,这两天我尝试将WCF寄宿程序移植到Mono中,遇到些问题,跟大家分享下!

      参考资料:

      移植Windows自宿主WCF服务到Linux/Mono2.8

     

         完成WPF及寄宿程序的编写(在这就不详细描述了),直接运行:

      

      在IE中输入baseAddress地址,能够正常访问,使用MoMA(MoMA Download)检测该程序也顺利通过,原本以为这样直接放到Mono中运行就可以了,不料还是遇到不少麻烦。:

        

     

      首先一上来就直接在linux下使用Mono(Mono Download)启动服务程序,却被告知:

      

     

      我在我Window平台下尝试使用的Mono启动该程序,也得到同样的信息。

      经过一番搜索和尝试,确定是Mono版本导致的问题,最初在下载页面习惯性的就下载了——Long-term Supported Version: 2.6.7 (Release Notes),其实Mono好像是从Version2.8~才开始支持.Net 4的,所以下载——Latest Stable Version: 2.10.2 (Release Notes)安装后问题解决。

      

      虽然同事强调说那台Linux上是取的最新版本的源码编译的,但是因为只能看到编译的版本号,不知道其对应的Release版本到底是多少,我想应该也是同样的问题。

     

      但是从IE浏览服务时又出现了问题,得到的错误信息如下:

    错误信息
      <?xml version="1.0" encoding="utf-8" ?> 
    -
    <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
    -
    <Code>
    <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:InternalServiceFault</Value>
    </Code>
    -
    <Reason>
    <Text xml:lang="en-US">The server was unable to process the request due to an internal error. The server may be able to return exception details (it depends on the server settings).</Text>
    </Reason>
    </Fault>

      光这么看也看不出个所以然来,我们通过设置IncludeExceptionDetailInFaults来查看进一步的错误信息。

      可以在配置文件中添加以下信息来打开这一开关

    includeExceptionDetailInFaults
        <behaviors>
    <serviceBehaviors>
    <behavior>
    <serviceMetadata httpGetEnabled="True"/>
    <serviceDebug includeExceptionDetailInFaults="True"/>
    </behavior>
    </serviceBehaviors>
    </behaviors>

      也可以通过在服务类上添加熟悉标记来设置开关

        [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class ModelService : IModelService
    {
    }

      

      再次执行之前的操作,可以的到如下信息:

    详细错误
      <?xml version="1.0" encoding="utf-8" ?> 
    -
    <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
    -
    <Code>
    <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:InternalServiceFault</Value>
    </Code>
    -
    <Reason>
    <Text xml:lang="en-US">XmlSchema error: Named item http://schemas.microsoft.com/2003/10/Serialization/:anyType was already contained in the schema object table. Consider setting MONO_STRICT_MS_COMPLIANT to 'yes' to mimic MS implementation. Related schema item SourceUri: , Line 3, Position 3.</Text>
    </Reason>
    -
    <Detail>
    -
    <ExceptionDetail xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel">
    <HelpLink i:nil="true" />
    <InnerException i:nil="true" />
    <Message>XmlSchema error: Named item http://schemas.microsoft.com/2003/10/Serialization/:anyType was already contained in the schema object table. Consider setting MONO_STRICT_MS_COMPLIANT to 'yes' to mimic MS implementation. Related schema item SourceUri: , Line 3, Position 3.</Message>
    <StackTrace>at System.Xml.Schema.ValidationHandler.RaiseValidationEvent (System.Xml.Schema.ValidationEventHandler handle, System.Exception innerException, System.String message, System.Xml.Schema.XmlSchemaObject xsobj, System.Object sender, System.String sourceUri, XmlSeverityType severity) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchemaObject.error (System.Xml.Schema.ValidationEventHandler handle, System.String message, System.Exception innerException, System.Xml.Schema.XmlSchemaObject xsobj, System.Object sender) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchemaObject.error (System.Xml.Schema.ValidationEventHandler handle, System.String message) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchemaUtil.AddToTable (System.Xml.Schema.XmlSchemaObjectTable table, System.Xml.Schema.XmlSchemaObject obj, System.Xml.XmlQualifiedName qname, System.Xml.Schema.ValidationEventHandler h) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchema.DoCompile (System.Xml.Schema.ValidationEventHandler handler, System.Collections.Hashtable handledUris, System.Xml.Schema.XmlSchemaSet col, System.Xml.XmlResolver resolver) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchema.CompileSubset (System.Xml.Schema.ValidationEventHandler handler, System.Xml.Schema.XmlSchemaSet col, System.Xml.XmlResolver resolver, System.Collections.Hashtable handledUris) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchema.CompileSubset (System.Xml.Schema.ValidationEventHandler handler, System.Xml.Schema.XmlSchemaSet col, System.Xml.XmlResolver resolver) [0x00000] in <filename unknown>:0 at System.Xml.Schema.XmlSchemaSet.Reprocess (System.Xml.Schema.XmlSchema schema) [0x00000] in <filename unknown>:0 at System.Runtime.Serialization.XsdDataContractExporter.Export (System.Type type) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.WsdlExporter.GetSchemaElementForPart (System.ServiceModel.Description.MessagePartDescription part, System.Xml.Schema.XmlSchema schema) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.WsdlExporter.ExportParameters (System.ServiceModel.Description.MessageBodyDescription msgbody, System.String name, System.String ns) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.WsdlExporter.ExportMessageBodyDescription (System.ServiceModel.Description.MessageBodyDescription msgbody, System.String name, System.String ns) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.WsdlExporter.ExportContractInternal (System.ServiceModel.Description.ContractDescription contract, Boolean rejectDuplicate) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.WsdlExporter.ExportEndpoint (System.ServiceModel.Description.ServiceEndpoint endpoint, Boolean rejectDuplicate) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.WsdlExporter.ExportEndpoints (IEnumerable`1 endpoints, System.Xml.XmlQualifiedName name) [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.ServiceMetadataExtension.get_Metadata () [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.HttpGetWsdl.GetMetadata () [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.HttpGetWsdl.EnsureMetadata () [0x00000] in <filename unknown>:0 at System.ServiceModel.Description.HttpGetWsdl.Get (System.ServiceModel.Channels.Message req) [0x00000] in <filename unknown>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0</StackTrace>
    <Type>System.Xml.Schema.XmlSchemaException</Type>
    </ExceptionDetail>
    </Detail>
    </Fault>

      我在“anyType was already contained in the schema object table. Consider setting MONO_STRICT_MS_COMPLIANT to 'yes' to mimic MS implementation. Related schema item SourceUri”这句话上纠缠了很久,试图在网上找到相应的信息,但收获不大,一直弄不明白“MONO_STRICT_MS_COMPLIANT ”是个什么东东,需要怎么处理,应该在什么地方去设置?

      甚至尝试用MonoDevelop(MonoDevelop  Download)来编译项目也解决不了问题(不过也好,对MonoDevelop也有了一些了解)。

      随后索性死马当活马医了,因为看到XmlSchemaUtil.cs有这样一句代码:

    internal static readonly bool StrictMsCompliant = Environment.GetEnvironmentVariable ("MONO_STRICT_MS_COMPLIANT") == "yes";

      就尝试在自己的代码中使用类似的方法,通过判断发现得到的“MONO_STRICT_MS_COMPLIANT”的值的确不为Yes。同时发现Environment不仅有Get方法也有对应的Set方法,试着做了如下处理:

    Environment
           if (Environment.GetEnvironmentVariable("MONO_STRICT_MS_COMPLIANT") == "yes")
    Console.WriteLine(
    "当前环境变量“MONO_STRICT_MS_COMPLIANT”值为Yes!");
    else
    Console.WriteLine(
    "当前环境变量“MONO_STRICT_MS_COMPLIANT”值为No!");


    Environment.SetEnvironmentVariable(
    "MONO_STRICT_MS_COMPLIANT", "yes");
    Console.WriteLine(
    "设置环境变量“MONO_STRICT_MS_COMPLIANT”为Yes!");

    if (Environment.GetEnvironmentVariable("MONO_STRICT_MS_COMPLIANT") == "yes")
    Console.WriteLine(
    "当前环境变量“MONO_STRICT_MS_COMPLIANT”值为Yes!");
    else
    Console.WriteLine(
    "当前环境变量“MONO_STRICT_MS_COMPLIANT”值为No!");

      最后输出如下

      

      奇怪的是每次程序启动得到的值都为"No”,看来这种方式对该变量的改变只是一时的。

      最后程序添加了这样一段代码来设置这一变量

                if (Environment.GetEnvironmentVariable("MONO_STRICT_MS_COMPLIANT") != "yes")
    {
    Environment.SetEnvironmentVariable(
    "MONO_STRICT_MS_COMPLIANT", "yes");
    Console.WriteLine(
    "设置环境变量“MONO_STRICT_MS_COMPLIANT”为Yes!");
    }

      现在启动服务后,再用IE访问就能得到如下信息了,Mono下访问得到的界面跟之前的不太一样,但实质都是一样的:

      

        

  • 相关阅读:
    一个6亿的表a,一个3亿的表b,通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录
    MySQL复制表的方式以及原理和流程
    Python里面如何拷贝一个对象
    python中*args,**kwargs
    Python删除list里面的重复元素的俩种方法
    Python是如何进行内存管理
    python中lambda函数
    python中filter(),reduce()函数
    python中map()函数用法
    重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell
  • 原文地址:https://www.cnblogs.com/wdysunflower/p/2113112.html
Copyright © 2020-2023  润新知