Почему я не могу передать этот объект в качестве аргумента?
Фон:
Написание клиента, использующего веб-сервис, на 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](IEnumerable
1 источник, 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
перед созданием modifiedDate
XElement
, Однако ближе к концу метода следующий оператор выполняется без какой-либо пустой проверки перед ним:
xr.date2 = ConvertToDateString(_record.modifiedDate);
Возможно, что _record.modifiedDate
является нулевым, и это ConvertToDateString
стартует ArgumentNullException
, Конечно, возможно, что ConvertToDateString
обрабатывает нулевые значения без ошибок, но не видя этого кода, сложно сказать.
Если проблема не в том, что я предложил, не могли бы вы обновить вопрос с более подробной информацией об исключении, а также добавить трассировку стека?
Надеюсь, это поможет.