IDataServiceMetadataProvider - Entities dont show up in $metadata - asp.net

I am trying to write our own RIA services provider to expose data from a server that I access via ODBC. I follow th eguidelines set out at http://blogs.msdn.com/alexj/archive/2010/03/02/creating-a-data-service-provider-part-9-un-typed.aspx
I have written our own IDataServiceMetadataProvider / IDataServiceQueryProvider pair and get no errors on what i do.
I am putting in a resource set like this:
ResourceType tableType = new ResourceType(
typeof(Dictionary<string, object>),
ResourceTypeKind.EntityType,
null,
"Martini",
table_name,
false
);
tableType.CanReflectOnInstanceType = false;
var prodKey = new ResourceProperty(
"Key",
ResourcePropertyKind.Key |
ResourcePropertyKind.Primitive,
ResourceType.GetPrimitiveResourceType(typeof(int))
);
prodKey.CanReflectOnInstanceTypeProperty = false;
tableType.AddProperty(prodKey);
var prodName = new ResourceProperty(
"Name",
ResourcePropertyKind.Primitive,
ResourceType.GetPrimitiveResourceType(typeof(string))
);
prodName.CanReflectOnInstanceTypeProperty = false;
tableType.AddProperty(prodName);
_MetaDataProvider.AddResourceType(tableType);
_MetaDataProvider.AddResourceSet(new ResourceSet(table_name, tableType));
I see the requests coming in for enumerating the resource sets. I check them there in a breakpoint, and the resource set and the type is there, with all properties.
Still, the output I get is:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
- <service xml:base="http://localhost:2377/MartiniData.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
- <workspace>
<atom:title>Default</atom:title>
</workspace>
</service>
And for the $metadata version:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
- <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
- <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0">
- <Schema Namespace="Martini" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm">
<EntityContainer Name="Martini" m:IsDefaultEntityContainer="true" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>
The actual metadata for the types never shows up, no error is shown. pretty frustrating. Anyone any idea?

Hmpf. Found.
config.SetEntitySetAccessRule("*", EntitySetRights.All);
was missing in the initialization, so all entities were filtered out ;)

Related

How to omit null values in JSON AssignMessage payload in APIGEE?

I built a proxy that basically expects a different JSON input object than the one the final endpoint is expecting to receive. So, in order to bridge the request object from one to the other I'm using an AssingMessage policy to transform the json input.
I'm doing something like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-Sample">
<DisplayName>Assign Message-Sample</DisplayName>
<Remove>
<Headers>
<Header name="login_id"/>
<Header name="Authorization"/>
</Headers>
<Payload>true</Payload>
</Remove>
<Set>
<Payload contentType="application/json">
{
"valueA": "{clientrequest.valueA}",
"valueB": "{clientrequest.valueB}",
"valueC": "{clientrequest.valueC}",
"valueD": "{clientrequest.valueD}",
"valueE": "{clientrequest.valueE}",
"valueF": "{clientrequest.valueF}",
}
</Payload>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
The problem comes when some of the values are empty. The destination server does not handle properly any empty values (escapes from my control).
My question is: how can I skip entirely a parameter if value is empty?
I'm looking for something like this (or better alternative):
<Payload contentType="application/json">
{
<skip-if-empty name="clientrequest.valueA">
"valueA": "{clientrequest.valueA}",
</skip-if-empty>
"valueB": "{clientrequest.valueB}",
...
}
</Payload>
For what I have found from my research, it seems this is a job for a Javascript Policy.
How is this done?
You basically need to place a javascript policy right before the AssignMessage execution. In the javascript policy you have the freedom to apply all the logic to omit certain parameters if values are not provided.
So for example, say we have already extracted the request values to variables using an ExtractVariables policy. Then, in the Javascript policy we can validate those values and build the resulting JSON object to later store it in another variable that will be picked up by the AssingMessage policy.
javascript policy:
var valueA = context.getVariable("clientrequest.valueA"),
valueB = context.getVariable("clientrequest.valueB"),
valueC = context.getVariable("clientrequest.valueC"),
...
var result = {};
if(valueB) {
result.b = valueB;
}
if(valueA) {
result.a = valueA;
}
if(valueC) {
result.c = valueC;
}
...
context.setVariable("newInput", JSON.stringify(result));
Then our AssignMessage will just pick up the variable we just stored: "newInput" that will contain the complete JSON object string:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-Sample">
<DisplayName>Assign Message-Sample</DisplayName>
<Remove>
<Headers>
<Header name="login_id"/>
<Header name="Authorization"/>
</Headers>
<Payload>true</Payload>
</Remove>
<Set>
<Payload contentType="application/json">
{newInput}
</Payload>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
This solution worked fine for me. I hope someone else finds it helpful.

