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

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.

Related

Web Api 2 custom IHttpActionResult CORS. No 'Access-Control-Allow-Origin' header is present on the requested resource

I have a problem with CORS from my WEB API 2 to Angular application.
Everything is working fine till now and all the response headers are receiving the following:
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:24
Content-Type:application/json; charset=utf-8
Date:Mon, 13 Nov 2017 08:15:32 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/10.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?...
Now I created a custom IHttpActionResult like this:
public class ZipFileActionResult : IHttpActionResult
{
private const long BufferLength = 65536;
public ZipFileActionResult(string file)
{
this.Filepath = file;
}
public string Filepath { get; private set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage result = new HttpResponseMessage();
var zipf = new FilesStream(this.Filepath);
Action<Stream, HttpContent, TransportContext> writeToStream = zipf.WriteToStream;
result.Content = new PushStreamContent(writeToStream, new MediaTypeHeaderValue("application/" + "zip"));
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "filename.zip"
};
return Task.FromResult(result);
}
private async void OnStreamConnected(Stream outputStream, HttpContent content, TransportContext context)
{
try
{
var buffer = new byte[BufferLength];
using (var nypdVideo = File.Open(this.Filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var videoLength = (int)nypdVideo.Length;
var videoBytesRead = 1;
while (videoLength > 0 && videoBytesRead > 0)
{
videoBytesRead = nypdVideo.Read(buffer, 0, Math.Min(videoLength, buffer.Length));
await outputStream.WriteAsync(buffer, 0, videoBytesRead);
videoLength -= videoBytesRead;
}
}
}
catch (HttpException ex)
{
return;
}
finally
{
// Close output stream as we are done
outputStream.Close();
}
}
}
and I use this in my DownloadCOntroller like this:
[HttpPost]
[Route("PaperCuts")]
public IHttpActionResult PaperCuts(List<SelectionObject> selections)
{
try
{
string sFileName = <filename> + ".zip";
return new ZipFileActionResult(sFileName);
}
}
catch (Exception ex)
{
throw ex;
}
}
I'm receiving the following error when I call this function correctly:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
And I'm receiving this as response header:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcS25pcHNlbGtyYW50XEtuaXBzZWxrcmFudEFQSVxLbmlwc2Vsa3JhbnRBUElcYXBpXGRvd25sb2FkXFBhcGVyQ3V0cw==?=
X-Powered-By: ASP.NET
Date: Mon, 13 Nov 2017 08:35:33 GMT
I also have this stated in my WebApiConfig.cs (It works for all my other requests except for this one).
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
So the problem is that the Access-Control-Allow-Origin header etc are not same as in ALL the other requests. So how is this possible and how can I fix this?
I hope I provided enough information for my question.
Kind regards,
D.
I found the answer and got reminded by #ICantSeeSharp
I added following code in my global exception handler:
public override bool ShouldHandle(ExceptionHandlerContext context)
{
return true;
}

Cannot run simple script with WebView Universal Windows App

I have simple html file (save in project) load on to WebView. It load success and display "Hello World" header.
File index.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>ABC</title>
<script>
function SayHello() {
return "hello";
};
</script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Load to WebView
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
webView.Navigate(new Uri("ms-appx-web:///index.html", UriKind.RelativeOrAbsolute));
// Exception below line
var data = await webView.InvokeScriptAsync("eval", new List<string> { "SayHello();" });
Debug.WriteLine(data);
}
I don't understand why this happen. It success run on Google Chrome. Am I miss something here?
MSDN about Navigate method:
Loads the HTML content at the specified Uniform Resource Identifier
(URI).
When you call the method, it doesn't instantly load the content, it may take some time. You need to listen to the DOMContentLoaded event and then run the script when page is actually loaded into the WebView.
webView1.DOMContentLoaded += webView1_DOMContentLoaded;
...
...
private async void webView1_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
var data = await webView.InvokeScriptAsync("eval", new List<string> { "SayHello();" });
Debug.WriteLine(data);
}
I think you should go to Manifest profile in URI,
Windows Runtime Access= All
Type = Include

Handling multiple submit buttons with JSP and Servlets

