List<string> with Json asp.net mvc - c#

I've been trying to find an answer on google without any result. My question is how can I manipulate my Json data (List<string>) in my view? I'd like to show all the string returned in a div for example.
Here's where I'm currently stuck at:
CONTROLLER
[HttpPost]
public async Task<ActionResult> RetournerOP(int OF)
{
List<string> ops = new List<string>();
Task verif = Task.Run(() =>
{
try
{
connection.Open();
string sqlQuery = "SELECT Operation from ZZ where ordre = " + OF;
SqlCommand command = new SqlCommand(sqlQuery, connection);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
ops.Add(Convert.ToString(reader["Operation"]));
}
}
}
catch (Exception) { }
finally { connection.Close(); }
});
await verif;
return Json(ops);
}
VIEW
function retournerOp() {
$.ajax({
url: '#Url.Action("RetournerOp", "Home", new { area = "Ajout" })',
data: {OF: document.getElementById("NumOf").value},
type: 'POST',
dataType: 'JSON',
cache: false,
success: function (data) {
//How can I manipulate my data returned?
}
});
}

Your server action method is currently returning an array of strings. So in your ajax call's success callback, you may loop through them and use each item as needed ( like adding to your DOM). $.each method will be handy to loop.
For example, the below code loops through the array and wrap each item in a p tag and append the list of p tags to a div with id myDivId
success: function (data) {
var t = "<div>";
$.each(data,function(a, b) {
t += '<p>'+b+'</p>';
});
$("#myDivId").html(t);
}
If you want to render a more complex html markup, i would strongly advise creating an action method (if you cannot update the existing one because other code is already using it) which returns a partial view result instead of the json. So you will pass the list of strings to the partia view and the partial view will have the code to render the sophisticated markup you want to return.
return PartialView(ops);
and in the partial view,
#model List<string>
#foreach (var item in Model)
{
<p>#item</p>
}
Now since the response coming from the server call is the HTML markup you want, simply update the DOM with that as needed.
$.ajax({
url: '#Url.Action("RetournerOp", "Home", new { area = "Ajout" })',
data: {OF:6},
type: 'POST',
success: function (data) {
$("#myDivId").html(data);
}
});
Also as others mentioned in the comments, your server code is prone to SQL injection. You should never concatenate the user input directly to a SQL statement like that. Consider using Parameterized queries.

Related

How to pass data from a controller to view during a JQuery AJAX call in MVC?

In my view, I have an AJAX call which sends an id parameter to my controller. This bit works fine. In my controller, I plan to query the database with that id, pull out associated data and want to send this back to the AJAX call/view. This is the bit I am struggling with, as I am new to AJAX calls.
var chosenSchoolID = $("#SelectedSchoolId").val();
$.ajax({
url: "/Home/GetSchoolDetailsAJAX",
type: "POST",
data: {
schoolID: chosenSchoolID
},
dataType: "text",
success: function(data) {
if (data == "success") {
}
},
error: function(data) {
if (data == "failed")
alert("An error has occured!");
}
});
The above is my AJAX call, and this does hit my controller method. However in my controller, I want to now send back other string data and I am unsure on how to do this (just placeholder code currently)
[HttpPost]
public ActionResult GetSchoolDetailsAjax(string schoolID)
{
// query database using schoolID
// now we have other data such as:
string SchoolName = "";
string SchoolAddress = "";
string SchoolCity = "";
return null;
}
Must I declare variables in my Jquery and pass into the data parameter of the AJAX call in order for the values to be passed?
Many thanks in advance
The simplest way to do this is to return the entities retrieved from your database using return Json() from your controller.
Note that when retrieving data then a GET request should be made, not a POST. In addition the default MVC configuration should have the routes setup to allow you to provide the id of the required resource in the URL. As such, try this:
$.ajax({
url: "/Home/GetSchoolDetailsAJAX/" + $("#SelectedSchoolId").val(),
type: "get",
success: function(school) {
console.log(school);
},
error: function() {
alert("An error has occured!");
}
});
[HttpGet]
public ActionResult GetSchoolDetailsAjax(string id) {
var school = _yourDatabaseContext.Schools.Single(s => s.Id == id); // assuming EF
return Json(school);
}
If you'd like to test this without the database integration, amend the following line:
var school = new {
Id = id,
Name = "Hogwarts",
Address = "Street, City, Country"
};

