This is my first web app project. I am using VS community, asp.net, bootstrap 4, C# and JS knockout for my view model, the server side data is coming from the company ERP SQL database using Entity Framework.
The idea is that the user receives a list of items to approve from the Company ERP system, which are loaded into the View Model. The View Model is structured as a JS Knockout observable array and that each item is a JS knockout item of observables (see full code below)
Once the user has processed the items as desired, I want the web app to post back the whole View Modal as a Json object and for the server Post Controller to take this Json object convert it to xml to send into a SQL stored procedure for insertion into the SQL database, from the SQL database the data will be handled and inserted into the ERP database
When I try to action the Post I get a 405 "Method Not Allowed"
> "tags": {
"ai.cloud.roleInstance": "[MYCOMPUTER].local",
"ai.operation.id": "c07680cd8c845240a9e3791018c39521",
"ai.operation.name": "POST ReqsTests",
"ai.location.ip": "::1",
"ai.internal.sdkVersion": "web:2.8.0-241",
"ai.internal.nodeName": "[MYCOMPUTER].local"
},
"data": {
"baseType": "RequestData",
"baseData": {
"ver": 2,
"id": "|c07680cd8c845240a9e3791018c39521.66f8d951_",
"name": "POST ReqsTests",
"duration": "00:00:00.0279394",
"success": false,
"responseCode": "405",
"url": "http://localhost:64234/api/ReqsTests/",
"properties": {
"DeveloperMode": "true",
"_MS.ProcessedByMetricExtractors": "(Name:'Requests', Ver:'1.1')"
}
}
}
}
I think that I am not receiving the Json Date from the client correctly. My thinking is because I am sending the whole model back, which is a Json list, which but My controller does not receiver a List rather a string.
Can any one explain how my controller should receive the client side data Here is my call to my Controller from the client and the server Post controller and full code listing is below
self.postAllReqs = function(self) {
self.error(''); // Clear error message
var data = ko.toJSON(self.Reqs); // convert to json
console.log(data);
ajaxHelper(reqsUri, 'POST', data).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
// POST: api/ReqsTests
public IHttpActionResult PostReqsTest(string json)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
try
{
//SQL store procedure
SqlParameter param1 = new SqlParameter("@XmlIn", doc);
db.Database.ExecuteSqlCommand("exec [CHC_Web].[TestWebHandShake],@XmlIn",
param1);
}
catch (Exception e)
{
string message = e.Message;
return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
return Ok();
}
Thanks
View Model Code
function ReqsTest(rt) {
rt = rt || {};
var self = this;
self.id = ko.observable(rt.ID || 0);
self.requisition = ko.observable(rt.Requisition || "");
self.reqnStatus = ko.observable(rt.ReqnStatus || "");
self.dateReqnRaised = ko.observable(rt.DateReqnRaised|| null);
self.reqnValue = ko.observable(rt.ReqnValue || null);
self.approvedValue = ko.observable(rt.ApprovedValue || null);
self.originator = ko.observable(rt.Originator || "");
self.origName = ko.observable(rt.OrigName || "");
self.origEmail = ko.observable(rt.OrigEmail || "");
self.line = ko.observable(rt.Line || 0.00);
self.indx = ko.observable(rt.INDX || 0);
self.dateReqnRaisedL = ko.observable(rt.DateReqnRaisedL || null);
self.reqStatus = ko.observable(rt.ReqStatus || "");
//self.reqBackground = ko.observable(rt.ReqBackground || "");
//Computed observables
self.reqBackground = ko.computed(function () {
// get variable
var status = self.reqStatus();
if (status == "A") { return "card-heading bg-success text-white"; }
else if (status == "D") { return "card heading bg-secondary"; }
else if (status == "R") { return "card heading bg-warning"; }
else if (status == "E") { return "card heading bg-danger"; }
else {
return "card-heading bg-primary text-white";
}
})
self.reqStatusLabel = ko.computed(function () {
// get variable
var status = self.reqStatus();
if (status == "A") { return "Approved"; }
else if (status == "D") { return "Declined - put on hold"; }
else if (status == "R") { return "Routing On"; }
else if (status == "E") { return "Erase On Syspro"; }
else {
return "Awaiting Approval";
}
})
self.approvalBtn = ko.computed(function () {
// get variable
var status = self.reqStatus();
if (status == "A") { return "css: button btn-secondary "; }
else {
return "btn btn-success ";
}
})
self.approvalBtnLbl = ko.computed(function () {
// get variable
var status = self.reqStatus();
if (status == "W") { return "Approve"; }
else {
return "UnApprove";
}
})
self.declineBtnLbl = ko.computed(function () {
// get variable
var status = self.reqStatus();
if (status == "D") { return "UnDecline"; }
else {
return "Decline";
}
})
self.deleteBtnLbl = ko.computed(function () {
// get variable
var status = self.reqStatus();
if (status == "E") { return "Restore"; }
else {
return "Erase";
}
})
// Functions
//show details alert
$(".btn").on("click", function () {
$(".alert").removeClass("in").show();
$(".alert").delay(200).addClass("in").fadeOut(2000);
});
}
function ReqsViewModel (){
var self = this;
self.Reqs = ko.observableArray([]);
self.error = ko.observable();
var reqsUri = '/api/ReqsTests/';
function ajaxHelper(uri, method, data) {
self.error(''); // Clear error message
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
function getAllReqs() {
ajaxHelper(reqsUri, 'GET').done(function (data) {
// Build the ReqsTest objects
var reqs = ko.utils.arrayMap(data, function (rt) {
return new ReqsTest(rt);
});
self.Reqs(reqs);
});
}
self.postAllReqs = function(self) {
self.error(''); // Clear error message
var data = ko.toJSON(self.Reqs); // convert to json
console.log(data);
ajaxHelper(reqsUri, 'POST', data).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
// Details
self.detail = ko.observable();
self.getReqDetail = function (item) {
//var url = reqsUri + item.indx();
//ajaxHelper(url, 'GET').done(function (data) {
// self.detail(data);
//}
//);
self.detail(item)
}
//Approval function
self.Approval = function (item) {
var status = item.reqStatus();
if (status == "W") { item.reqStatus("A"); }
else
{ item.reqStatus("W"); }
self.getReqDetail(item);
}
//Decline function
self.Decline = function (item) {
var status = item.reqStatus();
if (status == "D") { item.reqStatus("W"); }
else { item.reqStatus("D"); }
self.getReqDetail(item);
}
//Delete function
self.Delete = function (item) {
var status = item.reqStatus();
if (status == "E") { item.reqStatus("W"); }
else { item.reqStatus("E"); }
self.getReqDetail(item);
}
// Load the reqs - Take this out if you don't want it
getAllReqs();
}
ko.applyBindings(new ReqsViewModel());
Model Class
namespace POC_Reqs_v1.Models
{
using System;
using System.Collections.Generic;
public partial class ReqsTest
{
public string ID { get; set; }
public string Requisition { get; set; }
public string ReqnStatus { get; set; }
public Nullable<System.DateTime> DateReqnRaised { get; set; }
public Nullable<decimal> ReqnValue { get; set; }
public Nullable<decimal> ApprovedValue { get; set; }
public string Originator { get; set; }
public string OrigName { get; set; }
public string OrigEmail { get; set; }
public decimal Line { get; set; }
public long INDX { get; set; }
public string DateReqnRaisedL { get; set; }
public string ReqStatus { get; set; }
public string ReqBackground { get; set; }
}
}
Controller Code
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using System.Xml;
using Newtonsoft.Json;
using POC_Reqs_v1.Models;
namespace POC_Reqs_v1.Controllers
{
public class ReqsTestsController : ApiController
{
private ChamberlinWebEntities db = new ChamberlinWebEntities();
// GET: api/ReqsTests
public IQueryable<ReqsTest> GetReqsTests()
{
return db.ReqsTests;
}
// GET: api/ReqsTests/5
[ResponseType(typeof(ReqsTest))]
public async Task<IHttpActionResult> GetReqsTest(string id)
{
var ID = Convert.ToInt64(id);
ReqsTest reqsTest = await db.ReqsTests.FindAsync(ID);
if (reqsTest == null)
{
return NotFound();
}
return Ok(reqsTest);
}
// PUT: api/ReqsTests/5
[ResponseType(typeof(void))]
public async Task<IHttpActionResult> PutReqsTest(string id, ReqsTest reqsTest)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != reqsTest.ID)
{
return BadRequest();
}
db.Entry(reqsTest).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ReqsTestExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/ReqsTests
public IHttpActionResult PostReqsTest(string json)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
try
{
//SQL store procedure
SqlParameter param1 = new SqlParameter("@XmlIn", doc);
db.Database.ExecuteSqlCommand("exec [CHC_Web].[TestWebHandShake],@XmlIn",
param1);
}
catch (Exception e)
{
string message = e.Message;
return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
return Ok();
}
// DELETE: api/ReqsTests/5
[ResponseType(typeof(ReqsTest))]
public async Task<IHttpActionResult> DeleteReqsTest(string id)
{
ReqsTest reqsTest = await db.ReqsTests.FindAsync(id);
if (reqsTest == null)
{
return NotFound();
}
db.ReqsTests.Remove(reqsTest);
await db.SaveChangesAsync();
return Ok(reqsTest);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool ReqsTestExists(string id)
{
return db.ReqsTests.Count(e => e.ID == id) > 0;
}
}
}
For completeness here was my final solution: The main problem was the syntax error in the post controller, which did not create an error when compiled, the line that was incorrect was
// POST: api/ReqsTests
public IHttpActionResult PostReqsTest(string json)
The correct syntax was in the end
public async Task<IHttpActionResult> PostReqsTest(object json)
So the full controller code is was
// POST: api/ReqsTests
public async Task<IHttpActionResult> PostReqsTest(object json)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//convert the Json model to xml
XmlDocument doc = JsonConvert.DeserializeXmlNode(json.ToString());
try
{
//SQL store procedure
SqlParameter param1 = new SqlParameter("@XmlIn", doc.InnerXml);
db.Database.ExecuteSqlCommand("exec [CHC_Web].[TestWebHandShake] @XmlIn",
param1);
}
catch (Exception e)
{
string message = e.Message;
return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, message));
}
return ResponseMessage(Request.CreateResponse HttpStatusCode.OK,"Inserted to database")); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With