i am trying to post my model to the server through an ajax call. Unfortunately the Model is not updated?
<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<form id="ajaxForm" action="">
<div>
name:<%= Html.TextBoxFor(model => model.number) %>
</div>
<%--hidden vars--%>
<input type="hidden" id="Hidden1" />
<%= Html.Hidden("myModel", Model.Serialize())%>
</form>
<button id="submitbutton">
save
</button>
<script type="text/javascript">
$(document).ready(function () {
$("#submitbutton").click(function () {
var FormData = $("#ajaxForm").serialize();
$.ajax({
type: 'POST',
url: "/Home/SaveAjax",
data: { inputdata: $("#myModel").val() },
datatype: 'JSON'
});
})
});
</script>
[HttpPost]
public JsonResult SaveAjax(string inputdata)
{
MyModel myModel = (inputdata.DeSerialize() ?? TempData["myModel"] ?? new MyModel()) as MyModel;
//TryUpdateModel does not update my model??
TryUpdateModel(myModel);
TempData["myModel"] = myModel;
return Json(new { resultaat = "finished" });
}
[Serializable]
public class MyModel
{
//[Required]
public string name { get; set; }
public bool flag { get; set; }
public int number { get; set; }
public string address { get; set; }
public string abn { get; set; }
public string postalcode { get; set; }
}
public static class Extensions
{
public static string Serialize(this object myobject)
{
var sw = new StringWriter();
var formatter = new LosFormatter();
formatter.Serialize(sw, myobject);
return sw.ToString();
}
public static object DeSerialize(this string mystring)
{
if (string.IsNullOrEmpty(mystring))
return null;
var formatter = new LosFormatter();
MyModel mym = (MyModel)formatter.Deserialize(mystring);
return mym;
}
}
In your AJAX request you are sending only the value of the hidden field:
data: { inputdata: $("#myModel").val() }
so you cannot expect to get any other values on your server than this hidden field. If you want to POST the entire form contents use the formData variable that you declared in your code but left unused:
$('#submitbutton').click(function () {
var formData = $('#ajaxForm').serialize();
$.ajax({
type: 'POST',
url: '/Home/SaveAjax',
data: formData,
dataType: 'json'
});
});
Related
When I tried to refresh my page I can do it with this code;
$(document).ready(function () {
var interval = 500;
var refresh = function () {
$.ajax({
url: "https://localhost:44399/area/areadetail/#ViewBag.i",
cache: false,
success: function (html) {
$('.yika').html(html);
setTimeout(function () {
refresh();
}, interval);
}
});
};
refresh();
});
but my web page seems as;
How can I fix this situation in my code?
I will refresh the part of the page for you
step 1. add this class
public class JsonData
{
public string HtmlMsg { get; set; }
public string HtmlBody { get; set; }
public bool Success { get; set; }
}
step 2. then add class ViewHelper.cs
public static class ViewHelper
{
public static string RenderPartialToString(this ControllerBase controller)
{
return RenderViewToString(controller);
}
public static string RenderPartialToString(this ControllerBase controller, string partialViewName)
{
IView view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;
return RenderViewToString(controller, view);
}
public static string RenderPartialToString(this ControllerBase controller, string partialViewName, object model)
{
IView view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;
return RenderViewToString(controller, view, model);
}
}
step 3. add your PartialView and Put the part you want to refresh in PartialView exapmle:_MyDiv
<div class="col-level1-20">
<div class="row-new shadow-slider-list background-white border-r-1-ddd border-t-ddd">
refresh div
</div>
</div>
step 4. Your Action in Controller
public ActionResult areadetail(int id)
{
//............
return Json(new JsonData()
{
HtmlMsg = "OK",
HtmlBody = this.RenderPartialToString("_MyDiv"),
Success = true,
});
}
step 5. add PartialView in View
#{
ViewBag.Title = "TestPartialView";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<section class="row-new margin-t-10">
<div class="row-new">
<div class="container style-direction-rtl">
<span class="style-font-16-sb color-black">Test PartialView</span>
</div>
<div class="container style-direction-rtl" id="yika">
#Html.Partial("_MyDiv")
</div>
</div>
</section>
step 6. Finally add script
$(document).ready(function () {
var interval = 500;
var refresh = function () {
$.ajax({
url: "https://localhost:44399/area/areadetail/#ViewBag.i",
cache: false,
success: function (result) {
if(result.Success)
{
$('#yika').html(result.HtmlBody);
}
else
{
alert('failed');
}
}
error: function () {
alert('error');
}
});
};
});
My ajax POST request does'nt seem to be hitting my contoller, although i have used other Ajax post requests in my application this one doesnt seem to be working. My first throught was the datatypes within the model were not strings but other than that i can't seem to figure out why it isnt working.
Model
public class AppointmentViewModel
{
public List<DTO.Appointment> appointments { get; set; }
public DTO.Appointment appointment { get; set; }
public int AppointmentId_Input { get; set; }
public string AppointmentTitle_Input { get; set; }
public string AppointmentName_Input { get; set; }
public DateTime AppointmentStartTime_Input { get; set; }
public DateTime AppointmentEndTime_Input { get; set; }
public int AppointmentType_Input { get; set; }
public List<DTO.AppointmentType> appointmentTypes { get; set; }
}
Controller:
public ActionResult AddAppointment(Models.AppointmentViewModel avm)
{
BLL.FTSPManager fm = new BLL.FTSPManager();
DTO.Appointment a = new DTO.Appointment()
{
Id = avm.AppointmentId_Input,
Info = avm.AppointmentTitle_Input,
Name = avm.AppointmentName_Input,
StartTime = avm.AppointmentStartTime_Input,
EndTime = avm.AppointmentEndTime_Input,
type = new DTO.AppointmentType()
{
Id = avm.AppointmentType_Input
}
};
return Json(avm);
}
Ajax Request:
$('#btnAdd').click(function () {
var id, title, name, startTime, endTime, AppointmentType
id = $('#hdnAppointmentId').val();
title = $('#txtTitle').val();
name = $('#txtName').val();
startTime = $('#txtStartDate').val();
endTime = $('#txtEndDate').val();
AppointmentType = $('#drptype').val();
var JsonData = {
AppointmentId_Input: id,
AppointmentTitle_Input: title,
AppointmentName_Input: name,
AppointmentStartTime_Input: startTime,
AppointmentEndTime_Input: endTime,
AppointmentType_Input: AppointmentType
};
$.ajax({
type: "POST",
url: '#Url.Action("AddAppointment", "Admin")',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(JsonData),
dataType: "json",
success: function (data) {
return false;
}
});
})
You can use a FormData function. I can give for you a working example:
Html code(button, without other "input" tags:
<div class="form-group">
<button type="button" id="dataSend">DataSend</button>
</div>
Javascript code:
$("#dataSend").on('click', function () {
var formData = new FormData();
formData.append('Image', $('#file')[0].files[0]);
formData.append('Title', document.getElementById('Title').value);
formData.append('Description', document.getElementById('Description').value);
formData.append('Topic', document.getElementById('Topic').value);
formData.append('AdditionalFields', JSON.stringify(obsFields));
$.ajax({
contentType: false,
processData: false,
type: 'POST',
url: '/Collection/Create',
data: formData,
success: function () {
console.log("success.");
},
error: function () {
console.log("error.");
},
});});
C# code(controller):
[HttpPost]
public async Task<IActionResult> Create(DataForm AllData)
{
return RedirectToAction("Action-method", "Controller");
}
C# code(model):
public class DataForm
{
public string Title { get; set; }
public string Description { get; set; }
[EnumDataType(typeof(Topic))]
public Topic? Topic { get; set; }
public IFormFile Image { get; set; }
public string AdditionalFields { get; set; }
}
Field "AdditionalFields" is a son converted and in Controller it deserialized to 'List list'.
I'm waiting for your questions.
I try to put some info into a new modal :
when I click on a button I want to open a new modal with good info of clicked pokemon.
I made controller :
public IActionResult Index()
{
#region ListeDesPokemons
var pokemonList = new List<PokemonModel>();
var Id = 1;
var Img = 1;
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Bulbizarre", UsName = "Bulbasaur(us)", JpName = "フシギダネ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://www.pokemontrash.com/pokedex/images/sugimori/00" + Img++ + ".png" });
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Herbizarre", UsName = "Ivysaur(us)", JpName = "フシギソウ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://www.pokemontrash.com/pokedex/images/sugimori/00" + Img++ + ".png" });
var model = new PokemonViewModel();
model.Pokemons = pokemonList;
return View(model);
I made a Viewmodel :
public List<PokemonModel> Pokemons { get; set; }
public List<PokeBallModel> PokeBalls { get; set; }
public List<PokemonStatutModel> PokemonStatuts { get; set; }
}
I made a Model :
public int Id { get; set; }
public string Name { get; set; }
public string UsName { get; set; }
public string JpName { get; set; }
public string Type1 { get; set; }
public string Type2 { get; set; }
public int Rate { get; set; }
public string Image { get; set; }
I made a view :
#foreach (var pokemon in Model.Pokemons){ #pokemon.Id,#pokemon.Name #pokemon.Image}
here a picture of the first modal on the back of the screen with all pokemon list (foreach)
and the second modal on the front of the screen with no info.
please help.
I think you don't need to use form and should use ajax, when user click the picture of pokemon, you call an ajax with the Id of this pokemon, and in the controller you search all infos of pokemon with Id, and success in ajax just add infomations to the modal dialog. Something like:
<img class="align-self-center" id="tailleImg" src="#pokemon.Image" alt="#pokemon.Name" onclick="getInfo(#pokemon.Id)" />
function getInfo(val)
{
$.ajax({
url: '/yourController/yourActionToGetInfo',
type: "POST",
dataType: "json",
data: { "pokeId": val},
success: function (data) {
$("#pokeId").val(data.Id);
}
})
}
ok
In my view, in my foreach I add :
#foreach (var pokemon in Model.Pokemons)
{
<div class="col">
<button data-pokemon-id="#pokemon.Id" type="submit" class="btn" onclick="getInfo();">
<div class="card text-center rounded-lg">
<div id="tailleCard" class="card-body">
<h5 id="cardTitle" class="card-title">n°#pokemon.Id <br /> #pokemon.Name</h5>
<img id="tailleImg" src="#pokemon.Image" alt="#pokemon.Name" />
</div>
</div>
</button>
</div>
}
# the end of the view I add : But the Request does not exist in the current context nedd help please.
<script>
function getInfo() {
$.post('#(Url.Action("PokemonDetails", "Pokedex", null, Request.Url.Scheme))?pokemonId=' +
$(this).data("pokemon-id"))
.done(function (response) {
$("#divContent").empty();
$("#divContent").html(response);
$("#divContent").html(response);
$('#pokemonDetailsModal').modal('show');
});
</script>
In the controller I add a :
public IActionResult PokemonDetails(int pokemonId)
{
var model = new PokemonDetails();
return PartialView("_PokemonDetails", model);
}
I also made a Partial view _ and a PokemonDetail Model
public class PokemonDetails
{
public string Name { get; set; }
}
What I try to do it's to take the data of the selected pokemon (with the button in the foreach) and put the data of the selected pokemon in New Modal.
OK i almost there ! cool
in the view
...
#foreach (var pokemon in Model.Pokemons)
{
<button type="submit" class="btn" onclick="getInfo(#pokemon.Id)">
<div class="card text-center rounded-lg">
<div id="tailleCard" class="card-body">
<h5 id="cardTitle" class="card-title">n°#pokemon.Id <br /> #pokemon.Name</h5>
<img id="tailleImg" src="#pokemon.Image" alt="#pokemon.Name" />
</div>
</div>
</button>
}
...
at the end of the view page :
<script>
function getInfo(val) {
event.preventDefault;
//debug log
console.log('Star getInfo()');
$.ajax({
url: '/Pokedex/PokemonDetails/',
type: 'POST',
dataType: "html",
data: { "PokemonId": val },
//data: json,
//contentType: 'application/json; charset=utf-8',
success: function (response) {
//debug log
console.log(val);
$("#pokemonDetails").html(response);
$('#pokemonDetails').modal('show');
}
})
}
</script>
in the controller :
[HttpPost]
public IActionResult PokemonDetails(int PokemonId)
{
int SelectedPokemonId = PokemonId;
TempData["SelectedPokemonId"] = SelectedPokemonId;
ToDoo : Get Info of the pokemon from the Id
return PartialView("_PokemonDetails");
}
How I can get the info of the selected pokemon from the selected Id???
https://i.stack.imgur.com/atajO.png
[HttpPost]
public IActionResult PokemonDetails(int PokemonId)
{
int SelectedPokemonId = PokemonId;
TempData["SelectedPokemonId"] = SelectedPokemonId;
ToDoo : Get Info of the pokemon from the Id
return PartialView("_PokemonDetails");
}
Do you have database ? if you have just call:
return (db.PokemonModel.FirstOrDefault(n=>n.Id == PokemonId));
and if you don't have use the list you use in action Index:
return pokemonList.FirstOrDefault(n=>n.Id == PokemonId));
and in sucess ajax:
success: function (response) {
$("#cardTitle").html("n°" + response.Id +"<br />" + response.Name");
$("#tailleImg").attr('src', response.Image);
$("#tailleImg").attr('name', response.Name);
$('#pokemonDetails').modal('show');
}
I have Web API controller in mt server side
[HttpPost("CreateImage")]
public void CreateImage([FromBody] ImageDTO img)
{
Image image = new Image { FileName = img.FileName };
byte[] imageData = null;
using (var binaryReader = new BinaryReader(img.Image.OpenReadStream()))
{
imageData = binaryReader.ReadBytes((int)img.Image.Length);
}
image.Picture = imageData;
imageRepo.Create(image);
}
Where ImageDTO is
public class ImageDTO
{
public string FileName { get; set; }
public IFormFile Image { get; set; }
}
and Image.cs like this
public class Image
{
public int Id { get; set; }
public string FileName{ get; set; }
public byte[] Picture { get; set; }
public List<User> Users { get; set; }
}
And this is what I using for handling and sending image on React client:
<form>
<p>
<label>Аватар</label>
<input name="Avatar" id = 'img' type="file" class="form-control" onChange={(e)=>this.handleImageChange(e)}/>
</p>
<p>
<input type="submit" value="Добавить" onClick={this.sendImage}/>
</p>
</form>
<div className="imgPreview">
{$imagePreview}
</div>
function for handling file into state
handleImageChange(e) {
e.preventDefault();
let form = new FormData();
for (var index = 0; index < e.target.files; index++) {
var element = e.target.files[index];
form.append('file', element);
}
this.setState({file: form});
}
sending it on server
async sendImage(event) {
event.preventDefault();
console.log(this.state.file);
await addImage(this.state.file);
console.log('it works');}
addImge function:
addImage = async ( image) => {
await fetch('https://localhost:44331/api/users/CreateImage',
{
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + sessionStorage.tokenKey
},
body: JSON.stringify({
FileName: 'Img',
Image: image
})
}
)
}
But when it`s sending request on server it return Error 400, which means "Bad Request". So I think it is may be wrong type of data sent or something like that. Maybe someone sees a mistake or something that can be fixed. Or someone could show a working example of sending images from React to Web Api server. I need your help guys!
For uploading, you need to pay attention to points below:
You need to use formdata with FromForm
The fields in formdata should be corresponding to the model fields.
Steps:
Change the Controller action.
public void CreateImage([FromForm] ImageDTO img)
{
}
Client Code:
async sendImage(event) {
event.preventDefault();
console.log(this.state.file);
await this.addImage(this.state.file);
console.log('it works');
};
addImage = async (image) => {
await fetch('https://localhost:44385/api/users/CreateImage',
{
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer ' + sessionStorage.tokenKey
},
body: this.state.file
}
)
}
handleImageChange(e) {
e.preventDefault();
let form = new FormData();
for (var index = 0; index < e.target.files.length; index++) {
var element = e.target.files[index];
form.append('image', element);
}
form.append('fileName', "Img");
this.setState({ file: form });
};
In the controller WidgetConfigurationRequestVM request object
is returning 3 properties (lists) as null
jurisidctions
tags
workareas
I have binded this in the view and I am sure there is data set. They have same method types IEnumerable, why companyid binding and the other properties not binding in WidgetConfigurationRequestVM? Thank you for help!
API Controller:
[Route("api/track/v1/taxibriefing")]
public async Task<TaxiContainerModel> Post([FromBody] WidgetConfigurationRequestVM request)
{
request.Jurisidctions/tags/workareas = null?
request.companyId = exists
}
JS:
taxiBriefingButton.click(function (e) {
e.preventDefault();
var widgets = taxiConfigurationContainer.serialize();
var workAreaRefs = $(this).data("workarearefs");
var jurisdictions = $(this).data("jurisdictions");
var tags = $(this).data("tags");
var preset = $(this).data("preset");
createPdf($(this).data('companyid'), widgets, $('#notes').val(), workAreaRefs, jurisdictions, tags);
});
JS create PDF button:
function createPdf(companyId, widgets, notes, workAreaRefs, jurisdictions, tags) {
var doc = new PDFDocument({
bufferPages: true,
size: [842, 595]
});
window.dispatchEvent(GeneratingTaxiBriefingEvent);
var xhr = new XMLHttpRequest();
xhr.open('GET', '/taxiFonts/Roboto-Light.ttf', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
if (this.status == 200) {
doc.registerFont('Roboto', xhr.response);
$.ajax({
type: 'POST',
url: '/api/track/v1/taxibriefing',
contentType : 'application/json',
data: JSON.stringify({ CompanyId: companyId, Notes: notes, Configuration: widgets, Workareas: workAreaRefs, Jurisdictions: jurisdictions, Tags: tags }),
dataType: 'json',
success: function (result) { GeneratePDF(doc, result); }
});
}
};
xhr.send();
}
View:
#model Areas.Track.Models.TrackVM
<button id="taxi-briefing" class="btn btn-danger" data-preset="#Model.Filter.DatePreset" data-workarearefs="#Model.Filter.WorkareaRefs" data-jurisdictions="#Model.Filter.JurisdictionRefs" data-tags="#Model.Filter.TagsRefs" data-companyid="#Model.Filter.FirmRefs.First()">Create PDF</button>
Viewmodel:
public class WidgetConfigurationRequestVM
{
public int CompanyId { get; set; }
public string Notes { get; set; }
public IEnumerable<WidgetConfigurationVM> Configuration { get; set; }
public IEnumerable<int> Workareas { get; set; }
public IEnumerable<int> Jurisdictions { get; set; }
public IEnumerable<int> Tags { get; set; }
}