Requirement_Update using only some properties (SOAP)

Thursday, April 17, 2014
Avatar
Hello,

I was wondering if it was possible to update a requirement using only a subset of the available properties?

For example, when I want to update only the description of a requirement, I thought using the following SOAP envelope would work.
<soap:Envelope xmlns:a="http://schemas.datacontract.org/2004/07/Inflectra.SpiraTest.Web.Services.v4_0.DataObjects" xmlns:api="https://www.inflectra.com/SpiraTest/Services/v4.0/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <api:Requirement_Update>
            <api:remoteRequirement>
                <a:Description>My new description</a:Description>
                <a:RequirementId>3351</a:RequirementId>
            </api:remoteRequirement>
        </api:Requirement_Update>
    </soap:Body>
</soap:Envelope>
Unfortunately it doesn't. It seems the server wants me to send all the nullable properties set to nil. Here is the complete response I get (sorry, in French)
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode><faultstring xml:lang="en-CA">Un objet qui autorise la valeur Null doit posséder une valeur.</faultstring><detail><ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><HelpLink i:nil="true"/><InnerException i:nil="true"/><Message>Un objet qui autorise la valeur Null doit posséder une valeur.</Message><StackTrace>   à System.Nullable`1.get_Value()&#xD;
   à Inflectra.SpiraTest.Web.Services.v4_0.ImportExport.Requirement_Update(RemoteRequirement remoteRequirement)&#xD;
   à SyncInvokeRequirement_Update(Object , Object[] , Object[] )&#xD;
   à System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)&#xD;
   à System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)&#xD;
   à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)&#xD;
   à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)&#xD;
   à System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.InvalidOperationException</Type></ExceptionDetail></detail></s:Fault></s:Body></s:Envelope>

The main message in English would probably be: Nullable object must have a value.

 Is there no way around this? It would be very convenient if the server could be a little bit smarter and update only the properties which I care about, and leave the other ones unmodified. This is also the way that Requirement_Create2 works.

Thanks in advance for any help / tips!
2 Replies
Monday, April 21, 2014
Avatar
re: maco Thursday, April 17, 2014

Hi Maxim

For concurrency reasons you need to do the following:

  1. Do a Requirement_Retrieve(requirementId) first to get the existing RemoteRequirement object
  2. Update the fields you want to change
  3. Then use Requirement_Update(remoteRequirement) to send the updated data back.

Regards

Adam

Saturday, May 10, 2014
Avatar
re: inflectra.david Monday, April 21, 2014

Hello Adam, and thank you for your reply.

As per your recommendations I retrieved a complete copy of the remoteRequirement by using the Requirement_Retrieve command. I then parsed the returned XML to get the desired single requirement element, modified it and tried to update it on the server using Requirement_Update.

It worked, but only after I adapted the following:

  1. The XML namespace (xmlns) of the returned requirement object is set to a="http://schemas.datacontract.org/2004/07/Inflectra.SpiraTest.Web.Services.v4_0.DataObjects". For some reasons, I needed to set it instead to "https://www.inflectra.com/SpiraTest/Services/v4.0/" for the server to accept it (else I would get "The object reference is not set to an instance of an object").

  2. The element node's name for the requirement object was "RemoteRequirement". However I would also get "The object reference is not set to an instance of an object" before I changed the element node's name to "remoteRequirement".

Here is an excerpt of the original SOAP response containing the requirement of interest, as returned by the server. Notice the namespace of the RemoteRequirement node and also the capitalized R in its name.

<?xml version="1.0" encoding="UTF-8"?>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

<s:Body>

<Requirement_RetrieveResponse xmlns="https://www.inflectra.com/SpiraTest/Services/v4.0/">

<Requirement_RetrieveResult xmlns:a="http://schemas.datacontract.org/2004/07/Inflectra.SpiraTest.Web.Services.v4_0.DataObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

<a:RemoteRequirement>

<a:ArtifactTypeId>1</a:ArtifactTypeId>

<a:ConcurrencyDate>2014-03-26T20:09:58.233</a:ConcurrencyDate>

<a:CustomProperties>

[ . . . ]


After the changes discussed above, the functional Requirement_Update SOAP message looks like this:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.datacontract.org/2004/07/Inflectra.SpiraTest.Web.Services.v4_0.DataObjects" xmlns:api="https://www.inflectra.com/SpiraTest/Services/v4.0/">

<soap:Body>

<api:Requirement_Update>

<api:remoteRequirement>

<a:ArtifactTypeId>1</a:ArtifactTypeId>

<a:ConcurrencyDate>2014-04-22T19:01:22.323</a:ConcurrencyDate>

<a:CustomProperties>

[ . . . ]


Did I just find some issues in the SOAP-WSDL message returned by the SpiraTeam server or I am doing something wrong?

Regards,

Maxim

Spira Helps You Deliver Quality Software, Faster and With Lower Risk

And if you have any questions, please email or call us at +1 (202) 558-6885

 

Statistics
  • Started: Thursday, April 17, 2014
  • Last Reply: Saturday, May 10, 2014
  • Replies: 2
  • Views: 3376