Issue trying to solve 404 status error code on servlet GET request

Once again thanks for the help on previous help. Anyway I try to move on to my EFTscreen.java code to get my Search buttons to work. In my JSP page I have the following search button with the following function call (hope I get parathesis pasting this:
<button id="searchEFT" class="btn smBtn">Search</button>
xmlhttp = new XMLHttpRequest();
if (Cmd_Sched_Number != "")
{
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("EFTSumList").innerHTML = http.responseText;
}
};
xmlhttp.open("GET","/servlet/EFTscreen?method=searchSched&Schedule_Number="
+ Cmd_Sched_Number + "&Contract_Year=" + Cmd_Contract_Year,true);
xmlhttp.send();
}
Now in looking around I was told that I need to create the servlet name and classs in the web.xml file located the WEB-INF directory of project
<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<display-name>EFTscreen</display-name>
<servlet-name>EFTscreen</servlet-name>
<servlet-class>eftproject.EFTscreen</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EFTscreen</servlet-name>
<url-pattern>/servlet/EFTscreen</url-pattern>
</servlet-mapping>
here is my declaration in the EFTscreen.java file to supposedly pull the Httpservlet (removed some of the imports because it is already too big a question)
package eftproject;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
#WebServlet(name = "EFTscreen", urlPatterns = { "/servlet/EFTscreen"})
public class EFTscreen extends HttpServlet { }
When I try running this going through debugging, I am getting the 404 error in the xmlhttp.status field not being able to find the URL. The readystate fields are working but not sure if that is relevant.
Can you review to see what I am missing here or incorrectly? I am thinking it is something with my url-pattern in web.xml and how I am accessing it but maybe it is something even worse.
Thanks for the help

Generating XML output with XQuery / XPath expression matching nothing, why?

