web api though Method Not Allowed - asp.net-web-api

i have got the bellow simple api
public class ProductRepository : IProductPrpository
{
#region IProductPrpository Members
public IEnumerable<Product> GetAll(string ProductOption)
{
return Utility.GetDiscountItems(ProductOption);
}
public Product GetProduct(string Id)
{
return Utility.GetProduct(Id);
}
public String PostBag(Bag bagofItem)
{
return Utility.PostBagDiscountedItem(bagofItem);
}
#endregion
}
it is working fine when i call GetProduct & GetProduct but when post for PostBag it through the Method Not Allowed -
http://localhost:54460/api/products?PostBag="
error
please help
there is my client side script which post data to PostBag Api
#model List<MultiBuy.Models.Product>
#{
ViewBag.Title = "Index";
}
<h2>Items in the bag</h2>
<table>
<tr>
<th> Item_number_option </th>
<th> Option_number </th>
<th> Price </th>
<th> PublicationCode </th>
<th> Quantity </th>
</tr>
#foreach (var item in Model)
{
<tr>
<td> #item.ItemNumber</td>
<td> #item.Option</td>
<td> #item.Price</td>
<td> #item.PublicationCode</td>
<td> #item.Quantity</td>
</tr>
}
</table>
<div>
<ul id="products" />
<input type="button" value="Search" onclick="find();" />
</div>
#section scripts {
<script>
function find() {
var dataJSON = '#Model';
$.ajax({
type: 'POST',
url: 'http://locallhost:54460/api/products?PostBag=',
data: JSON.stringify(dataJSON),
contentType: 'application/json; charset=utf-8',
dataType: 'json'
}).done(function (data) {
$('#products').text(data)
});
};
</script>
}
appreciate all your help

You can not make a post in the same way you do the get, Get you can put parameters in your url, but Post you canĀ“t.
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/

Related

Net Core- add data to different model

I am pulling the extra materials on the order page in my project. Since the model on this page is product, I need to run a cart class to add to cart. But I don't know how to do this with asp-for. How can I add data for class cart because the model on the page is product?
#if (product.ProductExtras.Any())
{
<h5>Ekstra Malzemeler</h5>
<ul class="clearfix">
#foreach (var extra in product.ProductExtras)
{
<li>
<label class="container_check">
#extra.Extra.Name<span>+ #extra.Extra.Price.ToString("c2")</span>
<input type="checkbox">
<span class="checkmark"></span>
</label>
</li>
}
</ul>
}
Include your cart class and product class in a single class, and use this class in the view, you can access the data of both the cart class and the product class.
Like this:
public class ViewModel
{
//Choose the data type depending on your needs
public List<cart> cart { get; set; }
public List<product> product { get; set; }
}
For more details you can refer to this link.
Update:
I try to send a post request with the state of the checkbox, maybe that's what you mean.
Controller:
[HttpGet]
public IActionResult Test()
{
ViewModel viewmodel = new ViewModel();
viewmodel.product = new List<Product>();
viewmodel.product.Add(new Product() {Id =1,Name="Product1" });
viewmodel.product.Add(new Product() { Id = 2, Name = "Product2" });
viewmodel.product.Add(new Product() { Id = 3, Name = "Product3" });
return View(viewmodel);
}
[HttpPost]
public JsonResult Test([FromBody]ViewModel viewmodel)
{
//your own processing logic
return Json(viewmodel);
}
View:
#model _2022080202.Models.ViewModel
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.product[0].Id)
</th>
<th>
#Html.DisplayNameFor(model => model.product[0].Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.product) {
<tr>
<td name = "Id">#Html.DisplayFor(modelItem => item.Id)</td>
<td name = "Name">#Html.DisplayFor(modelItem => item.Name)</td>
<td><input type="checkbox" value="#item.Id" /></td>
</tr>
}
</tbody>
</table>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script>
$('input[type=checkbox]').change(function() {
if ($(this).is(":checked")) {
var id = $(this).val(); //The value bound in the checkbox
var row = $(this).parent("td").parent("tr");
ProductId = row.find("[name='Id']").text();
ProductName = row.find("[name = 'Name']").text();
var data = { ProductId: parseInt(ProductId), ProductName: ProductName };
var cart = new Array();
cart.push(data);
var viewmodel = { cart: cart};
$.ajax({
type: "post",
url: '/Home/Test',
data: JSON.stringify(viewmodel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result) {
//your own processing logic
},
error: function(error) { }
});
}
});
</script>
I send all the data out, you can just send an ID if you want and then do the following in the controller.
Test Result:

