Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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
Wcf OData4j例外情况-“;奇数字符;及;键串“的无效值字符串部分”;_Wcf_Json_Datetime_Illegalargumentexception_Odata4j - Fatal编程技术网

Wcf OData4j例外情况-“;奇数字符;及;键串“的无效值字符串部分”;

Wcf OData4j例外情况-“;奇数字符;及;键串“的无效值字符串部分”;,wcf,json,datetime,illegalargumentexception,odata4j,Wcf,Json,Datetime,Illegalargumentexception,Odata4j,编辑: 解决方案是创建一个镜像相关表的视图,并将日期转换为varchar,然后使用匹配的排序规则将其转换回日期 编辑结束 有人能告诉我为什么OData4j可以从我的一个WCF数据服务服务器读取日期时间值,但在从另一个WCF数据服务读取格式完全相同的日期时间类型时遇到非法参数异常(作为键字符串的一部分的错误值字符串) java.lang.IllegalArgumentException:错误的valueString [datetime'2012-01-24T14%3A57%3A22.243']作为

编辑:


解决方案是创建一个镜像相关表的视图,并将日期转换为varchar,然后使用匹配的排序规则将其转换回日期

编辑结束

有人能告诉我为什么OData4j可以从我的一个WCF数据服务服务器读取日期时间值,但在从另一个WCF数据服务读取格式完全相同的日期时间类型时遇到非法参数异常(作为键字符串的一部分的错误值字符串)

java.lang.IllegalArgumentException:错误的valueString [datetime'2012-01-24T14%3A57%3A22.243']作为键串的一部分

另一个问题是,当我从OData4j读取datetime类型没有问题的服务请求JSON响应时,我得到了另一个非法参数异常,错误消息是-奇数个字符

java.lang.IllegalArgumentException: org.odata4j.repack.org.apache.commons.codec.DecoderException:奇数 字符数

因为WCF数据服务不能有多个源,所以我用每个源自己的实体数据模型源(来自现有数据库)创建了两个项目。就像我上面提到的,我犯了这些恼人的错误

总之

示例1:错误的valueString作为keyString的一部分-在读取datetime时。
FormatType.JSON也会发生这种情况

ODataConsumer customerInfoServices = ODataConsumer
                                     .newBuilder("http://10.0.2.2:41664/CustomerInfoWCFDataServices.svc/")
                                     .setFormatType(FormatType.ATOM)
                                     .build();

customer = customerInfoServices
           .getEntities("Customers")
           .select("name, id")
           .filter("id eq " + 5)
           .execute()
           .firstOrNull();
示例2:奇数个字符。只有
FormatType.JSON
发生,读取日期时间没有问题

ODataConsumer businessServices = ODataConsumer
                                 .newBuilder("http://10.0.2.2:35932/BusinessWCFDataServices.svc/")
                                 .setFormatType(FormatType.JSON)
                                 .build();

Enumerable<?> ordrer = businessServices
                       .getEntities("Orders")
                       .filter("custId eq " + customer.getProperty("id").getValue())
                       .execute();
