I'm implementing asp.net core 3.1. I want to send a "year" value as the input parameter of my method controller. when I debug my project I can see that "year" has a value in ajax call but the argument of year in the controller method is null. I appreciate if anyone can suggest me to solve the issue.
Here is the related code in razor view:
$('#exampleModal').modal('#ViewBag.ModalState');
$('#exampleModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);
var year = $("input[name='Year']:checked").val();
console.log('myyear:' + year);
//My problem is here, when sending year value to the
//ProductDetails method
$.get('#Url.Action("ProductDetails", "Home")/' + {year: year}, function (data) {
$.each(data, function (index, value) {
var markup = "<tr><td>" + value.apName +"</td></tr>";
$("#classTable").append(markup);
})
});
});
Home controller method:
public IList<ApiApplicantDTO> ProductDetails(string year)
{
Console.WriteLine("year:" + year);
}
Be sure the year has value.And your url is incorrect,you need to change like below:
var year = "2019";
$.get('#Url.Action("ProductDetails", "Home")?year=' + year, function (data) {
//...
});
Result:
Related
I'm using this tutorial on www.asp.net to learn about .net web api 2. I added a second lookup on the index page:
<div>
<h2>Search by Category</h2>
<input type="text" id="catId" size="5" />
<input type="button" value="Search" onclick="findCat();" />
<p id="categories" />
</div>
and modified the existing javascript to add a lookup for category. The idea being to enter a category (eg, Toys) and the API would return the products in that category:
function findCat() {
var uri = 'api/GetCategory';
var cid = $('#catId').val();
$.getJSON(uri + '/' + cid)
.done(function (data) {
$('#categories').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#categories').text('Error: ' + err);
});
}
I added a method in the controller class that (I thought) would handle this:
public IHttpActionResult GetCategory(string Category)
{
var product = products.FirstOrDefault((c) => c.Category == Category);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
When I run a search on category it is unable to find the products in that category. What am I missing (besides about 6 months of study! I know!)
Thank you
By reading your comments you tell us that you only have the defaultApi in the route configuration, that would be:
api/{controller}/{id}
You also tell us that you get a NotFound error, I guess that this happens because it cannot find the controller/method.
By reading your script you are actually doing this:
function findCat() { //actual request URL:
var uri = 'api/GetCategory'; //api/GetCategory/
var cid = $('#catId').val();
$.getJSON(uri + '/' + cid) //api/GetCategory/1
You use GetCategory as controller, which is not correct, your controller is the class name + Controller. So in your case probably ProductController
Secondly, WebApi doesn't look for method names, it only looks for a distinction in HTTP-request type and parameters. So if you have two methods with different names but they are both a GET request-type and both have a int as parameter, Web Api doesn't know which one to use.
Your api link should be: api/Product?category="blabla"
What you can do is add additional routing to a method, the default AccountController gives good examples for this.
In your case:
[RoutePrefix("api/Product")] //you have to specify this if you would like to do custom routing.
public class ProductController : ApiController
{
//GET: api/Product/Category?category="blabla"
[HttpGet]
[Route("Category")] //route constraint
public IHttpActionResult GetCategory(string category)
{
var product = products.FirstOrDefault((c) => c.Category == Category);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
So now you can update your script, your script is made for getting something by Id, while you want this to be by string, you can probably figure it out. Something like this I guess (not that good with javascript yet.
function findCat() {
var uri = 'api/Product/Category';
var cid = $('#catName').valueOf();
$.getJSON(uri + '?category=' + cid)
.done(function (data) {
$('#categories').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#categories').text('Error: ' + err);
});
}
Optional: If you like to have you link like this: api/Product/Category/blabla you have to add this:
[Route("Category/{category}")]
Web API Routing: article
Attribute routing and constraints: article
Present set up -
url: configMap.sitePath + "api/Quiz/" + quizResponse.quizId,
data: JSON.stringify(quizResponse),
success: function (data) {
// Display the data on UI
}
the above post is to a .NET api controller which returns quizResponse.
[ValidateModelState, HttpPost]
public HttpResponseMessage Post(int id, QuizResponse value)
Now as per a new requirement , Once the api has the response I should redirect to another page(a MVC controller and then view). How do I achieve this -
public ActionResult ScptResult()
{
return View();
}
I also thought of redirect after ajax success but not sure if its a correct way.
Also, How do I pass data to the scptresult controller method after post?
In the success function of your JQuery, redirect the page to your MVC page:
window.location = '{controller}/{action}/{quizid}';
Assuming you use the standard MVC routing, and assuming you change your ScptResult function to accept a parameter, so you can pass data to it.
public ActionResult ScptResult(int quizid)
{
return View();
}
Use in java-script after complete your work in success method or anywhere
window.location = '#Url.Action("ScptResult", "YourControllerName")';
I should warn, I'm not very familiar with ajax responses but hopefully this gets close.
API
[ValidateModelState, HttpPost]
public HttpResponseMessage Post(int id, QuizResponse value)
{
//Other stuff...
var redirect = string.Format(#"/controller/ScptResult/{0}", id);
return new HttpResponseMessage()
{
Content = new StringContent(redirect)
};
}
Javascript
url: configMap.sitePath + "api/Quiz/" + quizResponse.quizId,
data: JSON.stringify(quizResponse),
success: function (data) {
window.location = data;
}
Controller
// This follows the default route.
// "/{controller}/{action}/{id}" where id is optional.
// window.location = "/ControllerName/ScptResult/OtherData"
public ActionResult ScptResult(string id)
{
return View();
}
I need to post the from Property name and values to the Mvc web api Controller without using model Property because i need to use same Ajax call (method) for different Forms also.
Using this Ajax Method i need to Post values i am Posting values but how i need to receive those values in Controller
Example Of Posting:
function Add(){var model = $("#Enquiry").serialize();
$.ajax({
url: 'http://localhost:60533/api/Enquiry',
type: 'POST',
dataType: 'json',
data: model,
success: function (data) {
console.log(data);
}
});}
Using Below Controller how can i Receive model Values without using C# (Get set Property) Model?
public HttpResponseMessage Post(object model)
{
var Result = (new EnquiryDtl().Post(model));
return Request.CreateResponse(HttpStatusCode.OK);
}
This is how I do it...
var dataArray = $("#Enquiry").serializeArray(),
var model = {};
for (i = 0; i < dataArray.length; i++)
model[dataArray[i].name] = dataArray[i].value;
var url = 'http://localhost:60533/api/Enquiry';
$.ajax({
url: url, type: "POST", dataType: 'json',
data: JSON.stringify(model), contentType: 'application/json',
success: function (data) {
....
}
});
and in the controller:
public HttpResponseMessage Post(Dictionary<string, string> fields)
{
...
}
As you've undoubtedly discovered, object doesn't have a lot of useful properties on it. This is where using a model really comes in handy. For example, let's say you're posting an integer called ID and a string called Name, then this simple object would be populated accordingly:
public class MyModel
{
public int ID { get; set; }
public string Name { get; set; }
}
And you'd use it in your method:
public HttpResponseMessage Post(MyModel model)
{
// here you can access model.ID and model.Name
}
If you really don't want to use a model, you can include the values directly in the method signature:
public HttpResponseMessage Post(int id, string name)
{
// here you can access id and name
}
Of course, using a model brings a lot more advantages. Specifically, you can add business logic to the model (since business logic belongs on the models and not on the controllers). Additional benefits include being able to modify the structure without having to modify all consuming code. (For example, if you have multiple methods which accept this structure then you'd have to change all of them to add a new field. With a model, you'd only have to change that one model.)
Finally I got the Solution To send the Key Pair values to the Mvc Controller using Ajax and web Api.
Without using C# Model get set property
My Script:
function Enquiry() {
var dataArray = $("#formMember").serializeArray(),
model = {};
for (i = 0; i < dataArray.length; i++) {
var Name = "["+i+"]"+""+"."+"Key";
var Value = "[" + i + "]" + "" + "." + "Value"
model[Name] = dataArray[i].name;
model[Value] = dataArray[i].value;
}
$.ajax({
url: 'http://localhost:60533/api/Enquiry',
type: 'POST',
data: model,
success: function (data) {
alert(data);
}
});}
C# Code
I am reciving Those values Instead of Object I am Using Dictionary
public HttpResponseMessage Post(Dictionary<string, string> dictionary)
{
var Result = (new EnquiryDtl().Post(dictionary));
return Request.CreateResponse(HttpStatusCode.OK);
}
Im new to Web Development and its principles so apologies if my question does not seem clear.
Story So Far......
Im writing an Open Source application to learn ASP.NET MVC3. Now im at the stage where im creating my CRUD controller to allow me to create some new Types. Now I have created a SiteAdmin Controller which holds my Dashboard, with has a View. The View will contain tabs . I have been learning how to handle tabs using the following blog post and JQuery UI
http://ericdotnet.wordpress.com/2009/03/17/jquery-ui-tabs-and-aspnet-mvc/
I have decided to use the AJAX example to handle my tabs, whereby I pass an index parameter to a Controller Action Method called AjaxGetTab . This method (as per the blog post) returns a Partial View for the required Type. Within the Partial View there are Create Controller Action Method's, for e.g. CreateTransactionType (HttpPost), which create new records.
"Stop the waffling what is the problem"
The problem is that my list within the tab on the view doesn't refresh after the Create method is finished. This problem only exists in IE9 (Only IE i have tested) but Chrome and Firefox work, i.e. the list refreshes.
I have checked the Database records exists.
My code is here:
JQuery in Dashboard.cshtml:
<script type="text/javascript">
$(document).ready(function() {
$("#tabs").tabs();
getContentTab (1);
});
function getContentTab(index) {
var url='#Url.Content("~/SiteAdmin/AjaxGetTab")/' + index;
var targetDiv = "#tabs-" + index;
var ajaxLoading = "<img id='ajax-loader' src='#Url.Content("~/Content")/ajax-loader.gif' align='left' height='28' width='28'>";
$(targetDiv).html("<p>" + ajaxLoading + " Loading...</p>");
$.get(url,null, function(result) {
$(targetDiv).html(result);
});
}
SiteAdminController AjaxGetTab Method:
/// <summary>
/// AJAX action method to obtain the correct Tab to use.
/// </summary>
/// <param name="index">Tab number</param>
/// <returns>Partial View</returns>
public ActionResult AjaxGetTab(int id)
{
string partialViewName = string.Empty;
object model = null;
//--Decide which view and model to pass back.
switch (id)
{
case 1:
partialViewName = "_TransactionType";
model = db.TransactionTypes.ToList();
break;
case 2:
partialViewName = "_DirectionType";
model = db.DirectionTypes.ToList();
break;
case 3:
partialViewName = "_UserType";
model = db.UserTypes.ToList();
break;
case 4:
partialViewName = "_CurrencyType";
model = db.CurrencyTypes.ToList();
break;
case 5:
partialViewName = "_tabError";
break;
}
return PartialView(partialViewName,model);
}
}
SiteAdminController CreateTransactionType Method:
[HttpPost]
public ActionResult CreateTransactionType(TransactionType model)
{
try
{
// TODO: Add insert logic here
if (ModelState.IsValid)
{
model.id = Guid.NewGuid();
model.RecordStatus = " ";
model.CreatedDate = DateTime.Now;
db.TransactionTypes.AddObject(model);
db.SaveChanges();
}
return RedirectToAction("Dashboard");
}
catch
{
return PartialView("_tabError");
}
}
Replace your
$.get(url,null, function(result) {
$(targetDiv).html(result);
});
By:
$.ajax({
type: 'get',
url: url,
cache: false,
success: function(result) {
$(targetDiv).html(result);
}
});
The problem is that IE caches ajax requests, so by setting cache: false in the settings it should work.
I have validated the JSON response from my C# Webmethod, so I don't believe that's the problem.
Am trying to parse the result using simple jQuery $.ajax, but for whatever reason I can't get the method to correctly fire and parse the result, also incidentally can't seem to get the function to fire the result. Are their any limits on the size of the JSON object that can be returned.
I also removed this code from inside a "Site.Master" page because it would always refresh when I hit the simple button. Do tags work correctly with jQuery elements like the button input I'm grabbing from the DOM?
function ajax() {
//var myData = { qtype: "ProductName", query: "xbox" };
var myData = { "request": { qtype: "ProductName", query: "xbox"} };
$.ajax({
type: "POST",
url: "/webservice/WebService.asmx/updateProductsList",
data: {InputData:$.toJSON(myData)},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// var msg = {__type: "Testportal.outputData", id: "li1234", message: "it's work!", myInt:101}
alert("message=" + msg.d.ProductName + ", id=" + msg.d.Brand);
},
error: function (res, status) {
if (status === "error") {
// errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
var errorMessage = $.parseJSON(res.responseText);
alert(errorMessage.Message);
}
}
});
}
And the page:
<asp:Button ID="Button1" runat="server" OnClientClick="ajax();" Text="Button" />
And the Serverside Webmethod:
public class WebService : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public OutputData updateProductsList(InputData request)
{
OutputData result = new OutputData();
var db = new App_Data.eCostDataContext();
var q = from c in db.eCosts
select c;
if (!string.IsNullOrEmpty(request.qtype) && !string.IsNullOrEmpty(request.query))
{
q = q.Like(request.qtype, request.query);
}
//q = q.Skip((page - 1) * rp).Take(rp);
result.products = q.ToList();
searchObject search = new searchObject();
foreach (App_Data.eCost product in result.products)
{
/* create new item list */
searchResult elements = new searchResult()
{
id = product.ProductID,
elements = GetPropertyList(product)
};
search.items.Add(elements);
}
return result;
}
And helper classes:
public class OutputData
{
public string id { get; set; }
public List<App_Data.eCost> products { get; set; }
}
public class InputData
{
public string qtype { get; set; }
public string query { get; set; }
}
One problem you may be having is that you aren't doing anything to prevent the button from submitting the form and executing a full postback/reload at the same time you're starting your $.ajax() callback.
I'd suggest wiring this up unobtrusively instead of using the OnClientClick property, like this:
$(document).ready(function() {
// May need to use $('<%= Button1.ClientID %>') if your Button is
// inside a naming container, such as a master page.
$('#Button1').click(function(evt) {
// This stops the form submission.
evt.preventDefault();
$.ajax({
// Your $.ajax() code here.
});
});
});
I also agree with Oleg that you should use json2.js for your JSON stringifying and parsing. In newer browsers, that will fall back to the browsers' native implementations of those methods, which is much faster and makes the parsing safer.
Update:
To answer your question about the data, no that doesn't look quite right.
What you want to ultimately send to the server is this (sans formatting):
{"request":{"gtype":"ProductName","query":"xbox"}}
To accomplish that, you want something like this:
var req = { request : { qtype: "ProductName", query: "xbox" }};
$.ajax({
data: JSON.stringify(req),
// Remaining $.ajax() parameters
});
Keep in mind that request, qtype, and query must match your server-side structure with case-sensitive accuracy.
You can also be more verbose in defining the request object (which I prefer, personally, to keep things clear and readable):
var req = { };
req.request = { };
req.request.qtype = "ProductName";
req.request.query = "xbox";
I've written a bit more about this here, if you're interested: http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/
What does your server side code method look like? Set a break point. Is it even being hit?
It should look something like:
[WebMethod, ScriptMethod]
public string updateProductsList(string qtype, string query)
{ // stuff
}
Also, your javascript data params do not look formatted correctly.
It seems to me that your problem is that you try to use manual JSON serialization. There are more direct way. You should just declare [ScriptMethod (ResponseFormat = ResponseFormat.Json)] or [ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] and return return direct an object instead of the string from the web method. On the client side (in JavaScript) I strictly recommend you to use JSON.stringify (from json2.js which can be downloaded from http://www.json.org/js.html) for the constructing of the data parameter of jQuery.ajax.
Look at Can I return JSON from an .asmx Web Service if the ContentType is not JSON? and How do I build a JSON object to send to an AJAX WebService? probably also in JQuery ajax call to httpget webmethod (c#) not working you have have an interest for more experiments.