ajax request asp.net mvc pass id value from ajax request to controller

<h2>GetAllProducts</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Genre)
</th>
<th>
#Html.DisplayNameFor(model => model.AgeId)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
#Html.DisplayFor(modelItem => item.AgeId)
</td>
<td> <button type="button" data-id="#item.Id"
class="productIdButton">AddProductToBasket</button></td>
</tr>
}
#section scripts {
<script type="text/javascript">
$("button").click(function () {
//returns all the product ids
//want to return the selected id of the button clicked
// var h = ($(this).data("id"));
var h= ($(this).attr("data-id"));
var productId = (h.Id);
var s = productId;
//alert(productId);
$.ajax({
url: "/api/BasketAPI/AddProductToBasket/",
type: "POST",
data: { id: productId },
contentType: false,
cache: false,
processData: false,
});
});
</script>
}
I am trying to pass the data-id="#item.Id" value found in the view (JQuery) to the controller and use this value to compare to the Id of a class. I am not sure to get the id value from the ajax request.
[Route("api/BasketAPI/AddProductToBasket/")]
[HttpPost]
public void AddProductToBasket(int id)
{
var returnAllProductIds = _productService.GetProductsById().Where(X=>X.Id==id).Select(x=>x.Id).FirstOrDefault();
At the moment the id from the ajax request (the id is the product id assigned to a button. Each button has a product id assigned to it) is not being passed to the controller. I want the id in the parameter of the method in the controller to be set to the id from the ajax request. At the moment this is not being set.
Please try this.
CSHTML Pages
<h2>GetAllProducts</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Genre)
</th>
<th>
#Html.DisplayNameFor(model => model.AgeId)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
#Html.DisplayFor(modelItem => item.AgeId)
</td>
<td> <button type="button" onclick="AddProductToBasket(#item.Id)" data-id="#item.Id"
class="productIdButton">AddProductToBasket</button></td>
</tr>
}
JavaScript Code
#section scripts {
<script type="text/javascript">
function AddProductToBasket(productid)
{
try
{
$.ajax({
url: "/api/BasketAPI/AddProductToBasket",
type: "POST",
data: { id: productid },
success: function(oData){
alert(oData);
},
error:function(error)
{
alert(error);
}
});
}
catch(e)
{
alert(e.message);
}
}
</script>
}
Controller Action
[Route("api/BasketAPI/AddProductToBasket/")]
[HttpPost]
public int AddProductToBasket(int id)
{
var returnProductId = _productService.GetProductsById().Where(X=>X.Id==id).Select(x=>x.Id).FirstOrDefault();
return returnProductId;
}

spring mvc return modelandview after ajax call