I am trying to generate the following xml output:
<OrderDataUpdate xmlns=”http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25”>
<TetheringType>IE Tethering</TetheringType>
</OrderDataUpdate>
But instead I get this(note the text content for TetheringType is not populated).
<OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
<TetheringType/>
</OrderDataUpdate>
My input XML:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<ser:serviceLookUpResponse
xmlns:ser="http://xmlns.oracle.com/communications/inventory/webservice/service">
<com:requestContext xsi:nil="true"
xmlns:com="http://xmlns.oracle.com/communications/inventory/webservice/common"/>
<com:messages xmlns:com="http://xmlns.oracle.com/communications/inventory/webservice/common"
>Success</com:messages>
<service>
<id>12021409</id>
<name>1</name>
<description xsi:nil="true"/>
<state>in service</state>
<startDate>2013-11-06T00:13:02.000-06:00</startDate>
<specification>
<name>HSPA Wireless Service</name>
<entityType>Service</entityType>
<description xsi:nil="true"/>
<startDate>2010-05-13T00:00:01.000-05:00</startDate>
<endDate xsi:nil="true"/>
</specification>
<parties>
<id>1-3BQJ7K</id>
<name>MTSC NETWORK SRV WIRELESS-CELLULAR</name>
<description xsi:nil="true"/>
</parties>
<configurations>
<version>31</version>
<previousVersion>30</previousVersion>
<id>Se_12021409_31</id>
<name>Se_12021409_31</name>
<description xsi:nil="true"/>
<state>completed</state>
<startDate>2015-01-21T15:03:52.000-06:00</startDate>
<endDate xsi:nil="true"/>
<configurationItems>
<name>Entitlement</name>
<index>0</index>
<resourceAssignment>
<state>assigned</state>
<resource>
<id>Tethering</id>
<name xsi:nil="true"/>
<description>Tethering Entitlement</description>
<specification>
<name>Entitlement</name>
<entityType>Custom Network Address</entityType>
<description xsi:nil="true"/>
<startDate>2015-01-15T00:00:01.000-06:00</startDate>
<endDate xsi:nil="true"/>
</specification>
</resource>
</resourceAssignment>
<resourceReference xsi:nil="true"/>
<characteristics>
<name>Tethering Type</name>
<value>IE Tethering</value>
</characteristics>
</configurationItems>
</configurations>
</service>
</ser:serviceLookUpResponse>
</soapenv:Body>
</soapenv:Envelope>
Xquery:
declare namespace soap = "http://schemas.xmlsoap.org/soap/envelope/";
declare namespace ser = "http://xmlns.oracle.com/communications/inventory/webservice/service";
declare namespace oms = "urn:com:metasolv:oms:xmlapi:1";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare option output:indent "yes";
declare function local:generateUpdate($uimResponse as element()*) as element()
{
let $update :=
<OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
<TetheringType>{ $uimResponse//characteristics[name='Tethering Type']/value/text() }</TetheringType>
</OrderDataUpdate>
return
$update
};
let $uimResponse := fn:root(.)/soap:Envelope/soap:Body/ser:serviceLookUpResponse
let $mdn := $uimResponse//configurationItems[name = 'MDN']/resourceAssignment/resource/name/text()
let $output := local:generateUpdate($uimResponse)
return
(
$output
)
If I modify the function local:generateUpdate to remove xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25", then text content of TetheringType gets populated in the generated output xml which appears something like below:
<OrderDataUpdate>
<TetheringType>IE Tethering</TetheringType>
</Add>
</OrderDataUpdate>
What am I doing wrong? Can someone explain to me why is it that on adding xmlns=”http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25” to the OrderDataUpdate element, the text content of xml nodes are not populated in the xml output. I need the <OrderDataUpdate> to be associated with the namespace "http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25"
Any help would be appreciated.
Thanks in advance.
At first glance, it looks as though by declaring a default namespace on your OrderDataUpdate element, you have caused a change in the interpretation of the unprefixed names characteristics, name, and value which occur lexically within that element. Your TetheringType element gets no text content because the XPath is matching nothing (there are no characteristics element in the namespace http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25 in your input).
On second glance, this hypothesis is confirmed by the XPath spec and by the behavior of the XQuery processors I have checked with.
There are at least two simple ways to fix your problem. First, you could avoid the name capture by not declaring a default namespace:
declare function local:generateUpdate(
$uimResponse as element()*
) as element() {
let $update := <odu:OrderDataUpdate
xmlns:odu=
"http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
<odu:TetheringType>{
$uimResponse//characteristics[name='Tethering Type']
/value/text()
}</odu:TetheringType>
</odu:OrderDataUpdate>
return $update
};
Or you could just move the calculation of the text out of the scope of the default namespace declaration:
declare function local:generateUpdate(
$uimResponse as element()*
) as element() {
let $tttext := $uimResponse
//characteristics[name='Tethering Type']
/value/text()
let $update := <OrderDataUpdate
xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
<TetheringType>{
$tttext
}</TetheringType>
</OrderDataUpdate>
return $update
};

wsdl soap exception

Having trouble with soap exceptions.
I'm throwing soap exception in asp.net web service and have to somehow get that exception (in form of xml) to show in browser, like this:
SOAP 1.1
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault><faultcode>soap:Client</faultcode>
<faultstring></faultstring>
<detail>
<Error>
<ErrorNumber>1</ErrorNumber>
<ErrorMessage>Error...</ErrorMessage>
</Error>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Throwing exception from web service:
XmlDocument doc = new XmlDocument();
XmlNode detailNode = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace);
XmlElement details = doc.CreateElement("Error");
XmlElement detailchild1 = doc.CreateElement("ErrorNumber");
detailchild1.InnerText = "1";
XmlElement detailchild2 = doc.CreateElement("ErrorMessage");
detailchild2.InnerText = "Error...";
details.AppendChild(detailchild1);
details.AppendChild(detailchild2);
detailNode.AppendChild(details);
throw new SoapException("Fault", SoapException.ClientFaultCode, "", details);
If I test it with windows application that calls that service, I can catch exception and extract all details so it seems that everything works with creating xml and throwing exception.
But all I'm getting from browser is internal error 500, which is according to other answers I found normal behaviour. Can I somehow get that xml in browser instead of internal error 500, maybe by changing web.config, IIS settings...
shouldn't this
throw new SoapException("Fault", SoapException.ClientFaultCode, "", details);
be
throw new SoapException("Fault", SoapException.ClientFaultCode, "", detailNode);
?

