Почему я не могу передать этот объект в качестве аргумента?

Фон:

Написание клиента, использующего веб-сервис, на C# с использованием.NET 4.0. Прокси-класс включает в себя объект типа запись, который заполняется из ответа SOAP от веб-службы.

Ситуация:

API включает в себя две функции, findRecords а также getRecords, Обе функции загружают фактическую запись, с той разницей, что findRecords имеет тип void и предоставляет запись через аргумент out, тогда как getRecords имеет тип записи и поэтому возвращает запись.

Проблема:

После выполнения звонка findRecordsЯ могу получить доступ к членам объекта записи (например, recordID, recordTitleи т. д.) для использования в других аргументах функции. Однако, если я пытаюсь передать сам объект записи в качестве аргумента, я получаю ArgumentNullException, Единственный способ в настоящее время передать запись в качестве аргумента - это использовать запись, возвращенную из getRecords функция. Недостаток этого подхода состоит в том, что он удваивает количество вызовов API, которые мне нужно сделать, что замедляет работу как моего клиента, так и веб-службы.

Вопрос:

Почему он так себя ведет, и есть ли что-то, что я могу сделать, чтобы иметь возможность передать объект записи из findRecords в качестве аргумента?

Код:

Это определение функции findRecords:

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://localhost:8080/findRecords", RequestNamespace="http://www.<redacted>.com/ws/schemas", ResponseNamespace="http://www.<redacted>.com/ws/schemas", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public void findRecords([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] string username, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] filter filter, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="integer")] string offset, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="integer")] string count, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] out System.Nullable<int> numResults, [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] [System.Xml.Serialization.XmlIgnoreAttribute()] out bool numResultsSpecified, [System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] [System.Xml.Serialization.XmlArrayItemAttribute("list", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)] out record[] results) {
        object[] results1 = this.Invoke("findRecords", new object[] {
                    username,
                    filter,
                    offset,
                    count});
        numResults = ((System.Nullable<int>)(results1[0]));
        numResultsSpecified = ((bool)(results1[1]));
        results = ((record[])(results1[2]));
    }

Определение функции getRecords:

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://localhost:8080/getRecords", RequestNamespace="http://www.<redacted>.com/ws/schemas", ResponseNamespace="http://www.<redacted>.com/ws/schemas", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    [return: System.Xml.Serialization.XmlArrayAttribute("records", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)]
    [return: System.Xml.Serialization.XmlArrayItemAttribute("list", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
    public record[] getRecords([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] string username, [System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] [System.Xml.Serialization.XmlArrayItemAttribute("list", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="integer", IsNullable=false)] string[] stiIds) {
        object[] results = this.Invoke("getRecords", new object[] {
                    username,
                    recordIds});
        return ((record[])(results[0]));
    }

И что я пытаюсь сделать с этим:

        // Objects to use for the findRecords call
        int? numResults;
        bool numResultsSpecified;
        record[] records;

        // Object for handling and saving the XML
        XRecord r;

                try
                {
                    ws.findRecords(usernames[uname_Index], GetFilter(), offset.ToString(), count.ToString(),
                        out numResults, out numResultsSpecified, out returnRecords);

                    for (int i = 0; i < returnRecords.Length; i++)
                    {
                        count--;
                        r = GrabRecord(returnRecords[i]);
                        r.record.Save(@".\Records\" + r.id + "_" + r.date2 + ".xml");
                    }
                }

......

    private static XRecord GrabRecord(record _record)
    {
        XNamespace nameSpace = "http://www.<redacted>.com/ws/schemas";

        XDocument r =
            new XDocument(
                new XElement(nameSpace + "getRecordsResponse",
                    new XAttribute(XNamespace.Xmlns + "ns1", nameSpace),
                    new XElement("list",
                        new XElement("ID", _record.id),
                        new XElement("title", _record.title),
            ...............
                        new XElement("comments", _record.comments),
                        new XElement("category", _record.category),
                        _record.modifiedDateSpecified ? new XElement("modifiedDate", _record.modifiedDate) : null,
                        new XElement("attachments", from a in _record.attachments
                                                    select new XElement("list",
                                                        new XElement("id", a.id),
                                                        new XElement("filePath", a.filePath),
                                                        new XElement("type", a.type))));

        XRecord xr = new XRecord();
        xr.record = r;
        xr.id = _record.id;
        xr.date2 = ConvertToDateString(_record.modifiedDate);

        return xr;
    }

Вот информация об исключениях и трассировке стека. Упомянутые номера строк относятся к строкам "XDocument r = " и "r = GrabRecord(...)" в соответствующих функциях.

Unexpected error: Value cannot be null. Parameter name: source at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable1 источник, Func2 selector) at WsClient.WSAPI.GrabRecord(record _record) in C:\...WSAPI.cs:line 1235 at WsClient.WSAPI.PersistentUpdate(String[] usernames) in C:\...WSAPI.cs:line 354

Как и предполагал rsbarro, я отредактировал код в функции GrabRecord, чтобы исключить возможность того, что ConvertToDateString() могла вызывать проблему, если ModifiedDate был нулевым. Это не устранило проблему, и сообщение об исключении не изменилось.

1 ответ

Решение

Глядя на код, я предполагаю, что вы получаете ArgumentNullException в призыве к GrabRecord, Существует потенциальная проблема в GrabRecord это может вызвать ArgumentNullException, Когда вы строите свой XDocument храниться в r, ты проверяешь _record.modifiedDateSpecified перед созданием modifiedDateXElement, Однако ближе к концу метода следующий оператор выполняется без какой-либо пустой проверки перед ним:

xr.date2 = ConvertToDateString(_record.modifiedDate);

Возможно, что _record.modifiedDate является нулевым, и это ConvertToDateString стартует ArgumentNullException, Конечно, возможно, что ConvertToDateString обрабатывает нулевые значения без ошибок, но не видя этого кода, сложно сказать.

Если проблема не в том, что я предложил, не могли бы вы обновить вопрос с более подробной информацией об исключении, а также добавить трассировку стека?

Надеюсь, это поможет.

Другие вопросы по тегам