in my form I have table to show some of customer data.user can click on row to see all of customer data.
<div class="container">
<table class="table table-bordered" style="direction: rtl">
<thead>
<tr>
<th style="text-align: center">customer name</th>
<th style="text-align: center">customer ID</th>
</tr>
</thead>
<tbody>
<c:forEach items="${customers}" var="customer" varStatus="loop">
<tr onclick="retrieveCustomer('${loop.index}')">
<td id="id-${loop.index}">${customer.customerId}</td>
<td>${customer.customerName}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<script>
function retrieveCustomer(id) {
debugger;
$.ajax({
url: "<%=request.getContextPath()%>/show_selected_customer",
data: {customerId: $('#id-' + id).text()},
type: "GET",
success: function (response) {
},
error: function (xhr, status, error) {
alert(error);
}
});
};
</script>
and in my controller:
#RequestMapping(value = "/show_selected_customer", method = RequestMethod.GET)
public ModelAndView showSelectedCustomer(#RequestParam("customerId") String customerId) {
Map<String, Object> model = new HashMap<>();
Customer customer = coreService.getCustomer(customerId);
model.put("customer", customer);
return new ModelAndView("showCustomerData", model);
}
tiles:
<definition name="showCustomerData" extends="base.definition">
<put-attribute name="title" value="customer data"/>
<put-attribute name="content" value="/WEB-INF/jsp/show_customer_data.jsp"/>
</definition>
until now every thing work correctly.
my problem is, it doesn't show show_customers.jsp page,and even I have no error in my log.
what is my problem,Is because of ajax call? I did`t use #responsebody and want to show customers.jsp page with return modelandview. thank you
Use the response body annotation and convert your entity to JSON and return it instead.

Ajax loaded submit form not working

I am using Ajax to replace a part of my page with a partial view containing multiple submit forms. This normally works when I use a normal Html.BeginForm and reload the entire page (the submit forms loaded work). However, when using Ajax to load the submit form, they display normally on the page but are not working.
I have looked around for information, but the information I have found mainly concerns submitting form through Ajax call, not loading submit forms.
This is the main View containing the javascript.
#model List<SrrManager.Models.User>
#{
ViewBag.Title = "Create";
}
<script>
$(function () {
$('Body').keypress(function (e) {
if (e.which == 13) {
$('#nomButton').trigger('click');
}
});
$('#nomButton').keyup(function (e) {
if (e.which == 13) {
$('#nomButton').trigger('click');
}
});/*
$('#prenomButton').keypress(function (e) {
if (e.which == 13) {
$('#nomButton').trigger('click');
}
});*/
$("#nomButton").on('click', function () {
var givenName = $("#prenomBox").val();
var nom = $("#nomBox").val();
$.ajax({
url: '#Url.Action("Create", "ManageUser")', //+ "?firstname=" + givenName + "&lastname=" + lastname,
type: 'GET',
data: { prenom: givenName, nomFamille: nom },
success: function (result) {
$('#liste-user').replaceWith(result);
}
});
});
});
</script>
<body>
<h2>Add an user</h2>
<p>
<label class="label-form">Prenom :</label>#Html.TextBox("prenomBox")
<br />
<label class="label-form">Nom :</label> #Html.TextBox("nomBox")
<br />
<input type="button" value="Filter" id="nomButton" />
</p>
#Html.Partial("_Create", Model)
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</body>
The _Create PartialView is as follow :
#model List<SrrManager.Models.User>
<div id="liste-user">
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email
</th>
<th>
Admin
</th>
<th></th>
</tr>
#foreach(var item in Model)
{
<tr>
<td>
#item.Name
</td>
<td>
#item.LastName
</td>
<td>
#item.email
</td>
#Html.Partial("__create", item)
</tr>
}
</table>
</div>
The last PartialView is used to create the submit form. The model is not a List but only User, and it is included once in each loop :
#model SrrManager.Models.User
#using(Html.BeginForm()){
<fieldset>
<legend>User</legend>
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(x => x.Name)
#Html.HiddenFor(x => x.LastName)
#Html.HiddenFor(x => x.email)
#Html.HiddenFor(x => x.account)
<td>
#Html.EditorFor(x => x.IsAdmin)
</td>
<td>
<input type="submit" value="save" />
</td>
</fieldset>
}
The list of user and the submit form is displayed normally using Ajax call or synchronous JQuery call when clicking on the Filter button, and the controller method is called as intended. However, the buttons work when loaded with synchronous JQuery calls, but not when loaded through Ajax.
The controller method is :
public ActionResult Create(string prenom ="", string nomFamille ="")
{
List<User> listeUser = new List<User>();
if (prenom.Equals("") && nomFamille.Equals(""))
{
}
else if (prenom.Equals(""))
{
string search = "*" + nomFamille + "*";
listeUser = SearchDirectory(search, 1);
}
else if (nomFamille.Equals(""))
{
string search = "*" + prenom + "*";
listeUser = SearchDirectory(search, 2);
}
else
{
string search = "*" + prenom + "*" + nomFamille + "*";
listeUser = SearchDirectory(search, 3);
}
if (Request.IsAjaxRequest())
{
return PartialView("_Create", listeUser);
}
return View(listeUser);
}
I am a beginner using Ajax, and I am at lost as to why it does not work. If any one has any lead, it would be very appreciated.
Try adding a jQuery handler for form submits.
$('form').submit(function () {
var givenName = $("#prenomBox").val();
var nom = $("#nomBox").val();
$.ajax({
url: '#Url.Action("Create", "ManageUser")', //+ "?firstname=" + givenName + "&lastname=" + lastname,
type: 'GET',
data: { prenom: givenName, nomFamille: nom },
success: function (result) {
$('#liste-user').html(result);
}
});
});

MVC 3 - Entity Framework - Post data from ajax-invoked Partial View

I have a problem with the binding of a complex model from a View that has updatable content, first things first, entites:
public partial class Diagnosis
{
public Diagnosis()
{
this.DiagZones = new HashSet<DiagZone>();
...
}
public int diagnosisid { get; set; }
public int playerid { get; set; }
public int userid { get; set; }
...
public virtual ICollection<DiagZone> DiagZones { get; set; }
}
My DiagZones Collection is the intermediate table between Diagnosis and Zones but it exist in my Model cause has more fields than the id's.
I have a Select control where you can select and unselect the Zones, when onchange fires, I Get a Partial View with an ajax call.
The code:
EditDiagnosis.cshtml
#model Gfire.Models.DiagnosisViewModel
<h2>
#ViewBag.playername</h2>
#using (Html.BeginForm("EditDiagnosis", "Diagnosis", FormMethod.Post))
{
#Html.HiddenFor(d => d.Diagnosis.diagnosisid)
<table>
...
</table>
<table>
<tr>
<td>
Zones:
</td>
<td>
#Html.ListBoxFor(d => d.SelectedZones, new SelectList(Model.Zones, "zoneid", "description"), new
{
style = "width:305px;",
onchange = "QualityMovement(this);",
id = "lbZone",
#class = "chzn-select"
})
</td>
<td>
...
</td>
</tr>
</table>
<div id="qualitymovement">
#Html.Partial("_QualityMovement", Model.Diagnosis.DiagZones)
</div>
<div>
<input type="submit" value="Save" />
&nbsp | &nbsp #Html.ActionLink("Cancel", "IndexDiagnosisPlayer", new { playerid = ViewBag.playerid })
</div>
}
Partial View (_QualityMovement.cshtml):
#model List<Gfire.Domain.Entities.Diagnosis.DiagZone>
#if (Model.Count() != 0)
{
<table>
#foreach (var dz in Model)
{
<tr>
<tr>
<td>
Flex:
</td>
<td>
#Html.TextBoxFor(d => dz.flex))
</td>
</tr>
</tr>
}
</table>
}
The Ajax.Get call:
<script type="text/javascript" language="javascript">
function JointBalance(item) {
...
$.ajax({
url: '#Url.Action("GetJointBalances", "Diagnosis")',
data: arrayToParamObject('zonesid', items),
contentType: "application/json; charset=utf-8",
success: function (data) {
// Successful requests get here
$("#jointbalance").html(data);
$("#jointbalance").fadeIn('slow');
},
type: "GET",
datatype: "json"
});
...
}
</script>
In server I have a Method that initialize a new list of DiagZones and update correctly the EditView.cshtml.
The problem comes when I try to Submit the complete Diagnosis object with all the fields and the list of DiagZones but my method:
[HttpPost]
public ActionResult EditDiagnosis(DiagnosisViewModel DiagnosisViewModel)
{
if (ModelState.IsValid)
{
// Save the model
...
return RedirectToAction("IndexDiagnosisPlayer", new { playerid = SessionHelper.Player.playerid });
}
else
{
return View("EditDiagnosis", new { diagnosisid = DiagnosisViewModel.diagnosisid });
}
}
My Model has empty the DiagnosisViewModel.DiagZones list.
I've tried to use EditorFor, pass the complete model to the partial View, add several forms... but it was useless, how can I bind that list to my model?
Thanks in advance.
UPDATE
Here is what the server side action is expecting:
[HttpGet]
public ActionResult GetJointBalances(int[] zonesid) { ... }
GET ajax request data looks like:
Request URL:http://localhost/Gfire.WebUI/Diagnosis/GetQualityMovement?zonesid=47
Request Method:GET
Status Code:200 OK
Request Headersview source
...
Connection:keep-alive
Content-Type:application/json; charset=utf-8
...
Referer:http://localhost/Gfire.WebUI/Diagnosis/EditDiagnosis?diagnosisid=0&playerid=23
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22
X-Requested-With:XMLHttpRequest
Query String Parametersview sourceview URL encoded
zonesid:47
I found a temporal solution, not the best of course, but I thougth it would help to understand what I was trying to do and how to solve this.
The problem, as Justin said, was binding the list<DiagZones> to main model, the Diagnosis object, following the posts of this:
ASP.Net MVC4 bind a "create view" to a model that contains List
I understand a little bit of the binding functionality, with that in mind I code my new PartialView _QualityMovement.cshtml:
#model List
#if (Model.Count() != 0)
{
<table>
#foreach (var dz in Model)
{
<tr>
<tr>
<td>
Flex:
</td>
<td>
Html.TextBox("Diagnosis.DiagZones[" + i + "].ext", Model[i].ext)
</td>
</tr>
</tr>
}
</table>
}
It's a bad solution but at least I had my Model binded in server side.
The problem is the abstraction made by the entity framework to my entities, as an ICollection so I cannot iterate as a List and found myself "casting" everywhere.
I suppose a better approach should be a CustomBinder to retrieve the data in the Request or type it in a neater and understandable way.
Thanks Justin for all the help you gave me.

Resources