How to pass an object to controller that contains an html string in .NetCore

I have an object that I want to pass to the controller. This object contains multiple strings that contains different sections of html code. My code worked for normal strings being passed, but once I tried adding html code, it failed to route anymore and I started getting 404s.
I tried changing the model to encode the string prior to passing it across however that failed completely. The following code works if the 3 strings contain no html code within. The sample strings are what I'm trying to get passed to my controller through the ajax call.
Javascript
var htmlString1 = '<div style="width: 100px;">Test html div 1</div>';
var htmlString2 = '<div style="width: 100px;">Test html div 2</div>';
var htmlString3 = '<div style="width: 100px;">Test html div 3</div>';
var htmlSectionContainer = {
htmlSection1: htmlString1,
htmlSection2: htmlString2,
htmlSection3: htmlString3
};
debugger;
$.ajax({
url: "#Url.Action("DisplayHtmlObjects", "Pages")",
method: "GET",
data: { "data": JSON.stringify(data) },
success: (response) => {
//do things
});
}
Model
public class HtmlSectionContainer
{
//Article ids for each of the pivot section intros.
public string htmlSection1{ get; set; }
public string htmlSection2 { get; set; }
public string htmlSection3 { get; set; }
}
Controller action
[HttpGet]
public IActionResult DisplayHtmlObjects(string data)
{
HtmlSectionContainer section = new HtmlSectionContainer();
if (data != null)
{
section = JsonConvert.DeserializeObject<HtmlSectionContainer>(data);
}
return View(section);
}
The actual result of the above html strings is a 404.
Trying to encode the individual strings inside the object still gives me a 404.
var htmlSectionContainer = {
htmlSection1: encodeURI(htmlString1),
htmlSection2: encodeURI(htmlString2),
htmlSection3: encodeURI(htmlString3)
};
Right now I'm not hitting the breakpoint at all inside the controller action. I should be able to hit the breakpoint, and in the data parameter see each of the 3 strings.
Also minor improvement, if possible, I'd prefer to have HtmlSectionContainer data as the parameter instead of string data in the controller action it data was null when I tried to do that.
There is a syntax error in this JS Code, i think it's getting the URL wrong
$.ajax({
url: "#Url.Action("DisplayHtmlObjects", "Pages"),
method: "GET",
data: { "data": JSON.stringify(data) },
success: (response) => {
//do things
});
}
It should be like this, you missed closing " it should be like this
$.ajax({
url: '#Url.Action("DisplayHtmlObjects", "Pages")',
method: "GET",
data: { "data": JSON.stringify(data) },
success: (response) => {
//do things
});
}
I have replaces the double quotation marks " to single quotation marks ' in this line
'#Url.Action("DisplayHtmlObjects", "Pages")'
Because inside the string you're using double quotations and that'll lead JS to think that the string has ended here.
And also you're passing data object JSON.stringify(data) but i don't see where that variable been declared and populated, you're using the variable htmlSectionContainer above to set the HTML data. so i guess it should be like this.
$.ajax({
url: '#Url.Action("DisplayHtmlObjects", "Pages")',
method: "GET",
data: { "data": JSON.stringify(htmlSectionContainer) },
success: (response) => {
//do things
});
}

Performing a SQL query in controller action ASP.NET Core

