I want to deploy an Apex class via REST API in a "single package" way. The deployment process begins and then fails with "No package.xml found" error. The manifest file is put directly in the root of the archive, however the API tells me that there is no manifest.
My request body looks in the following way
----------------------------BOUNDARY
Content-Disposition: form-data; name="entity_content"
Content-Type: application/json
{
"deployOptions": {
"allowMissingFiles": false,
"autoUpdatePackage": false,
"checkOnly": false,
"ignoreWarnings": false,
"performRetrieve": false,
"purgeOnDelete": false,
"rollbackOnError": true,
"runTests": [],
"singlePackage": true,
"testLevel": "NoTestRun"
}
}
----------------------------BOUNDARY
Content-Disposition: form-data; name="file"; filename="deploy.zip"
Content-Type: application/zip
UEsDBAoAAAAAAM4EL1Zi1oXYuQAAALkAAAALAAAAcGFja2FnZS54bWw8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PjxQYWNrYWdlIHhtbG5zPSJodHRwOi8vc29hcC5zZm9yY2UuY29tLzIwMDYvMDQvbWV0YWRhdGEiPjx0eXBlcz48bWVtYmVycz5BPC9tZW1iZXJzPjxuYW1lPkFwZXhDbGFzczwvbmFtZT48L3R5cGVzPjx2ZXJzaW9uPjU2LjA8L3ZlcnNpb24+PC9QYWNrYWdlPlBLAwQKAAAAAADOBC9WAAAAAAAAAAAAAAAACAAAAGNsYXNzZXMvUEsDBAoAAAAAAM4EL1aRdfeXigAAAIoAAAAWAAAAY2xhc3Nlcy9BLmNscy1tZXRhLnhtbDw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+PEFwZXhDbGFzcyB4bWxucz0iaHR0cDovL3NvYXAuc2ZvcmNlLmNvbS8yMDA2LzA0L21ldGFkYXRhIj48YXBpVmVyc2lvbj41Ni4wPC9hcGlWZXJzaW9uPjwvQXBleENsYXNzPlBLAwQKAAAAAADOBC9WnojzmRIAAAASAAAADQAAAGNsYXNzZXMvQS5jbHNwdWJsaWMgY2xhc3MgQSB7IH1QSwECFAAKAAAAAADOBC9WYtaF2LkAAAC5AAAACwAAAAAAAAAAAAAAAAAAAAAAcGFja2FnZS54bWxQSwECFAAKAAAAAADOBC9WAAAAAAAAAAAAAAAACAAAAAAAAAAAABAAAADiAAAAY2xhc3Nlcy9QSwECFAAKAAAAAADOBC9WkXX3l4oAAACKAAAAFgAAAAAAAAAAAAAAAAAIAQAAY2xhc3Nlcy9BLmNscy1tZXRhLnhtbFBLAQIUAAoAAAAAAM4EL1aeiPOZEgAAABIAAAANAAAAAAAAAAAAAAAAAMYBAABjbGFzc2VzL0EuY2xzUEsFBgAAAAAEAAQA7gAAAAMCAAAAAA==
----------------------------BOUNDARY--
where Base64-encoded Zip file has the following structure
package.xml
classes/
A.cls
A.cls-meta.xml
and those three files look in the following way.
(package.xml)
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>A</members>
<name>ApexClass</name>
</types>
<version>56.0</version>
</Package>
(A.cls)
public class A { }
(a.cls-meta.xml)
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>56.0</apiVersion>
</ApexClass>
I've also tried to set singlePackage to false and use unpackaged folder as a wrapper but I doesn't work, too.
There is a possibility that "No package.xml found" is a catch-all error that makes solving the problem harder than it should be.
I want to remove the backslashes from the soap service response.
Is there any way to remove the single backslashes?
string;
<?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\">
I have a valid sitemap.xml file. The problem arises when I try to serve this file as a sitemap.xml. I get the following error:
This page contains the following errors:
error on line 1 at column 95: Extra content at the end of the document
Below is a rendering of the page up to the first error.
When I inspect /sitemap.xml from browser each element tag gets this added to it.
<url xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
the rest
</url>
Here is how I return the file from the controller:
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\sitemap.xml");
return Content(xml.DocumentElement.InnerXml, "application/xml");
Here is an example of the file I have and trying to return
<?xml version="1.0" encoding="utf-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>LINK</loc>
</url>
THE REST OF URLS
</urlset>
I have tried switching the "application/xml" to "text/xml" but didn't solve this problem. Am I not using XmlDocument correctly or am I not fully understanding what happens with return Content()?
Any help is appreciated.
Thank you
What ended up fixed this was a simple fix.
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\sitemap.xml");
return Content(xml.DocumentElement.InnerXml, "application/xml");
Changed to
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\sitemap.xml");
return Content(xml.DocumentElement.OuterXml, "application/xml");
Hope this helps someone later.
Have the following code in my Default.aspx file, located at http://localhost/idss/Default.aspx:
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head id="Head1" runat="server">
<title>Testing IDSS Return Values</title>
</head>
<body>
<%#
// how we do it
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("idss/requests/categoryList.xml"));
// create the request to your URL
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/idss/Default.aspx");
// add the headers
// the SOAPACtion determines what action the web service should use
// YOU MUST KNOW THIS and SET IT HERE
request.Headers.Add("SOAPAction", "http://ws.idssasp.com/Members.asmx/GetCategoryList");
// set the request type
// we use utf-8 but set the content type here
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Accept = "text/xml";
request.Method = "POST";
// add our body to the request
Stream stream = request.GetRequestStream();
doc.Save( stream );
stream.Close();
// get the response back
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
request.Write(response);
}//end using
%>
</body>
</html>
The xml file located at: http://localhost/idss/requests/categoryList.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthorizeHeader xmlns="http://ws.idssasp.com/Members.asmx">
<UserName>MyUsername</UserName>
<Password>MyPassword</Password>
</AuthorizeHeader>
</soap:Header>
<soap:Body>
<GetCategoryList xmlns="http://ws.idssasp.com/Members.asmx" />
</soap:Body>
</soap:Envelope>
Where MyUsername and MyPassword is filled in with the correct username and password. The URL located here: http://ws.idssasp.com/members.asmx?op=GetCategoryList&pn=0 tells me that SOAP should send a request like this:
POST /members.asmx HTTP/1.1
Host: ws.idssasp.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://ws.idssasp.com/Members.asmx/GetCategoryList"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthorizeHeader xmlns="http://ws.idssasp.com/Members.asmx">
<UserName>string</UserName>
<Password>string</Password>
</AuthorizeHeader>
</soap:Header>
<soap:Body>
<GetCategoryList xmlns="http://ws.idssasp.com/Members.asmx" />
</soap:Body>
</soap:Envelope>
But when I browse to http://localhost/idss/Default.aspx I get an Internal Server Error (500). What exactly am I doing wrong here? Do I need to add namespaces? Or other References somewhere in the Default.aspx file? If so, which one's are needed? Also, am I pointing to the correct in (HttpWebRequest)WebRequest.Create("http://localhost/idss/Default.aspx");?
Am I doing this correctly? I just feel like something is missing here.
I there a way to know if a request is a soap request on AuthenticateRequest event for HttpApplication? Checking ServerVariables["HTTP_SOAPACTION"] seems to not be working all the time.
public void Init(HttpApplication context) {
context.AuthenticateRequest += new EventHandler(AuthenticateRequest);
}
protected void AuthenticateRequest(object sender, EventArgs e) {
app = sender as HttpApplication;
if (app.Request.ServerVariables["HTTP_SOAPACTION"] != null) {
// a few requests do not enter here, but my webservice class still executing
// ...
}
}
I have disabled HTTP POST and HTTP GET for webservices in my web.config file.
<webServices>
<protocols>
<remove name="HttpGet" />
<remove name="HttpPost" />
<add name="AnyHttpSoap" />
</protocols>
</webServices>
Looking at ContentType for soap+xml only partially solves my problem. For example,
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 1131
Content-Type: text/xml
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: ro
Host: localhost
mymethod: urn:http://www.wsnamespace.com/myservice
Some clients instead of having the standard header SOAPAction: "http://www.wsnamespace.com/myservice/mymethod", have someting like in example above. "mymethod" represents the method in my web service class with [WebMethod] attribute on it and "http://www.wsnamespace.com/myservice" is the namespace of the webservice. Still the service works perfectly normal.
The consumers use different frameworks (NuSOAP from PHP, .NET, Java, etc).
You could look at Request.ContentType property, which if properly set by the client should be
application/soap+xml; charset=utf-8
The utf-8 part may not be present.
Aside from that, surely you can just check the URL, and if it's a webservice one then that tells you what it is.
I always give web services their own port. That way I don't have to filter every HTTP request that comes across port 80. Or rather, I can filter port 80 for browser-oriented issues, and SOAP/SOA ports for other types of attacks.
IMAO, mixing (potentially) sensitive business data with public data just so you don't have to open another hole in the firewall is thumbing your nose at the very reason you have a firewall in the first place.
You could also go down the harder route and figure things out based on everything else that's below HTTP headers. What I mean by that is, to analyze things like below, which is the SOAP request body - part of the request...
<soap:Envelope xmlns:soap="..." soap:encodingStyle="...">
IBM
Have you tested the System.Web.HttpContext.Current.Request.CurrentExecutionFilePathExtension ??
Normally this would be .asmx for webservices (json and xml), as long as you handle the service of course.
I am using following code to identify the request type. Try this if it match your requirment. Mark as answer if it help you.
if (request.Headers["SOAPAction"] != null || request.ContentType.StartsWith("application/soap+xml"))
return ServiceRequestTypes.SoapRequest;
else if ("POST".Equals(request.RequestType, StringComparison.InvariantCultureIgnoreCase) && request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.InvariantCultureIgnoreCase))
return ServiceRequestTypes.HttpPostRequest;
else if ("POST".Equals(request.RequestType, StringComparison.InvariantCultureIgnoreCase) && request.ContentType.StartsWith("application/json", StringComparison.InvariantCultureIgnoreCase))
return ServiceRequestTypes.AjaxScriptServiceRequest;
return ServiceRequestTypes.Unknown;