I am currently working on an accounting project and I am experiencing a stupid problem.
I enter the values in text boxes and I click on Add Person button, the values get added but when I click Save to Database button the multiple added values get pushed into database. I am able to insert multiple values in the database but unable to call the multiple entries from the SQL server back again onto my UI.
I have multiple same first names in my table of SQL server and I want to pick up all the values which have the same first name and populate them in $scope.arr I defined in angular code.
When I pass an integer value in my $scope.GetPerson() method, I get the desired result and my array ($scope.arr) gets populated with all the values having the same CustomerCode but when I pass a string value i.e, FirstName in GetPerson method, my array($scope.arr) doesn't get populated with the same First Name values that were placed into the database.
I want the experts to look into this problems and guide me where am I actually doing the mistake.`
My Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestProj.Models
{
public class TestModel
{
public int ID { get; set; }
public int CustomerCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal Debit { get; set; }
public decimal Credit { get; set; }
}
}
My Angular JS script:
var app = angular.module("TestApp", []);
app.controller("TestCtrl", function ($scope, TestService) {
$scope.arr = [];
GetAllPers();
function GetAllPers() {
var getPersData = TestService.getPersons();
getPersData.then(function (Persons) {
$scope.persons = Persons.data;
}, function () {
alert('Error in getting Person records');
});
}
$scope.addPerson = function () {
var obj = {
CustomerCode: $scope.customercode,
FirstName: $scope.firstname,
LastName: $scope.lastname,
Debit: $scope.debit,
Credit: $scope.credit,
};
$scope.arr.push(obj);
};
$scope.savePerson = function () {
var TestData = TestService.AddPer($scope.arr);
TestData.then(function (msg) {
$scope.customercode = "";
$scope.firstname = "";
$scope.lastname = "";
$scope.debit = "";
$scope.credit = "";
GetAllPers();
alert(msg.data);
for (var i = 0; i < $scope.arr.length; i++) {
$scope.arr.pop();
}
}, function () {
alert('Error In Adding Person');
});
};
$scope.GetPerson = function (test) {
var getTestData = TestService.getPers(test.FirstName);
getTestData.then(function (_test) {
$scope.arr = _test.data;
}, function () {
alert('Error in getting person records');
});
}
});
app.service("TestService", function ($http) {
this.getPersons = function () {
return $http.get("/Test/GetAllPers");
}
this.AddPer = function (person) {
var response = $http({
method: "post",
url: "/Test/AddPerson",
data: JSON.stringify(person),
dataType: "json",
});
console.log(response);
return response;
}
this.getPers = function (persname) {
var response = $http({
method: "post",
url: "/Test/GetPersonByFName",
params: {
firstname: JSON.stringify(persname)
}
});
return response;
}
});
My C# controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestProj.Models;
namespace TestProj.Controllers
{
public class TestController : Controller
{
TestContext dc = new TestContext();
// GET: Test
public ActionResult Index()
{
return View();
}
public JsonResult GetAllPers()
{
var personList = dc.TestModels.ToList();
return Json(personList, JsonRequestBehavior.AllowGet);
}
public JsonResult GetPersonByFName(string firstname)
{
var q = (from ab in dc.TestModels.Where(b => b.FirstName == firstname) select ab);
return Json(q, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public string AddPerson(List<TestModel> test)
{
bool val = false;
foreach (var t in test)
{
if (t != null)
{
dc.TestModels.Add(t);
val = true;
}
else
{
val = false;
}
}
dc.SaveChanges(); //save context at the end, when no error occurs
if (val == true)
{
return "Success";
}
else
{
return "Failed";
}
}
}
}
My HTML:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div ng-controller="TestCtrl">
<form>
<button class="btn" data-toggle="modal" data-target="#myModal">Show records</button><br />
Customer Code: <input class="form-control" ng-model="customercode" /><br />
FirstName: <input class="form-control" ng-model="firstname" /><br />
LastName: <input class="form-control" ng-model="lastname" /><br />
Debit: <input class="form-control" ng-model="debit" /><br />
Credit: <input class="form-control" ng-model="credit" /><br />
<button class="btn btn-success" ng-click="addPerson()">Add Person</button>
<button class="btn btn-success" ng-click="savePerson()">Save To DB</button>
#*Table for showing pushed values*#
<table class="table table-bordered">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Debit</th>
<th>Credit</th>
</tr>
<tr ng-repeat="a in arr">
<td>{{a.CustomerCode}}</td>
<td>{{a.FirstName}}</td>
<td>{{a.LastName}}</td>
<td>{{a.Debit}}</td>
<td>{{a.Credit}}</td>
</tr>
</table>
#*Modal popup*#
<div class="modal fade" role="dialog" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4>Persons</h4>
</div>
<div class="modal-body">
<label class="control-label col-md-2" style="width: auto">Search:</label>
<div class="col-md-8">
<input class="form-control" ng-model="searchfor" />
</div><br />
<table class="table table-hover">
<tr>
<td><b>First Name</b></td>
<td><b>Last Name</b></td>
<td><b>Debit</b></td>
<td><b>Credit</b></td>
<td><b>Select</b></td>
</tr>
<tr ng-repeat="b in persons | filter:searchfor ">
<td>{{b.CustomerCode}}</td>
<td>{{b.FirstName}}</td>
<td>{{b.LastName}}</td>
<td>{{b.Debit}}</td>
<td>{{b.Credit}}</td>
<td>
<button type="button" class="btn btn-success" ng-click="GetPerson(b)" data-dismiss="modal">Select</button>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#myModal">Okay</button>
</div>
</div>
</div>
</div><br />
</form>
</div>
<script src="~/Scripts/MyAngular/Module.js"></script>
The issue is with your getPers(). Adding JSON.stringfy() adds " to your string.
It should be used like this :
this.getPers = function (persname) {
var response = $http({
method: "post",
url: "/Test/GetPersonByFName",
params: {
firstname: persname
}
});
return response;
}
Related
I want to create a Quiz, add questions to the quiz, and add answers to the question. I bound all items with asp-for, serialize my form, and send it to the controller, but they don't bind.
My classes:
public class Answer
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Content { get; set; }
public Guid QuestionId { get; set; }
}
public class Question
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Content { get; set; }
public Guid QuizId { get; set; }
public ICollection<Answer> Answers { get; set; } = new List<Answer>() {
new Answer() { Content = "Answeeeer" },
new Answer() { Content = "Answeeeer2" },
new Answer() { Content = "Answeeeer3" }
};
}
public class Quiz
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Name { get; set; }
public ICollection<Question> Questions { get; set; } = new List<Question>() { };
}
Quiz view:
#model QuizIt_Tests.Entities.Quiz
#{
ViewData\["Title"\] = "Create";
}
\<h1\>Create\</h1\>
\<h4\>Quiz\</h4\>
\<hr /\>
\<div class="row"\>
\<div class="w-75"\>
\<form id="myform" asp-action="Create" method="post" class="p-3"\>
<div class="form-group">
<label asp-for="Name" class="control-label">Quiz Name</label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div id="questionRows" class="form-group w-100">
#Html.EditorFor(model => model.Questions)
<button type="button" id="AddQuestion" class="btn btn-primary mt-2">Add Question</button>
</div>
<div class="form-group mt-2">
input id="submitbutton" type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
\</div\>
\<div\>
\<a asp-action="Index"\>Back to List\</a\>
\</div\>
#section Scripts {
#{
await Html.RenderPartialAsync("\_ValidationScriptsPartial");
}
<script>
$("#submitbutton").click(function (e) {
e.preventDefault();
console.log("Serialized Data: ");
console.log($('#myform').serialize())
$.ajax({
async: true,
data: $('#myform').serialize(),
method: 'post',
url: "Quizes/AddQuestion",
success: function () {
}
});
});
$("#AddQuestion").click(function () {
console.log("Serialized Data: ");
console.log($('#myform').serialize())
console.log($('#questionRows').serialize())
$.ajax({
url: '#Url.Action("AddBlankQuestion", "Quizes")',
cache: false,
success: function (html) { $("#questionRows").append(html); },
error: function (xhr, status, error) {
console.log(xhr.responseText);
}
});
return false;
});
$("a.deleteRow").on("click", function () {
$(this).parents("div.editorRow:first").remove();
return false;
});
</script>
}
Question partial view:
#model QuizIt_Tests.Entities.Question
\<hr style="height: 4px; color: black;" /\>
\<div class="w-100 p-3 px-5 my-3"\>
<div class="form-group">
<label asp-for="Content" class="control-label">Question</label>
<input asp-for="Content" class="form-control" value="#Model.Content" />
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<input type="hidden" asp-for="Id" class="form-control" value="#Model.Id" />
#{
var answerrowid = "answerRows" + #Model.Id;
var addanswerbtnid = "addAnswer" + #Model.Id;
}
<div id="#answerrowid" class="w-75">
#Html.EditorFor(model => model.Answers)
</div>
<button type="button" class="btn btn-primary" id="#addanswerbtnid">Add Answer</button>
\</div\>
<script>
console.log("##addanswerbtnid");
$("##addanswerbtnid").click(function () {
console.log("Add Answer clicked");
$.ajax({
url: '#Url.Action("AddBlankAnswer", "Quizes")',
cache: false,
success: function (html) {
$("##answerrowid").append(html);
},
error: function (xhr, status, error) {
console.log(xhr.responseText);
}
});
return false;
});
</script>
Answer partial view:
#model QuizIt_Tests.Entities.Answer
\<div class="row" style="margin: 20px;"\>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Content" class="control-label">Answer Content</label>
<input asp-for="Content" class="form-control" value="#Model.Content" />
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<input type="hidden" asp-for="Id" class="form-control" value="#Model.Id" />
\</div\>
This is my controller:
public class QuizesController : Controller
{
private readonly ApplicationDBContext _context;
public QuizesController(ApplicationDBContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
return View(await _context.Quizzes.ToListAsync());
}
public IActionResult Create()
{
var newquiz = new Quiz();
return View(newquiz);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Quiz quiz)
{
if (ModelState.IsValid)
{
_context.Add(quiz);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(quiz);
}
public IActionResult AddBlankQuestion(Quiz model)
{
Question question = new Question();
//question.Answers.Add(new Answer() { QuestionId = question.Id, Content = "Salaaam Necesem" });
return PartialView("EditorTemplates/Question", question);
}
public IActionResult AddBlankAnswer(Question model)
{
var newanswer = new Answer() { QuestionId = model.Id, Content = String.Empty };
return PartialView("EditorTemplates/Answer", newanswer);
}
}
I want to create a Quiz, add questions to the quiz, and add answers to the question. I bound all items with asp-for, serialize my form, and send it to the controller, but they don't bind.
public ICollection Questions { get; set; }
You don't bind Content to your list ICollection<Question> Questions , so the Questions list is null.
You need to set name like name="Questions[0].Content" and name="Questions[1].Content".
I am developing an ASP.NET core Razor application and I have a form that I am posting, but I don't want the page to reload on submit. I read that this can be avoided by using Ajax, but i'm not sure how to implement this.
This is my form:
<form id="bankDropdown" method="post">
<div>
<label class="ratings-text" for="bank">Select Bank:</label>
<select name="BankOptions" class="form-control ratings-text" style="width:21%" id="bank">
#foreach (var bank in Model.BankLists)
{
<option name="BankOptions" value="#bank.ShortName" id="selection">#bank.ShortName</option>
}
</select>
</div>
<br />
<div>
<label>Enter Start Date:</label>
<input type="date" asp-for="DateSelect.DateMonthYear1" class="DateMonthYear" name="DateMonthYear1">
<i data-toggle="tooltip" title="Set to first day of the month for optimal results" class="far fa-question-circle"></i>
</div>
<br />
<div>
<label>Enter End Date:</label>
<input type="date" asp-for="DateSelect.DateMonthYear" class="DateMonthYear" name="DateMonthYear" required>
<i data-toggle="tooltip" title="Set to last or current day of the month for optimal results" class="far fa-question-circle"></i>
</div>
<br />
<div>
<input class="ratings-button" type="submit" value="Submit"/>
</div>
</form>
This is my POST function in my page model:
public IActionResult OnPost(string DateMonthYear, string DateMonthYear1, string BankOptions)
{
CurrentDate = string.Format(DateMonthYear);
SelectBank = BankOptions;
BankLists = ModelService.RunBankList();
TotalBankCollections = ModelService.RunTotalBankCollection1(DateMonthYear);
TotalTransactionCounts = ModelService.RunTotalTransactionCount1(DateMonthYear1, DateMonthYear);
long floatTotalCount = 0;
int intVolumeCount = 0;
string stringTotalVolume = "";
//get individual bank monthly collections
foreach (var collection in TotalBankCollections)
{
if (BankOptions == collection.ShortName)
{
string myBank = collection.TotalCollection;
BankCollection = Convert.ToDecimal(myBank).ToString("#,###,###.##");
}
}
//get total collections from all the banks
foreach (var collection in TotalBankCollections)
{
floatTotalCount += (long)Convert.ToDouble(collection.TotalCollection);
string stringTotalCount = Convert.ToDecimal(floatTotalCount).ToString("#,###,###.##");
TotalCollectionCount = stringTotalCount;
}
//get individual monthly volume collections
foreach (var collection in TotalTransactionCounts)
{
if (BankOptions == collection.ShortName)
{
string myBank = collection.TotalCount;
MonthlyVolumeCount = Convert.ToDecimal(myBank).ToString("#,##0");
}
}
//get total transactions of all banks
foreach (var collection in TotalTransactionCounts)
{
intVolumeCount += int.Parse(collection.TotalCount);
stringTotalVolume = intVolumeCount.ToString("#,##0");
TotalVolumeCount = stringTotalVolume;
}
return Page();
}
This is what I have so far, I have never used Ajax before and I have a project deadline:
$.ajax({
type: "POST",
url: "/Identity/Account/Ratings",
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (response) {
alert(response);
},
failure: function (response) {
alert(response);
}
});
Thanks for the help.
If you want to use ajax with post method in razor page,here is a demo:
TestFormPost.cshtml(script):
$("#bankDropdown").on('submit', function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "",
data: $("#bankDropdown").serialize(),
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
success: function (data) {
}
});
})
TestFormPost.cshtml.cs:
public class TestFormPostModel : PageModel
{
[BindProperty]
public List<Bank> BankLists { get; set; }
[BindProperty]
public DateSelect DateSelect { get; set; }
public IActionResult OnGet()
{
BankLists = new List<Bank> {
new Bank{ ShortName="bank1"},
new Bank{ ShortName="bank2"},
new Bank{ ShortName="bank3"}
};
return Page();
}
public IActionResult OnPost(string DateMonthYear, string DateMonthYear1, string BankOptions) {
return Page();
}
}
public class Bank
{
public string ShortName { get; set; }
}
public class DateSelect
{
public string DateMonthYear { get; set; }
public string DateMonthYear1 { get; set; }
}
result:
you can prevent form submission by
$('form').on('submit',function(e){
e.preventDefault();
////then ajax call
})
I'm trying to save the image on the server alongside with some information about it using form and then angular (1.5.7) and C#.
I've tried multiple ways, Either the file passed to Api controller is empty or the Model state is invalid.
Can you tell me what am I doing wrong?
My C# Controller:
namespace xxx.Controllers.Api
{
[Route("api/partners")]
public class PartnersController : Controller
{
private IMeblatRepository _repository;
private ILogger<PartnersController> _logger;
private IHostingEnvironment _environment;
public PartnersController(IMeblatRepository repository, ILogger<PartnersController> logger, IHostingEnvironment environment)
{
_repository = repository;
_logger = logger;
_environment = environment;
}
[HttpGet("")]
public IActionResult Get()
{
try {
var results = _repository.GetAllPartners();
return Ok(Mapper.Map<IEnumerable<PartnersViewModel>>(results));
}
catch (Exception ex)
{
_logger.LogError($"Failed to get All Partners: {ex}");
return BadRequest("Bad Request");
}
}
[HttpPost("")]
public async Task<IActionResult> Post([FromBody]Data data)
{
if (ModelState.IsValid)
{
var uploads = Path.Combine(_environment.WebRootPath, "uploads");
if (data.file.Length > 0)
{
using (var fileStream = new FileStream(Path.Combine(uploads, data.file.FileName), FileMode.Create))
{
await data.file.CopyToAsync(fileStream);
}
}
//Save to the Database
var newPartner = Mapper.Map<Partners>(data.newPartner);
_repository.AddPartner(newPartner);
if(await _repository.SaveChangesAsync())
{
return Created($"api/partners/{data.newPartner.Name}", Mapper.Map<PartnersViewModel>(newPartner));
}
else
{
return BadRequest("Failed to save to the database");
}
}
return BadRequest(ModelState);
}
[HttpDelete("{name}")]
public async Task<IActionResult> Delete([FromRoute] string name)
{
if (ModelState.IsValid)
{
var partnerToDelete = _repository.GetPartnerByName(name);
_repository.RemovePartner(partnerToDelete);
if (await _repository.SaveChangesAsync())
{
return Ok($"api/partners");
}
else
{
return BadRequest("Failed to remove");
}
}
return BadRequest(ModelState);
}
}
}
Data class:
public class Data
{
public PartnersViewModel newPartner { get; set; }
public IFormFile file { get; set; }
}
Angular controller:
(function () {
"use strict";
// getting the existing module
angular.module("app-edit")
.controller("partnersController", partnersController);
function partnersController($http, $scope) {
var vm = this;
vm.partners = [];
vm.newPartner = {};
vm.errorMessage = "";
vm.isBusy = true;
var f = null;
$scope.add = function () {
f = document.getElementById('uploader').files[0];
if (f) {
alert("File attached succesfully");
}
};
$http.get("/api/partners").then(function (response) {
//success
angular.copy(response.data, vm.partners);
}, function () {
//failure
vm.errorMessage = "failed to load data";
})
.finally(function () {
vm.isBusy = false;
});
vm.addPartner = function () {
vm.isBusy = true;
vm.errorMessage = "";
var Indata = { 'newPartner': vm.newPartner, 'file': f };
$http.post("/api/partners", Indata)
.then(function () {
//success
vm.partners.push(response.data);
vm.newPartner = {};
}, function () {
//failure
vm.errorMessage = "Failed to save new partner";
})
.finally(function () {
vm.isBusy = false;
});
};
vm.removePartner = function (name) {
vm.isBusy = true;
vm.errorMessage = "";
$http.delete("/api/partners/" + name)
.then(function () {
//success
//vm.partners.shift();
//vm.newPartner = {};
vm.errorMessage = "Udało się usunąć partnera";
}, function () {
//failure
vm.errorMessage = "Nie udało się usunąć partnera";
})
.finally(function () {
vm.isBusy = false;
});
};
}
})();
HTML file:
<div class="col-md-6 col-md-offset-3">
<div class="text-danger" ng-show="vm.errorMessage">{{ vm.errorMessage }}</div>
<wait-cursor ng-show="vm.isBusy"></wait-cursor>
<form novalidate name="newPartnerForm" method="POST" enctype="multipart/form-data" ng-submit="vm.addPartner()">
<div class="form-group">
<label for="name">Nazwa Partnera</label>
<input class="form-control" type="text" id="name" name="name" ng-model="vm.newPartner.name" required/>
<span ng-show="newPartnerForm.name.$error.required" class="text-warning">To pole jest wymagane</span>
</div>
<div class="form-group">
<label for="files">Ścieżka</label>
<input type="file" id="uploader" name="files[]" class="btn btn-primary" accept="image/*" ng-model="files" ngf-multiple="false">
<button ng-click="add()">Add</button>
</div>
<div class="form-group">
<label for="href">Link do strony partnera</label>
<input class="form-control" type="text" id="href" name="href" ng-model="vm.newPartner.href"/>
</div>
<div class="form-group">
<input type="submit" value="Add"
class="btn btn-success btn-sm"
ng-disabled="newPartnerForm.$invalid" />
</div>
</form>
<table class="table table-responsive table-striped">
<tr ng-repeat="partner in vm.partners">
<td> {{partner.name}}</td>
<td> {{partner.href}}</td>
<td><a ng-href="#/editor/{{ patner.name }}" class="btn btn-sm btn-primary">Manage</a></td>
<td><input type="button" ng-click="vm.removePartner(partner.name)" value="Usuń" class="btn btn-sm btn-danger"/></td>
</tr>
</table>
Passing from form seems to be working as the alert is trigerred everytime I choose the file.
I am using a partial view "_studentList" in a View "SearchStudent". In my View i have a textfield and a search button and i am showing list of students in my partial view.
My View is like as follow:
#model Practice_SQL_Validation_ALL.Models.SearchViewModel
#{
ViewBag.Title = "SearchStudent";
}
<h2>SearchStudent</h2>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand">Search</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" id="txtserch" placeholder="Enter Roll No or Name">
#*#Html.EditorFor(model => model.SEARCHCRITERA.VALUE, new { htmlAttributes = new { #class = "form-control", placeholder = "Enter Roll No or Name" } })*#
</div>
<button id="preview" type="button" class="btn btn-default">Search</button>
</form>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div id="result">
#Html.Partial("_StudentList", Model.STUDENTLIST)
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
jQuery.ready(function () {
$("#result").hide();
$("#preview").click(function () {
//$("#div1").hide();
$("#result").show();
});
});
$("#preview").click(function () {
var jsonObject = {
"returnUrl": $('#txtserch').val()
};
jQuery.ajax({
type: "POST",
url: "SearchStudent",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(jsonObject),
success: function (data) { alert("Success"); },
failure: function (errMsg) {
alert("Error");
}
});
});
</script>
And my Partial View is like as follow:
#model IEnumerable<Practice_SQL_Validation_ALL.Models.Student>
#*<p>
#Html.ActionLink("Create New", "Create")
</p>*#
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ROLLNUMBER)
</th>
<th>
#Html.DisplayNameFor(model => model.NAME)
</th>
<th>
#Html.DisplayNameFor(model => model.ADDRESS)
</th>
<th>
#Html.DisplayNameFor(model => model.PHONE)
</th>
<th>
#Html.DisplayNameFor(model => model.CLASS)
</th>
<th>
#Html.DisplayNameFor(model => model.ISNEW)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ROLLNUMBER)
</td>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.ADDRESS)
</td>
<td>
#Html.DisplayFor(modelItem => item.PHONE)
</td>
<td>
#Html.DisplayFor(modelItem => item.CLASS)
</td>
<td>
#Html.DisplayFor(modelItem => item.ISNEW)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
My ViewModel is like as follow:
namespace Practice_SQL_Validation_ALL.Models
{
public class SearchViewModel
{
private SearchCriteria searchcriteria = null;
private List<Student> studentlist = null;
public SearchCriteria SEARCHCRITERA
{
set
{
searchcriteria = value;
}
get
{
return searchcriteria;
}
}
public List<Student> STUDENTLIST
{
set
{
studentlist = value;
}
get
{
return studentlist;
}
}
public SearchViewModel()
{
searchcriteria = new SearchCriteria();
studentlist = new List<Student>();
}
}
public class SearchCriteria
{
[Display(Name = "Criteria")]
public string CRITERIA { get; set; }
[Display(Name = "Value")]
public string VALUE { get; set; }
}
public class Student
{
#region Properties
private bool m_isnew = true;
[Required]
[Display(Name = "Roll Number")]
public string ROLLNUMBER { get; set; }
[Required]
[Display(Name = "Name")]
public string NAME { get; set; }
//[Required]
[Display(Name = "Address")]
public string ADDRESS { get; set; }
//[Required]
[Display(Name = "Phone#")]
public string PHONE { get; set; }
[Display(Name = "Class")]
public string CLASS { get; set; }
[Display(Name = "Edit Mode")]
public bool ISNEW { get { return m_isnew; } set { m_isnew = value; } }
#endregion
}
}
My StudentController is as follow:
namespace Practice_SQL_Validation_ALL.Controllers
{
public class StudentController : Controller
{
public ActionResult SearchStudent()
{
SearchViewModel obj = new SearchViewModel();
ViewBag.Count = 0;
return View(obj);
}
[HttpPost]
//[AllowAnonymous]
//[ValidateAntiForgeryToken]
//[ChildActionOnly]
public ActionResult SearchStudent(string returnUrl)
{
SearchViewModel obj = new SearchViewModel();
//DAS db = new DAS();
//list = db.SearchStudentwithCriteria("RollNo", "");
//return PartialView()
obj.SEARCHCRITERA.VALUE = "Some";
obj.STUDENTLIST.Add(new Student { ADDRESS = "Address", ROLLNUMBER = "3160", NAME = "Awais", CLASS = "A", PHONE = "Phone" });
//return View(list);
ViewBag.Count = obj.STUDENTLIST.Count;
//return View(obj);
return PartialView("_StudentList", obj);
//return PartialView("_StudentList", list);
//return PartialView("_StudentList", list);
}
}
}
I want that if I click search button then ajax call SearchStudent Post function and return collection that should be displayed on partial view. Till now function is being called but response is not being returned to the view or partialview. As i am showing alertbox in both cases success and failure but system does not show alertbox in anycase. What am i doing wrong? Any help would be greatly appreciated! Please let me know if you need any more information.
Very Thanks in Advance.
Everything seems fine just the ajax succes you have to put the content like this
$.ajax({
url: "SearchStudent",
data: { "returnUrl": $('#txtserch').val()},
type: "POST",
cache: false,
success: function (data) {
$("#result").html(data); //********* This is where you have put the result into, because in success you will get the HTML
},
error: function () {
}
});
Made some changes as follow and got my issue fixed.
In Controller function "SearchStudent" returned partialview with collection.
public ActionResult SearchStudent(string returnUrl)
{
SearchViewModel obj = new SearchViewModel();
obj.SEARCHCRITERA.VALUE = "Some";
obj.STUDENTLIST.Add(new Student { ADDRESS = "Address", ROLLNUMBER = "3160", NAME = "Awais", CLASS = "A", PHONE = "Phone" });
ViewBag.Count = obj.STUDENTLIST.Count;
return PartialView("_StudentList", obj.STUDENTLIST);
}
And changed ajax call as follow:
jQuery.ajax({
type: "POST",
url: "SearchStudent",
//dataType: "json",
cache: false,
//context:
contentType: "html",
data: JSON.stringify(jsonObject),
success: function (data) { $("#result").html(data); },
failure: function (errMsg) {
$("#result").html("Error");
}
});
I think problem was majorly in ajax call. As i was returning html content from controller function but in ajax call i have mentained contentType and datatype properties as Json. That's why HTML could not been shown on success.
How can i get value from ajax to mvc controller method in 'FileStreamResult' in mvc?I want to pass value from #Model[i].ToString() to controller by ajax.
Controller
public ActionResult Index()
{
IEnumerable<VmFile> model = _manager.fileName();
return View(model);
}
public ActionResult Upload(HttpPostedFileBase file)
{
try
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/File/"), fileName);
file.SaveAs(path);
_manager.UploadFile(file, path.ToString());
}
ViewBag.Message = "Upload successful";
return RedirectToAction("Index");
}
catch
{
ViewBag.Message = "Upload failed";
return RedirectToAction("Index");
}
}
public FileStreamResult GetFile(int Id)
{
string fileName = _manager.FileName(Id);
string filePath = ConfigurationManager.AppSettings["FilePath"] + fileName;
FileStream fs = new FileStream(Server.MapPath(filePath), FileMode.Open, FileAccess.Read);
return File(fs, "application/pdf");
}
FileManager
public string FileName (int id)
{
string fileName = _unitOfWork.FileRepository.Get(r => r.Id == id).Select(f => f.Name).First();
return fileName;
}
public IEnumerable<VmFile> fileName()
{
var file = _unitOfWork.FileRepository.Get();
var model = from r in file
select new VmFile
{
Id = r.Id,
Name = r.Name,
ThanaId =r.ThanaId,
RoadId = r.RoadId,
Url = r.Url,
UpLoadDate = r.UpLoadDate,
FCategoryId = r.FCategoryId,
FileType = r.FileType
};
return model;
}
public void UploadFile(HttpPostedFileBase file,string path)
{
string fName = file.FileName;
string[] typ = fName.Split('.');//Regex.Split(fName, #".");
File newFIle = new File
{
Name = fName,
Url = path,
FCategoryId = 1,
ThanaId = 23201,
RoadId = 12,
FileType = typ[1],
UpLoadDate = DateTime.Now
};
_unitOfWork.FileRepository.Insert(newFIle);
_unitOfWork.Save();
}
VmFile
public class VmFile
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public Nullable<short> BridgeId { get; set; }
public Nullable<DateTime> UpLoadDate { get; set; }
public Nullable<double> FromChain { get; set; }
public Nullable<double> ToChain { get; set; }
public string FileType { get; set; }
public Nullable<int> FCategoryId { get; set; }
public Nullable<int> ThanaId { get; set; }
public Nullable<int> RoadId { get; set; }
}
View
#model IEnumerable<RSDMS.ViewModel.VmFile>
#{
Layout = null;
}
<html>
<head>
<link href="~/Content/bootstrap-theme.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<div id="header" class="container">
<h2>Document Module</h2>
<div class="panel panel-default">
<div id="h2" class=" panel panel-primary "><h4 id="h4">Document Type</h4></div>
<div id="form" class=" panel-body">
<form role="form">
<label class="checkbox-inline">
<input type="checkbox" value="">A-Road Related
</label>
<label class="checkbox-inline">
<input type="checkbox" value="">B-Road+Structure Relate
</label>
<label class="checkbox-inline">
<input type="checkbox" value="">C-
</label>
<label class="checkbox-inline">
<input type="checkbox" value="">Option 1
</label>
<label class="checkbox-inline">
<input type="checkbox" value="">Option 2
</label>
<label class="checkbox-inline">
<input type="checkbox" value="">Option 3
</label>
</form>
</div>
</div>
<div id="listpanel" class="panel-primary">
<h1>List Panel</h1>
<div id="file">
<table>
<th>File Name</th>
#foreach (var file in Model)
{
<tr>
<td>
<li>
#file.Name
</li>
</td>
</tr>
<br />
}
</table>
</div>
#using (Html.BeginForm("Upload", "Document", FormMethod.Post, new {enctype = "multipart/form-data"}))
{
<label class="btn btn-block btn-primary">
Browse … <input type="file" name="file" id="file" style="display: none;">
</label>
<input type="submit" class="btn" value="Upload">
}
</div>
<div id="frame" class="panel-body">
<div id="frame">
<iframe src="#Url.Action("GetFile", "Document")" width="900px" height="500px"></iframe>
</div>
</div>
</div>
</body>
</html>
<style>
#h2 {
background-color: lightblue;
height: 40px;
}
#h4 {
margin-left: 20px;
}
#header {
margin-left: 50px;
margin-right: 50px;
}
#frame {
float: right;
margin-bottom: 50px;
}
#listpanel {
float: left;
}
</style>
<script>
$(document).ready(function(e) {
// var p = { Data: $('#fileId').val() };
//var currentDataItem = this.dataItem(this);
//id = currentDataItem.Id;
alert($('#fileId').attr('id'));
var p = { Data: $('#fileId').val() };
alert(p);
var id = $('#fileId').text();
alert(id);
$('#fileId').click(function () {
$.ajax(
{
//url: '#Url.Action("GetFile", "Document")?id=' + id,
url: '/Document/GetFile',
type: "POST",
data: {Id:id},
success:function(data)
{
},
error:function(e)
{
}
});
})
});
</script>
Your javascript code should be wrapped in a jQuery load function, like this:
$(function () {
//Paste all your java script here
});
That was the only change I made on my side and the AJAX call to GetFile in the Document controller is now working
As Denis Wessels said you have to enclose jquery code inside document ready block
$( document ).ready(function() {
var currentDataItem = this.dataItem(this.select());
id = currentDataItem.Id;
var p = { Data: $('#fileId').val() };
$('#fileId').click(function () {
$.ajax(
{
url: '#Url.Action("GetFile", "Document")?id=' + id,
//url: '/Document/GetFile',
type: "POST",
// data: {Id:id},
success:function(data)
{
},
error:function(e)
{
}
});
})
});
First all let me correct certain mistakes in your code. In view haven't passed any id that could be passed in the action method. So either in the FileManager class change the returntype of GetData method as
Dictionary<int,string>
OR
create a model class say FileManagerModel as follows
public class FileManagerModel
{
public int ID {get;set;}
public string FileName{get;set;}
}
and change the return type as
List<FileManagerModel>
accordingly change the model in the view as
#model Dictionary<int, string> // If the return type is Dictionary<int,string>
and then in the view change your for loop as follows
#foreach(var file in Model)
{
<tr>
<td>
<li>
#file.Value
</li>
</td>
</tr>
<br />
}
and also change your GetFile method as follows
public FileStreamResult GetFile(int? id)
{
string fileName = "IFrameTest.txt";
var t = ConfigurationManager.AppSettings["FilePath"];
string filePath = ConfigurationManager.AppSettings["FilePath"] + fileName;
FileStream fs = new FileStream(Server.MapPath(filePath), FileMode.Open, FileAccess.Read);
return File(fs, "text/plain");
}
add nullable int arguement in your method as on page load your id will be null.
As the method by default is HTTPGET method in your Ajax call you need to make changes as follows
<script>
$(document).ready(function(e) {
var id = $('#fileId').text();
$('#fileId').click(function (event) {
event.preventDefault();
var id = $(this).data("id");
$.ajax(
{
url: '#Url.Action("GetFile", "Document")',
type: "GET",
data: { id: id },
success:function(data)
{
},
error:function(e)
{
}
});
})
});
</script>
On doing these changes it worked for me .I hope this will rectify your issue
UPDATE
If you are using IEnumerable pass the Id in the data attribute as
#file.Name