ODataConsumer businessServices=ODataConsumer
.newBuilder(“http://10.0.2.2:35932/BusinessWCFDataServices.svc/")
.setFormatType(FormatType.JSON)
.build();
可枚举ordrer=businessServices
.getEntities(“订单”)
.filter(“custId eq”+customer.getProperty(“id”).getValue()
.execute();
我想要的是接收JSON响应(ATOM对于android来说仍然过于臃肿),并且读取datetime属性没有问题


没有人能帮助我

我一直在努力在谷歌上找到解决方案,但运气不佳


没有日期时间问题的数据库的排序规则是“Danish_Norwegian_CI_AS”,而有读取错误的数据库的排序规则是“SQL_Danish_Pref_CP1_CI_AS”。我不知道这是否有任何意义,但我怀疑这与此有关。

解决方案是创建一个视图,镜像相关表并将日期转换为varchar,然后使用匹配的排序规则将其转换回日期。:-)

我今天遇到了这个问题,在谷歌搜索和查看了大约三个小时的代码后,我设法弄明白了到底发生了什么。以下是我的设置/情况以及我的发现:

设置
  • (OData服务)Windows Server 2012上的Microsoft IIS 8.0使用 默认应用程序池
  • (OData生产商)微软WCF中间层 使用实体框架和Web数据服务
  • (小田消费者) Android客户端使用OData4J v0.8快照
  • 问题 在我的中间层(ODataProducer)中,我使用EntityFramework5.0定义一个带有
    Edm.DateTime
    列的简单表。我的
    MessageTable.edmx
    文件生成一个简单的表:

    CREATE TABLE [dbo].[MessageTable] (
        [Id] int IDENTITY(1,1) NOT NULL,
        [Date1] datetime NULL
    );
    
    在中间层的WCF数据服务(OData Producer)中,我从Android客户端应用程序截取OData帖子。我使用一些C代码在中间层手动设置Date1列:

    注意,我使用了C#的静态属性。MSDN文档说明
    DateTime.Now

    获取一个DateTime对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间

    要认识到的关键是,本地时间意味着C#date时间结构现在包含本地时区信息

    因此,在中间层代码完成后,WCF服务将OData POST插入到我的表中。然后,Microsoft将
    [Date1]
    列发送回我的Android客户端(OData消费者)。Microsoft似乎将该日期编码为OData DateTimeOffset,因为它包含本地时区信息。即as
    2013-08-26T17:30:00.0000000-7:00

    代码 在OData4j中,有一个包
    org.odata.internal
    ,用于解析odata日期时间字符串。在版本0.6中,我在第40-44行找到了关于用于解析日期时间字符串的
    DATETIME_模式
    regex模式的以下注释:

    40   // Since not everybody seems to adhere to the spec, we are trying to be
    41   // tolerant against different formats
    42   // spec says:
    43   // Edm.DateTime: yyyy-mm-ddThh:mm[:ss[.fffffff]]
    44   // Edm.DateTimeOffset: yyyy-mm-ddThh:mm[:ss[.fffffff]](('+'|'-')hh':'mm)|'Z'
    45   private static final Pattern DATETIME_PATTERN =
    46       Pattern.compile("(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})(:\\d{2})?(\\.\\d{1,7})?((?:(?:\\+|\\-)\\d{2}:\\d{2})|Z)?");
    47 
    48
    
    在OData4j v0.7中,
    DATETIME\u模式
    已成为
    DATETIME\u XML\u模式

    40 
    41   private static final Pattern DATETIME_XML_PATTERN = Pattern.compile("" +
    42       "^" +
    43       "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})" + // group 1 (datetime)
    44       "(:\\d{2})?" + // group 2 (seconds)
    45       "(\\.\\d{1,7})?" + // group 3 (nanoseconds)
    46       "(Z)?" + // group 4 (tz, ignored - handles bad services)
    47       "$");
    48 
    49   private static final Pattern DATETIMEOFFSET_XML_PATTERN = Pattern.compile("" +
    50       "^" +
    51       "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})" + // group 1 (datetime)
    52       "(\\.\\d{1,7})?" + // group 2 (nanoSeconds)
    53       "(((\\+|-)\\d{2}:\\d{2})|(Z))" + // group 3 (offset) / group 6 (utc)
    54       "$");
    
    41   private static final Pattern DATETIME_XML_PATTERN = Pattern.compile("" +
    42       "^" +
    43       "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})" + // group 1 (datetime)
    44       "(:\\d{2})?" + // group 2 (seconds)
    45       "(\\.\\d{1,7})?" + // group 3 (nanoseconds)
    46       "((?:(?:\\+|\\-)\\d{2}:\\d{2})|Z)?" + 
    47       "$");
    
    我认为第46行的评论解释了一切:

    …//第4组(tz,忽略-处理不良服务)

    我将此理解为“任何时区信息都将被忽略-这将处理发送时区信息的坏服务(如Microsoft)”

    在我看来,OData4j的作者们决定坚持自己的观点,只接受正确的
    Edm.DateTime
    字符串格式

    解决方案 如果您可以访问OData生产商代码,则修复非常简单:

        private static void ProcessMessage(ODataMessage message)
        {
            .
            .
            .
            conn.Open();
            cmd.ExecuteNonQuery();
            int returnCode = (int)cmd.Parameters["@result"].Value;
            if (returnCode == 0)
            {
                message.Processed = true;
                message.Date1 = DateTime.UtcNow;
            }
            .
            .
            .
        }
    
    改为使用属性。MSDN文档说明:

    获取一个DateTime对象,该对象设置为此计算机上的当前日期和时间,表示为协调世界时(UTC)

    如果您没有访问odataproducer的权限,我能看到的唯一解决方案就是更改OData4j代码。更改
    DATETIME\u XML\u模式的正则表达式模式

    40 
    41   private static final Pattern DATETIME_XML_PATTERN = Pattern.compile("" +
    42       "^" +
    43       "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})" + // group 1 (datetime)
    44       "(:\\d{2})?" + // group 2 (seconds)
    45       "(\\.\\d{1,7})?" + // group 3 (nanoseconds)
    46       "(Z)?" + // group 4 (tz, ignored - handles bad services)
    47       "$");
    48 
    49   private static final Pattern DATETIMEOFFSET_XML_PATTERN = Pattern.compile("" +
    50       "^" +
    51       "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})" + // group 1 (datetime)
    52       "(\\.\\d{1,7})?" + // group 2 (nanoSeconds)
    53       "(((\\+|-)\\d{2}:\\d{2})|(Z))" + // group 3 (offset) / group 6 (utc)
    54       "$");
    
    41   private static final Pattern DATETIME_XML_PATTERN = Pattern.compile("" +
    42       "^" +
    43       "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2})" + // group 1 (datetime)
    44       "(:\\d{2})?" + // group 2 (seconds)
    45       "(\\.\\d{1,7})?" + // group 3 (nanoseconds)
    46       "((?:(?:\\+|\\-)\\d{2}:\\d{2})|Z)?" + 
    47       "$");
    
    结论 我认为这实际上是微软的一个错误。我确信他们发送
    Edm.DateTimeOffset
    有一些复杂的理由,但我的
    MessageTable.edmx
    文件将
    [Date1]
    指定为
    Edm.DateTime
    ,因此我认为