I'm having a hard time performing query's in ASP.NET Core.
What I need to do: I have a index view with all sort of property's, next to the rows in my view I have a button, on button click it must perform a controller action, that controller action exists out of: A query which inserts the specific row into a new table and then deletes the row in the current table.
I am doing it this way now:
The controller action I created:
[HttpPost]
public void MutatieButton(int? id)
{
using (var context = new Context())
using (var command = context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "INSERT INTO Mutatie SELECT * FROM Moederblad" + "DELETE FROM Moederblad WHERE Id="+ id;
context.Database.OpenConnection();
using (var result = command.ExecuteReader())
{
return;
}
}
}
The button in the view:
<input id="Mutatie" asp-route-id="#item.Id" type="button" value="Mutatie" onclick="MutatieButton()" />
The script code to perform controller action onclick:
function MutatieButton() {
$.ajax({
type: "POST",
url: '#Url.Action("Index", "Moederblads")',
async: true,
success: function (msg) {
ServiceSucceeded(msg);
},
error: function () {
return "error";
}
});
}
But I can't seem to figure it out.
I have read something about Unit of Work but it is very confusing to me, if I understand it correctly: You have a DAL where you put all the actions in like: Delete, update, insert, edit etc. And you call these actions in your controller to perform them?
Or is there a better practice doing this?

Ajax to MVC controller. Not passing parameters unless Ajax followed by alert

I have the strangest situation. I have two ajax POST. First I had problems passing the parameters to the controller but at some point I got them trough and with some debugging I figured out that I only get all of the values to the controller if my ajax definition is followed by an alert.
One of them:
$.ajax({
type: 'POST',
url: '/Contact/IntresseAnmälan/',
dataType: 'json',
data: {
Namn: $('#namn').val(),
Mail: $('#mail').val(),
Info: $('#meddelande').val(),
Telefon: $('#nr').val(),
IsEnkel: false,
PassId: function () {
var url = window.location.pathname;
var id = url.substring(url.lastIndexOf('/') + 1);
return id;
},
Participanter: getParticipant(),
ParticipantMail: getParticipantMail()
},
traditional: true,
success: function (result) {
// window.location.href = '#Url.Action("IntresseAnmälan", "Contact")';
}
});
alert("Hur sparas dina uppgifter?");
Here are my Getters for name and mail. The form-elements(input type mail and text) theese are dynamicly added to the form if the user wants clicks a button two inputs are added. Then theese functions returns an array with the inputed values from the form.
function getParticipant() {
var p = [];
for (var i = 1; i <= participantCount; i++) {
var name = '#anNamn' + i;
p[i -1] = $(name).val()
}
return p;
}
function getParticipantMail() {
var p = [];
for (var i = 1; i <= participantCount; i++) {
p[i -1] = $('#anMail' + i).val();
}
return p;
}
And here is my controller. I've removed the body in the controller. It saves to the Db and send a verification mail to the admin.
[HttpPost]
public ActionResult IntresseAnmälan(BokningContainer bokning)
{
//Saves to Db and Send a verification mail to admin
}
If I exclude the alert after the ajax some parameters are passed, I think it's Namn and Mail, but most of them not passed. I'm quite puzzled.
Also, is ajax the only way to pass an object to a controller from jQuery?
Also, is ajax the only way to pass an object to a controller from
jQuery?
No, you can use a regular HTML Form to submit your data, you just have to conform to the expected object in the controller Action (should be decorated with HttpPostAttribute) - There is a Model-Binding process which attempting to bind the Request data to your domain object.
You don't need to pass every field's value using jQuery. Instead you can create a form whose data you want to post like :
<form id="frmTest">
... add input types here
</form>
and you can pass data of form using $('#frmTest').serialize() method to the controller
$.ajax({
type: "POST",
data: $('#frmTest').serialize(),
url: "url",
dataType: "json",
success: function (data) { alert('worked!'); },
error: function (data) {
alert('error');
}
});

ASP.NET MVC: passing a complex viewmodel to controller

