I have a Web Service that i have created using C# and Visual Studio 2010. The definition is below.
[WebService(Namespace = "http://targetrocksoftware.org")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class GetAssessmentResults : System.Web.Services.WebService
{
SchoolTestManagerDBContainer SchoolDB = new SchoolTestManagerDBContainer();
[WebMethod]
public XmlDocument GetAssessment(int assessmentid)
{
int intid = 88;
Assessment a = SchoolDB.Assessments.SingleOrDefault(m=>m.Id == (int) intid);
if (a != null)
{
MemoryStream ms = new MemoryStream();
Test t = Test.GetTestStructure(a);
t.SerializeTest(ms);
ms.Seek(0, SeekOrigin.Begin); //reset read pointer
XmlDocument xd = new XmlDocument();
xd.Load(ms);
return xd;
}
else
return null;
}
}
it is very simple as you can see and it takes one parameter an integer which is the unique id of a table. No issues you would think. Everthing works except that when i call the web service from SSRS (either in local mode via ReportBuilder 2.0) or directly from the SSRS server, the parameter assessmentid is always 0.
The SSRS report calls the web service using the following query parameter in a dataset.
<Query xmlns="http://targetrocksoftware.org">
<ElementPath IgnoreNamespaces="True">
GetAssessmentResponse/GetAssessmentResult/Test
{
NumQuestions(integer),
nAnswered(integer),
Highest(float),
Lowest(float),
Median(float),
Mean(float),
Correct(integer),
Incorrect(integer),
KR20(float),
StandardDeviation(float),
Variance(float)
}
</ElementPath>
<SoapAction>http://targetrocksoftware.org/GetAssessment</SoapAction>
<Method Namespace="http://targetrocksoftware.org" Name="GetAssessmet">
<Parameters>
<Parameter Name="assessmentid">
<DefaultValue>88</DefaultValue>
</Parameter>
</Parameters>
</Method>
</Query>
Everyting seems to work except the assessmentid parameter is always 0. If I hard code an assessmentid that i know is in the db (in this case 88) the web service returns the correct Xml Document and the report renders perfectly.
But for the life of me i cannot get SSRS to pass the parameter correctly. I have used fiddler2 to look at the request which is copied below
POSThttp://192.168.2.10/WebServices/GetAssessmentResults.asmxHTTP/1.1
SOAPAction:http://targetrocksoftware.org/GetAssessment`
Content-Type: text/xml
Host: 192.168.2.10
Content-Length: 280
Expect: 100-continue
Connection: Keep-Alive
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAssessmet xmlns="http://targetrocksoftware.org">
<assessmentid>88</assessmentid>
</GetAssessmet>
</soap:Body>
</soap:Envelope>
`
If i use a WebService Test Tool like soapUI to send a request to the service it works (e.g. assessmentid is sest to the value passed, 88). The only thing i can see that is different is that on the request that is sent from soapUI the parameter that is passed has a namespace qualifier. Cany anyone help me please. A netmon trace is included below, that shows the difference between the two requests. My basic question is how do you get ssrs to work (e.g. include the namepace in each part of the soap request (at least that is what i think is wrong:))
- Soap: xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tar="http://targetrocksoftware.org/"
- Envelope: <soapenv:Envelope>
+ STag: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tar="http://targetrocksoftware.org/">
+ Header: <soapenv:Header>
- Body: <soapenv:Body>
+ STag: <soapenv:Body>
- Node: XmlElement:<tar:GetAssessment>
+ STag: <tar:GetAssessment>
- Element: XmlElement:<tar:assessmentid> - 88
+ STag: <tar:assessmentid>
Content: 88
+ ETag: </tar:assessmentid>
+ ETag: </tar:GetAssessment>
+ ETag: </soapenv:Body>
+ ETag: </soapenv:Envelope>- Soap: xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tar="http://targetrocksoftware.org/"
- Envelope: <soapenv:Envelope>
+ STag: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tar="http://targetrocksoftware.org/">
+ Header: <soapenv:Header>
- Body: <soapenv:Body>
+ STag: <soapenv:Body>
- Node: XmlElement:<tar:GetAssessment>
+ STag: <tar:GetAssessment>
- Element: XmlElement:<tar:assessmentid> - 88
+ STag: <tar:assessmentid>
Content: 88
+ ETag: </tar:assessmentid>
+ ETag: </tar:GetAssessment>
+ ETag: </soapenv:Body>
+ ETag: </soapenv:Envelope>
Kevin
If anyone is interested i have solved this issue. Not in a good way, but it is solved. The solution was to start fresh and recreate a new webservice with the exact same functionality. The only difference is that now i have left the service namespace as the default http://tempuri.org. I am not sure why it fixed the issue but it did. If anyone can shed some light on it that would be great
Kevin
Related
How to verify if my Soap request consists of an particular element in header and body using JSON and standalone WireMock.
I should get response1 if my request contain <a:Id>1876</a:Id> in the header else i should get response2
similarly i need to check in body also.
Below is my request XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://abc.example.com/a"
xmlns:b="http://abc.example.com/b"
xmlns:c="http://abc.example.com/c"
<soapenv:Header>
<a:abcHeaders>
<a:Id>1876</a:Id>
<a:Xid>12</a:Xid>
</a:abcHeaders>
</soapenv:Header>
<soapenv:Body>
<b:abcOpern>
<b:xyz>
<c:pqr>12</c:pqr>
</b:xyz>
</b:abcOpern>
</soapenv:Body>
</soapenv:Envelope>
In WireMock.Net you can use XPath matching. For some details see here.
trying to translate from one asmx web service to svc web service. same code, but got the following difference in responce
when using asmx:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.MyKidsSpending.com/">-2202.68</string>
when using svc:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">-2202.68</string>
where did the first line go?
Here is the fist couple of lines of the function that I am testing in the svc service....
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml)]
public string Balance(string Uid)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
I was suggested that the response was html, that is why it doesn't have
<?xml version="1.0" encoding="utf-8"?>
now I change text/html to text/xml, why doesn't still match? Suggestions? Thanks
I'm using DevExpress, XAF, and XPO for my application. I need to expose my data from a webservice.
ASP.NET Web API V2 is not compatible with XPO objects... (If you found how to... I will take it!).
The DevExpress wizard can help me to generate a WCF Web Service project, where
MyContext inherits from XpoContext
MyService inherits from XpoDataServiceV3 (and the class have an attribute : [JSONPSupportBehavior])
I would get a list of my XPO Objects, for that, I wrote the next code
[WebGet]
public IQueryable<MyType> Get()
{
return new XPQuery<MyType>(new UnitOfWork());
}
I have found various properties on WebGet attribute : RequestFormat, ResponseFormat, BodyStyle, UrlTemplate. On Format properties, I have the choise between WebMessageFormat.Json and WebMessageFormat.Xml. Logically, I type WebMessageFormat.Json.
When I go on my favorite webbrowser or fiddler, I do this request:
GET http://localhost:51555/MyService.svc/Get HTTP/1.1
User-Agent: Fiddler
Host: localhost:51555
Content-Type: application/json
But this not works... The response is :
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 24250
Content-Type: application/atom+xml;type=feed;charset=utf-8
Server: Microsoft-IIS/10.0
...
And content was wrote in XML.
We are okay, I have configure my query with format properties... :
[WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
I've found ! On your WCF service global class, wrote the following code :
HttpContext.Current.Request.Headers.Add("Accept", "application/json;");
I have a BizTalk 2013 app (not R2) that needs to send a Json document to an external vendor's RESTful api. The vendor requires three Http headers:
Content-Type: application/json
Date: in ISO8601 UTC format
Authorization: custom auth. using a constructed string that includes the above Date value run through the HMACSHA1 hash
In BizTalk, my outbound (xml) message goes to the Send Port, there is a Custom Pipeline Component that transforms to Json using JSON.Net. So far, so good. To add the headers which are unique per message, I created a WCF Behavior extension that implements IClientInspector and IEndpointBehavior. In BeforeSendRequest(), I get a reference to the HttpRequestMessageProperty for the request.
I can successfully add to the Headers Collection a ContentType header and an Authorization header. I cannot add a Date header - no errors, just no header value when examining with Fiddler.
I read somewhere that Date is a restricted header and for a workaround I could use Reflection to get around it. E.g.
MethodInfo priMethod = headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
priMethod.Invoke(headers, new[] { "Date", ISODateTimestamp });
That didn't work either. I'm really stumped with: 1. Why no Date header at all is on my request? 2. If there was one, how I could manipulate it as I need to give that is "restricted"?
I tried two different options: a WCF behavior extension:
public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
{
System.Diagnostics.Debug.Print("Entering BeforeSendRequest()");
try
{
HttpRequestMessageProperty httpRequest = null;
if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
{
httpRequest = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
}
WebHeaderCollection headers = httpRequest.Headers;
headers.Add(HttpRequestHeader.ContentType, "application/json");
headers.Add(string.Format("{0}:{1}", "Date", _taxwareHelper.ISODateTimestamp));
headers.Add("tweDate", _taxwareHelper.ISODateTimestamp);
headers.Add(HttpRequestHeader.Authorization, _taxwareHelper.AuthorizationString);
and a Custom Pipeline Component in a Send Pipeline
string httpHeaderValue =
new StringBuilder()
.Append("Content-Type: application/json")
.Append("\n")
//.Append(string.Format("Date:{0}", taxwareHelper.ISODateTimestamp))
//.Append("\n")
.Append(string.Format("Date:{0}", "Fri, 10 Jul 2015 08:12:31 GMT"))
.Append("\n")
.Append(string.Format("tweDate:{0}", taxwareHelper.ISODateTimestamp))
.Append("\n")
.Append(string.Format("Authorization:{0}", taxwareHelper.AuthorizationString))
.ToString();
pInMsg.Context.Write("HttpHeaders", "http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties", httpHeaderValue);
in either case, I can set the Content-Type, the Authorization and test date - tweDate just to test, but I can not set the actual Date header.
Yes indeed Date is a special HTTP Header that respresents the date and time at which the message originated but that doesn't prevent you from using it. BUT the date has to be in RFC 822 Format Tue, 15 Nov 1994 08:12:31 GMT
Another thing why do you make it the hard way by coding a behaviour while you could just use HTTPHeaders to add your custom header in your custom pipeline component plus this is so much cleaner
So try to convert your date in the correct format or use HTTPHeaders
http://www.codit.eu/blog/2013/04/30/using-httpheaders-with-wcf-webhttp-adapter-on-biztalk-2013/
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
I having some trouble accessing the REST API from Domino Access Service (9.0.1) via Alamofire in swift.
My code looks like:
Alamofire.request(.GET, dbPath)
.authenticate(usingCredential: credential)
.responseViewCollectionArray { (request, response, viewWrapper, error) in
println("res: \(response)")
if let anError = error {
println("error \(anError)")
completionHandler(nil, anError)
return
}
println("success atPath")
completionHandler(viewWrapper, nil)
}
What brings me as result:
res: Optional( { URL: http://das.name.de/DASLib.nsf/api/data/collections } { status code: 404, headers {
"Cache-Control" = "no-cache";
Connection = close;
"Content-Length" = 220;
"Content-Type" = "text/html; charset=US-ASCII";
Date = "Mon, 06 Apr 2015 06:41:37 GMT";
Expires = "Tue, 01 Jan 1980 06:00:00 GMT";
Server = "Lotus-Domino";
} })
error Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x7fc911f01af0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
So the content-type is wrong why I got an error when putting it into a JSON (swiftyJSON). I can see the "wrong" result using responseString instead of responseJSON from Alamofire. The strange part now is. When I am putting the end point in a rest client like CocoaRestClient it gives me a different content-type
HTTP 200 No Error
Content-Encoding: gzip
Content-Length: 489
Vary: Accept-Encoding
Content-Type: application/json
Server: Lotus-Domino
Date: Sun, 05 Apr 2015 19:41:28 GMT
If I am accessing a different part off the Domino-REST-API (e.g. the Databases on the Server) with the same code (only changing the end point). The code works well and I got the JSON.
So what am I missing? Maybe someone had the same problem when using REST via xPages in Domino.
As #muenzpraeger pointed out: you have a 404 - not found. Presuming that the resource does actually exist, it points to a configuration error. Most likely you haven't enabled the database or the view for access via DAS.
I would be super-mega careful with DAS, once you allow WRITE access anybody who can reach the URL and has author or better access, can write back arbitrary documents and mess up your database (no validation!).
I'm working on some alternative (that also would return JSON on 404). Stay tuned