WCF ProtocolException receiving html - wcf

I am getting the below error while accesssing method from WCF to DotNet
The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: '<html>
<head>
<title>Runtime Error</title>
<style>
body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;}
p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:"Lucida Console";font-size: .9em}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
</style>
</head>
<body bgcolor="white">
<span><H1>Server Error in '/ORSXMLWCFServiceNew' Application.<hr width=100% size=1 color=silver></H1>
<h2> <i>Runtime Error</i> </'.
Kindly help me.

I found a way how to get full response, not just useless 1024 bytes...
using (var client = new Service1Client())
{
try
{
Console.WriteLine(client.DoWork());
}
catch (ProtocolException e)
{
var webException = e.InnerException as WebException;
var responseString = webException.ExtractResponseString();
if (string.IsNullOrEmpty(responseText))
Console.WriteLine(e);
else
Console.WriteLine(responseString);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
where the following helper method is used
public static string ExtractResponseString(this WebException webException)
{
if (webException == null || webException.Response == null)
return null;
var responseStream = webException.Response.GetResponseStream() as MemoryStream;
if (responseStream == null)
return null;
var responseBytes = responseStream.ToArray();
var responseString = Encoding.UTF8.GetString(responseBytes);
return responseString;
}
See my blog for more details http://mnaoumov.wordpress.com/2012/09/28/wcf-protocolexception/

This is caused by an error on your WCF service, the best way to go about fixing it (after checking your code for anything obvious) would be to get some error logging working on the WCF service and check for any exceptions in the logs.
These might help:
Adding logging to WCF
Creating a logging class

Related

ASP.NET Core Web API: 405 - HTTP verb used to access this page is not allowed

In ASP.NET Core-6 application, I have this code for PUT Request:
Service:
public Response<object> AppendStatus(string acctNumber, string appendName)
{
var response = new Response<object>();
try
{
using (AseConnection con = new AseConnection(aseConnection))
{
AseCommand cmd = new AseCommand("sp_append", con);
cmd.CommandType = CommandType.StoredProcedure;
var managerId = CodeUsername.Username;
cmd.Parameters.AddWithValue("#AggregatorId", managerId);
cmd.Parameters.AddWithValue("#AcctNo", acctNumber);
cmd.Parameters.AddWithValue("#ManagerName", appendName);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
response.Success = true;
}
catch (Exception ex)
{
_logger.Error($"An Error occured " + ex.ToString());
response.Success = false;
}
return response;
}
Then I have this controller:
BaseController:
[Produces("application/json")]
[ApiController]
public class BaseApiController : ControllerBase
{
}
[Consumes("application/json")]
[Authorize]
[Route("api/v1/[controller]")]
public class ManagerController : BaseApiController
{
private readonly ILogger<ManagerControllerr> _logger;
private IAccountsTransService _accountsTransService;
public ManagerController(
ILogger<ManagerController> logger,
IAccountsTransService accountsTransService
)
{
_logger = logger;
_accountsTransService = accountsTransService; }
[HttpPut]
[Route("account/append")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public ActionResult<Response<object>> AppendAccount(string acctNumber, string appendName)
{
var result = _accountsTransService.AppendAccount(acctNumber, appendName);
return result;
}
The application is deployed on IIS.
When user submits, the error comes up:
Response body:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>405 - HTTP verb used to access this page is not allowed.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
<div class="content-container"><fieldset>
<h2>405 - HTTP verb used to access this page is not allowed.</h2>
<h3>The page you are looking for cannot be displayed because an invalid method (HTTP verb) was used to attempt access.</h3>
</fieldset></div>
</div>
</body>
Response headers:
allow: GET,HEAD,OPTIONS,TRACE
content-length: 1293
content-type: text/html
date: Wed,12 Oct 2022 17:15:02 GMT
server: Microsoft-IIS/10.0
x-powered-by: ASP.NET
But this is not affecting GET Request.
As I stated, it is a PUT Request.
How do I resolve it?
Often this error is caused by the WebDAV module that try to handle this kind of requests, an easy solution is to remove WebDAV from your system. You can easily get this done in "Turn Windows Features On or Off" simply un-ticking the checkbox.
If this solution does not solve your problem, you can try the solution in this link:
HTTP Error 405.0 when you visit a website that is hosted on a server that is running IIS.

ServiceStack doesn't populate the response DTO when throwing HttpErrors

ServiceStack doesn't populate the original response in the WebServiceException's responseDTO property.
I'm running the code below which should always return a 404 response code with the ResponseStatus property of the TestResponse populated with "Some bad request" but it also seems like should return the original good response with it's output property populated from the request's input property. However I get null when I look at the WebServiceException responseDTO
public TestResponse Post(Test request)
{
var response = new TestResponse() { Output = request.Input };
throw new HttpError(response, (int)HttpStatusCode.BadRequest, "Some bad request");
}
public TestResponse Get(Test request)
{
try
{
using (var client = new JsonServiceClient("http://localhost:5000"))
{
var response = client.Post(request);
return response;
}
}
catch (WebServiceException ex)
{
throw;
}
}
In general I was expecting that the responseDTO property in the WebServiceException will contain the endpoint's DTO as long as it's passed in when throwing the HttpError but that doesn't seem to be the case. I see only default values and nulls for each property in the responseDTO.
When an Exception is thrown only the ResponseStatus is preserved, you can add any additional info to its Meta dictionary.
Alternatively you can return a failed HTTP Response:
public TestResponse Post(Test request)
{
var response = new TestResponse() { Output = request.Input };
base.Response.StatusCode = (int)HttpStatusCode.BadRequest;
return response;
}

XmlHttpRequest and AEM Servlet

I am making an raw ajax call on the clientside, which look like the following,
var url = '/bin/denisa/dummyServlet';
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhr.setRequestHeader('Accept', 'application/json, text/javascript, */*; q=0.01');
xhr.onload = function() {
if (xhr.status === 200) {
alert('deni');
}
else {
alert('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
to the following servlet in AEM:
#Component(
service = {
Servlet.class
},
property = {
"sling.servlet.paths=/bin/denisa/dummyServlet",
"sling.servlet.extensions=json",
"sling.servlet.methods=GET"
}
)
public class DummyServlet extends SlingSafeMethodsServlet {
private static final Logger LOG = LoggerFactory.getLogger(DummyServlet .class);
#Reference
private dummyService dummyService;
#Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(dummyService);
response.setContentType("application/json");
response.getWriter().write(gson.toJson(jsonElement));
}
}
And I got a 404, and i don't know exactly why because the path is the same, and also contentTypes. Does anybody has a clue?
Your code looks good it seems something is missing on the config side
can you log in to the felix console
http://localhost:4502/system/console/bundles
Expand you project bundle and check for your servlet
with Service ID xx Types: javax.servlet.Servlet and other details
*Also ensure the bundle is not installed and in active state
Then go to http://localhost:4502/system/console/configMgr and verify Apache Sling Servlet/Script Resolver execution paths contain /bin/ entry
If above mentioned configs are navigate to http://localhost:4502/system/console/servletresolver
check for servlet response.
These are some of the configuration which helped me to resolve 404

How to return multipart/form-data in response from WCF service?

In my WCF service I need to return MIME Multipart data (a text file) back to client in the response. Althoug the response returned to the client, I don't see the data being returned. As a matter of fact, I don't see anything I setup on the server side being returned to the client. Could someone shed some light on this? Here is what I have in my code for building and returning response:
MultipartFormDataContent formData = new MultipartFormDataContent("myboundary");
HttpResponseMessage responseMsg = new HttpResponseMessage();
try
{
using (Stream fs = File.OpenRead("C;\\mydata.txt"))
{
formData.Add(new StreamContent(fs), "Payload", "mydata.txt");
}
}
catch (Exception ex)
{
ServiceUtil.LogMessage(ex.Message);
}
responseMsg.StatusCode = System.Net.HttpStatusCode.OK;
responseMsg.Content = formData;
WebOperationContext.Current.OutgoingResponse.ContentLength = 2048;
WebOperationContext.Current.OutgoingResponse.ContentType = "multipart/form-data";
WebOperationContext.Current.OutgoingResponse.Headers["Accept"] = "multipart/form-data";
}

Why is WSPasswordCallback.getPassword null when I try my SOAP request

I have made an Axis2 web service with Rampart security, but I was constantly receiving NullPointerException at this line:
if((pwcb.getIdentifier().equals("bob")) && pwcb.getPassword().equals("bobPW")) )
So I added this code:
if ( pwcb.getPassword()==null) {
throw new Exception ("passsssssssss is null:"+pwcb.getPassword());
}
Which threw the exception; so I know that the problem is that pwcb.getPassword is null, but don't understand why.
This is the SOAP request I'm sending:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:nilo="http://nilo">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="123">
<wsse:Username>bob</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobPW</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<nilo:getdataForChecking>
<nilo:data>tranXml</nilo:data>
</nilo:getdataForChecking>
</soapenv:Body>
</soapenv:Envelope>
Here is the handle method that I'm using:
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
//When the server side need to authenticate the user
WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
if ( pwcb.getPassword()==null) {
try {
throw new Exception ("passsssssssss null:"+pwcb.getPassword());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
try {
throw new Exception ("pass nooot null:"+pwcb.getPassword());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(pwcb.getIdentifier().equals("bob") && pwcb.getPassword().equals("bobPW")) {
return;
}
//When the client requests for the password to be added in to the
//UT element
}
}
Whether WSPasswordCallback contains password depends on its usage field. For instance for usage USERNAME_TOKEN_UNKNOWN the password is set and callback handler is supposed to throw an exception, if it does not match username. For SIGNATURE on the other hand, the password field is empty and the callback needs to set it, so that the key can be retrieved from keystore.
You should verify in what scenario callback is called and react appropriately. For instance:
// Rampart expects us to do authentication in this case
if (pwcb.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
String password = passwordFor(pwcb.getIdentifier());
if (pwcb.getPassword().equals(password))
return;
throw new UnsupportedCallbackException(callback,
"password check failed for user " + pwcb.getIdentifier());
}
if (pwcb.getUsage() == WSPasswordCallback.SIGNATURE) {
pwcb.setPassword(passwordFor(pwcb.getIdentifier()));
The handler needs to know the password of the user that initiated the call. You do not have to do the comparison yourself.
Modifying this line from:
if((pwcb.getIdentifier().equals("bob")) && pwcb.getPassword().equals("bobPW")) )
to:
if (pwcb.getIdentifier().equals("bob"))
{
pwcb.setPassword("bobPW");
}