firs of all i searched for my question but couldnt find anything that helped me get any further.
i am trying to implement a view which allows me to set permissions for the current user.
As the data-structure i use following recursive class where each PermissionTree-Object references the sub-permissions (permissions are hierarchically structured in my application) :
public class PermissionTree
{
public Permission Node; //the permission object contains a field of type SqlHierarchyId if that is relevant
public bool HasPermission;
public IList<PermissionTree> Children;
//i cut out the constructors to keep it short ...
}
here is how the controller looks like:
//this is called to open the view
public ActionResult Permissions()
{
//pass the root element which contains all permission elements as children (recursion)
PermissionTree permissionTree = PopulateTree();//the fully populated permission-tree
return View(permissionTree);
}
//this is called when i submit the form
[HttpPost]
public ActionResult Permissions(PermissionTree model)
{
SetPermissions(model);
ViewData["PermissionsSaved"] = true;
return View(model);//return RedirectToAction("Index");
}
in am using a strongly typed view like this:
#model PermissionTree
//....
#using (Html.BeginForm("Permissions", "Permission", null, FormMethod.Post, new { #class = "stdform stdform2" }))
{
<input name="save" title="save2" class="k-button" type="submit" />
<div class="treeview">
//i am using the telerik kendoUI treeview
#(Html.Kendo().TreeView()
.Name("Permissions")
.Animation(true)
.ExpandAll(true)
.Checkboxes(checkboxes => checkboxes
.CheckChildren(true)
)
.BindTo(Model, mapping => mapping
.For<PermissionTree>(binding => binding
.Children(c => c.Children)
.ItemDataBound( (item, c) => {
item.Text = c.Node.PermissionName;
item.Checked = c.HasPermission;
})
)
)
)
ok, so when i click the button, i want my viewmodel to be sent to the controller action that is decorated with [HttpPost]. But when i debug the application, the received model does not really contain my data (it is not null though).
Does anyone know how i can achieve my goal and get the whole viewmodel?
best regards,
r3try
I think it's better to use a JSON post here ,then it's easy to prepare the object in the javascript side.
I don't know how your HTML looks like or the names of the elements you can easyly use javascript/Jquery to build the client side json object with similar names and slimier hierarchy/dataTypes just like in the PermissionTree class. And then use Ajax post to post as JSON
var PermissionTree={Node:{},HasPermission:false,Children:{}}
$.ajax({ data:PermissionTree
type: "POST",
url: 'YourController/Permissions',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
}
);
The important thing is you need to find a better way of going throuth the tree view and build the object in javascript.
as i cant get that to work i was trying a slightly different approach:
example for adding a node:
- press add button -> execute ajax call -> add the node in nhibernate -> call the view again with the new data (the new node included)
controller-action that is called by the ajax request:
[Authorize]
[HttpPost]
public ActionResult AddPermission(string parentPermissionName, string permissionName)
{
var pd = ServiceContext.PermissionService.permissionDao;
Permission parentPermission = pd.GetPermissionByName(parentPermissionName);
if (parentPermission == null) {
parentPermission = pd.GetRoot();
}
if (parentPermission != null && !string.IsNullOrEmpty(permissionName) && !pd.PermissionExists(permissionName))//only add with a name
{
pd.AddPermission(parentPermission, permissionName);
}
//refresh data
PermissionTree permissionTree = LoadTreeSQLHierarchy(null, false);//start at root
return View("Permissions", permissionTree);
}
Ajax Request in the View:
function addNode() {
//... get the data here
var addData = { parentPermissionName: selectedNodeName, permissionName: newNodeName };
$.ajax(
{
data: addData,
type: "POST",
url: '#Url.Action("AddPermission", "Permission")',
dataType: "json",
success: function (result) {
//$('.centercontent').html(response);//load to main div (?)
return false;
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status + ":" + thrownError);
return false;
}
}
);
return false;
}
But when i execute this i get an error stating that json.parse hit an invalid character (i get this error at the alert in the ajax's error function).
Judging from that message i would say that the problem is that i am returning html but the ajax call expects json or so...
But what is the correct way to just reload my view with the new data? Can i somehow tell the ajax call to not go back at all and just execute the called controller-method?

Categories

Resources