Does anyone know if the crossdomain policy file at salesforce.com has changed?

Suddenly my Flex Apps can no longer connect to salesforce.com via its API, I am getting a security sandbox violation. Login credentials are correct, I have tried them via a different means, and I have obfuscated them below.
This was working fine earlier today and I have not been coding since then.
Anyone else come across this or know what's going on?
Here is the exception returned to my app
Method name is: login
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer connected.
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer sending message 'B89E5879-D7F7-E91E-2082-BBEE231054DD'
'direct_http_channel' channel sending message:
(mx.messaging.messages::HTTPRequestMessage)#0
body = "<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/"><se:Header xmlns:sfns="urn:partner.soap.sforce.com"/><se:Body><login xmlns="urn:partner.soap.sforce.com" xmlns:ns1="sobject.partner.soap.sforce.com"><username>simon.palmer#***.com</username><password>***</password></login></se:Body></se:Envelope>"
clientId = (null)
contentType = "text/xml; charset=UTF-8"
destination = "DefaultHTTPS"
headers = (Object)#1
httpHeaders = (Object)#2
Accept = "text/xml"
SOAPAction = """"
X-Salesforce-No-500-SC = "true"
messageId = "B89E5879-D7F7-E91E-2082-BBEE231054DD"
method = "POST"
recordHeaders = false
timestamp = 0
timeToLive = 0
url = "https://www.salesforce.com/services/Soap/u/11.0"
Method name is: login
*** Security Sandbox Violation ***
Connection to https://www.salesforce.com/services/Soap/u/11.0 halted - not permitted from https://localhost/pm_server/pm/pm-debug.swf
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer acknowledge of 'B89E5879-D7F7-E91E-2082-BBEE231054DD'.
'A997F86A-36E9-DDDC-EC6B-BBEE23101466' producer fault for 'B89E5879-D7F7-E91E-2082-BBEE231054DD'.
Comunication Error : Channel.Security.Error : Security error accessing url : Destination: DefaultHTTPS
Error: Request for resource at https://www.salesforce.com/services/Soap/u/11.0 by requestor from https://localhost/pm_server/pm/pm-debug.swf is denied due to lack of policy file permissions.
You have to make sure to load the policy from the /services tree, the default policy at the root won't help you. You need to load this policy https://www.salesforce.com/services/crossdomain.xml
The solution to this problem was to set the server protocol and url as follows:
apex = new Connection();
apex.serverUrl = "https://na3.salesforce.com/services/Soap/u/14.0";
apex.protocol = "https";
However, this seems to create a secondary issue of users being locked out, so the issue of non-connectivity remains.
Update: salesforce.com have acknowledged a bug. See my other related post.
Did you recently upgrade to flash player 10? Flash player 10 changes the way policy files work to some degree, and the crossdomain.xml file needs to be updated to address this. In short, Salesforce.com probably isn't prepared for users upgrading to Flash Player 10 yet.
I resolve this issue accessing to the Flash Player Configuration Panel(I just recommend it in a development environment), in the "Global Security" tab, select Always Allow.
Regards.
I am uploading a file from flex to Google docs. Everything is working in the local file however, when we upload the SWF file as S-controls in Salesforce (sandbox), an error appears upon connecting to Google. Please see error below:
Error:[FaultEvent fault=[RPC Fault faultString="Security error accessing url"
faultCode="Channel.Security.Error" faultDetail="Destination: DefaultHTTPS"]
messageId="1F812836-1318-B845-AC01-F51AB1D11518" type="fault" bubbles=false
cancelable=true eventPhase=2]
We tried the following solutions below but nothing seems to work:
FLEX:
- Add the crossdomain.xml in the bin-debug folder: below is the content of the cross domain policy.
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" secure="false" />
<allow-http-request-headers-from domain="*" headers="*" secure="false" />
</cross-domain-policy>
Used flash.system.security.allowinsecuredomain/allowdomain(“*”) in the initialization.
Also tried in the connection.protocol set to http
Salesforce:
Disabled the protocol security in the remote site settings
o Setup -> Administration Setup -> Security Controls -> Remote Site Settings
 URL: http://www.google.com.ph
There’s no problem in connection to Salesforce but upon initialization of the uploading page the security error will appear specifically in the onErrorFault function. Below are code snippets:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="534" height="462" verticalScrollPolicy="off" horizontalScrollPolicy="off"
creationComplete="init()" showCloseButton="true" close="{this.closeWindow(event)}" roundedBottomCorners="true">
<mx:Script>
<![CDATA[
private function init():void{
Security.allowInsecureDomain("*");
//<salesforce:Connection id="apex" sendRequest="sendRequestListener(event)" serverUrl="http://www.salesforce.com/services/Soap/u/10.0" protocol="http"/>
RESTProxyTest();
send_data();
arrAddedFiles = new Array();
this.uploadGrid.dataProvider= this.acFiles;
this.title = "Attachment: "+this.selectedTimeSheetDetail.Project.label;
}
public function RESTProxyTest():void
{
_conn = new NetConnection();
_conn.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
_conn.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
_conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
_conn.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
_conn.objectEncoding = ObjectEncoding.AMF3;
_conn.connect(_url);
_responder = new Responder(onResult, onFault);
}
private function send_data():void {
userRequest.url = getLoginURL();
userRequest.addEventListener(ResultEvent.RESULT, httpResult);
userRequest.addEventListener(FaultEvent.FAULT, onErrorFault);
userRequest.send();
}
private function onErrorFault(obj:FaultEvent):void
{
Alert.show("Error:"+obj.toString());
}
private function httpResult(obj:ResultEvent):void
{
trace(obj.toString());
var result:String = obj.result as String;
var pos:int = result.lastIndexOf("Auth=");
var auth:String = result.substr(pos + 5);
txtAuth.text = StringUtil.trim(auth);
placeCall();
}
protected function placeCall():void
{
trace("placeCall");
var headers:Array = ["Authorization: " + "GoogleLogin auth=" + StringUtil.trim(txtAuth.text)];
var postVars:Array = [];
var uri:String = "http://docs.google.com/feeds/documents/private/full?showfolders=true";
_conn.call("RESTProxy.request", _responder, uri, "get", new Array(), postVars, headers);
}
private function getLoginURL():String
{
var url:String = 'https://www.google.com/accounts/ClientLogin?accountType=HOSTED_OR_GOOGLE&' +
'Email=' + this.session.config.gmail + '&' +
'Passwd=' + this.session.config.password + '&service=writely';
return url;
}
]]>
</mx:Script>
<mx:HTTPService id="userRequest" useProxy="false" method="POST" contentType="application/x-www-form-urlencoded" showBusyCursor="true"/>

Resources