I have a table that is generated from the database. This table will be enclosed in a form. Below is the result on a browser:
http://i.imgur.com/NLZzgwP.png (Low rep problems)
Below is the JSP/JSTL code:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Issues</title>
<style type="text/css">
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
td {
padding: 10px;
}
</style>
</head>
<body>
<sql:setDataSource
var="myDS"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/pdfdb"
user="user" password="*******"
/>
<sql:query var="listIssues" dataSource="${myDS}">
SELECT BookId from Book;
</sql:query>
<form method="get" action="fileDownload">
<div align="center">
<table>
<caption>List of Issues</caption>
<tr>
<th>Magazine Issue #</th>
<th>Download</th>
</tr>
<c:forEach var="issue" items="${listIssues.rows}">
<tr>
<td><c:out value="${issue.BookId}" /></td>
<td><input name='<c:out value="${issue.BookId}" />' type="submit" value="Download"></td>
</tr>
</c:forEach>
</table>
</div>
</form>
</body>
</html>
Now, what I want is for the download button to be kind of linked with the id/Issue number that is placed on the same row as the button such that, when the user clicks the download button, it passes the id/magazine issue number to the url telling the browser that the user wants to download the corresponding magazine issue number of that button clicked. Below is the servlet I use to implement this:
package com.mypackage.fileDownload;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FileDownloadServlet
*/
#WebServlet("/fileDownload")
public class FileDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//size of byte buffer to send file
private static final int BUFFER_SIZE = 4096;
//database connection settings
private String dbUrl = "jdbc:mysql://localhost:3306/pdfdb";
private String dbUser = "user";
private String dbPass = "******";
/**
* #see HttpServlet#doGet(HttpServletRequesrequest,HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get upload id from URL's parameters
String uploadId = request.getParameter("name");
Connection con = null; //connects to the database
try {
//connects to the database
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(dbUrl, dbUser, dbPass);
//queries the database
String sql = "SELECT * FROM Book WHERE BookId = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, uploadId);
ResultSet result = pstmt.executeQuery();
if(result.next()) {
//gets file name and file blob data
String fileId = result.getString("BookId");
Blob blob = result.getBlob("BookContent");
InputStream inputStream = blob.getBinaryStream();
int fileLength = inputStream.available();
System.out.println("File length = " + fileLength);
ServletContext context = getServletContext();
//Sets MIME type for the file download
String mimeType = context.getMimeType(fileId);
if(mimeType == null) {
mimeType = "application/octet-stream";
}
//set content properties and header attributes for the response
response.setContentType(mimeType);
response.setContentLength(fileLength);
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", fileId);
response.setHeader(headerKey, headerValue);
//writes the file to the client
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
} else {
//no file found
response.getWriter().print("File not found for the id: " + uploadId);
}
} catch(SQLException ex) {
ex.printStackTrace();
response.getWriter().print("SQL Error: " + ex.getMessage());
} catch(IOException ex) {
ex.printStackTrace();
response.getWriter().print("IO Error: " + ex.getMessage());
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
response.getWriter().print("Class Missing Error: " + ex.getMessage());
}
finally {
if(con != null) {
//closes the database connection
try {
con.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
}
}
}
Well, from the way I have done this, it is not working the way I wanted it to. For example, if you run this code on the server and click any of the download buttons, the url will be something like
issue.jsp?1=Download
which is weird.It will also display on the browser
File not found for the id: null
I expect something like(on the url)
issue.jsp?Download=1
where 1 is the issue being downloaded. My database has two columns: the IssueId and fileContent(content of file stored in BLOB).
I think I have explained enough and the concept is clear. Any help will be appreciated and this is as far as I could go with my code & research. Thanks!
The simplest way is to just move the form inside the table and do multiple forms:
<div align="center">
<table>
<caption>List of Issues</caption>
<tr>
<th>Magazine Issue #</th>
<th>Download</th>
</tr>
<c:forEach var="issue" items="${listIssues.rows}">
<tr>
<td><c:out value="${issue.BookId}" /></td>
<td>
<form method="get" action="fileDownload">
<input type='hidden' name='bookid' value='<c:out value="${issue.BookId}" />' />
<input type="submit" value="Download">
</form>
</td>
</tr>
</c:forEach>
</table>
</div>
You also need to move the value out of the name attribute of the button and into the value attribute of a hidden input. That hidden input needs a name you will use to get the value in the servlet: request.getParameter("bookid");

jasper pdf report does not show up

my JSF 2.0 web application is intended to produce PDF reports.
the problem is that no PDF report is shown up in the explorer window.
I am using eclipse kepler, with apache-tomcat-7.0.52 and the version of jasper Ireport is 4.8
any help would be appreciated.
I will provide the whole java class :
package khldqr.beans;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
#ManagedBean
#SessionScoped
public class TestReport {
private List<Refugee> refugee;
public List<Refugee> connectRefugeeData() {
ResultSet rs = null;
PreparedStatement pst = null;
Connection con = Database.getConnection();
String stm = "Select R_NO, F_P_Name from M_MAIN_INFO where R_NO < 10";
refugee = new ArrayList<Refugee>();
try {
pst = con.prepareStatement(stm);
pst.execute();
rs = pst.getResultSet();
while (rs.next()) {
Refugee refugeelist = new Refugee();
refugeelist.setR_NO(rs.getInt(1));
refugeelist.setF_P_Name(rs.getString(2));
refugee.add(refugeelist);
}
} catch (SQLException e) {
e.printStackTrace();
}
return refugee;
}
public void PDF(ActionEvent actionEvent) throws IOException, JRException {
System.out.println("this is not my lucky day!!!!!");
File jasper = new File(FacesContext.getCurrentInstance().getExternalContext().getRealPath("report/Majd.jasper"));
byte[] bytes = JasperRunManager.runReportToPdf(jasper.getPath(),null,new JRBeanCollectionDataSource(refugee));
HttpServletResponse response =(HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setContentType("application/pdf");
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(bytes, 0 , bytes.length);
outputStream.flush();
outputStream.close();
FacesContext.getCurrentInstance().responseComplete();
}
public TestReport() {
connectRefugeeData();
}
public List<Refugee> getRefugee() {
return refugee;
}
public void setRefugee(List<Refugee> refugee) {
this.refugee = refugee;
}
}
and here is xhtml file:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Hello To GOPA World!!</title>
</h:head>
<h:body dir="rtl">
<h:form>
<p:commandButton value = "PDF" actionListener="#{testReport.PDF}"></p:commandButton>
</h:form>
<h:dataTable value="#{testReport.refugee}" var="var">
<h:column>
<h:outputText value="#{var.r_NO}"></h:outputText>
</h:column>
<h:column >
<h:outputText value="#{var.f_P_Name}"></h:outputText>
</h:column>
</h:dataTable>
</h:body>
</html>
I can see the message on the console and the page gets refreshed but no PDF report is come up the explorer screen
I have replaced the above PDF method with the code below, but in vain, the same result: no PDF report is coming up the explorer screen.
JasperPrint jasperPrint;
public void init() throws JRException{
JRBeanCollectionDataSource beanCollectionDataSource=new JRBeanCollectionDataSource(refugee);
String reportPath= "e:\\Rita.jasper";
jasperPrint=JasperFillManager.fillReport(reportPath, new HashMap(),beanCollectionDataSource);
}
public void PDF(ActionEvent actionEvent) throws JRException, IOException{
init();
HttpServletResponse httpServletResponse=(HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
// httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
FacesContext.getCurrentInstance().getExternalContext().setResponseContentType("‌​application/pdf");
ServletOutputStream servletOutputStream=httpServletResponse.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
System.out.println("All done the report is done");
servletOutputStream.flush();
servletOutputStream.close();
FacesContext.getCurrentInstance().responseComplete();
}
the code is correct, and there is nothing wrong with it.
the problem was some kind of security issue.
I faced the above problem when the report was in a full access folder to all users.
put when I put both of the requested xhtml and the report in a secured folder, everything went OK.
I don't know why!! but that was the case with me.
hoping others will make use of this.
thx.
<p:commandButton value = "PDF" actionListener="#{testReport.PDF}" ajax="false" type="submit"></p:commandButton>
you cant use ajax when calling jasperReports

WCF ProtocolException receiving html

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