Just don't get it what i'm doing wrong..
i've been looking for dozens of similar questions, yet still got misunderstandings...
when i call CallHandler function from JS, i always get 'Request Failed' alert.
please help me.
JS/Jquery:
function CallHandler() {
$.ajax({
url: "DemoHandler.ashx",
contentType: "application/json; charset=utf-8",
type: 'POST',
dataType: "json",
data: [{"id": "10000", "name": "bill"},{"id": "10005", "name": "paul"}],
success: OnComplete,
error: OnFail
});
return false;
}
function OnComplete(result) {
alert(result);
}
function OnFail(result) {
alert('Request Failed');
}
asp.net c# code behind:
public void ProcessRequest(HttpContext context)
{
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
string jsonString = HttpContext.Current.Request.Form["json"];
List<Employee> emplList = new List<Employee>();
emplList = jsonSerializer.Deserialize<List<Employee>>(jsonString);
string resp = "";
foreach (Employee emp in emplList){
resp += emp.name + " \\ ";
}
context.Response.Write(resp);
}
public class Employee
{
public string id { get; set; }
public string name { get; set; }
}
Try
data: JSON.stringify([{id: "10000", name: "bill"},{id: "10005", name: "paul"}])
edit I removed the quotes from the property names
Also, the JSON string needs to be read in other way
string jsonString = String.Empty;
HttpContext.Current.Request.InputStream.Position = 0;
using (StreamReader inputStream = new StreamReader(HttpContext.Current.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
}
An working solution
public void ProcessRequest(HttpContext context)
{
var jsonSerializer = new JavaScriptSerializer();
var jsonString = String.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
}
var emplList = jsonSerializer.Deserialize<List<Employee>>(jsonString);
var resp = String.Empty;
foreach (var emp in emplList)
{
resp += emp.name + " \\ ";
}
context.Response.ContentType = "application/json";
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.Write(jsonSerializer.Serialize(resp));
}
public class Employee
{
public string id { get; set; }
public string name { get; set; }
}
public bool IsReusable
{
get
{
return false;
}
}
Related
I'm stuck on an issue. I am trying to access an observable Value from my controller. The data is stored in a JSON object. What's the best way to access it from a controller.
This is my VM
var urlPath = window.location.pathname;
var CreateSalesVM = {
Image :ko.observable({
base64StringArray: ko.observableArray()
}),
btnCreateSales: function () {
console.log("Ko is ", ko.toJSON(this));
$.ajax({
url: urlPath,
type: 'post',
dataType: 'json',
data: ko.toJSON(this),
contentType: 'application/json',
success: function (result) {
console.log("This was a success");
// window.location.href = urlPath + '/';
alert(ko.toJSON(this));
console.log("Ko is ", ko.toJSON(this));
},
error: function (err) {
console.log("Ko is ", ko.toJSON(this));
if (err.responseText == "success")
{
console.log("This was an error success", urlPath);
// window.location.href = urlPath + '';
}
else {
alert(err.responseText);
// console.log("This was an error ", urlHostPath );
}
},
complete: function () {
}
});
}
};
ko.applyBindings(CreateSalesVM);
This is the controller
public ActionResult Create()
{
return View();
}
// POST: Sales/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
public string Create(SALE_ITEMS sALE_ITEMS)
{
//used for testing since image won't come over
byte[] test = Encoding.ASCII.GetBytes("1232434234");
try
{
var sALE_ITEM_IMAGES = new SALES_ITEM_IMAGES();
Debug.Write("SALES DATA is", sALE_ITEMS);
db.SALE_ITEMS.Add(sALE_ITEMS);
db.SaveChanges();
// Getting id from primary to store record in foreign
decimal newID = sALE_ITEMS.SALE_ID;
Debug.Write("SALES DATA is", newID.ToString());
sALE_ITEM_IMAGES.SALE_ITEM_ID = newID;
//This is where I need to grab the base64 and store it inside sALE_ITEM_IMAGES.IMAGE
sALE_ITEM_IMAGES.IMAGE = sALE_ITEMS.IMAGE;
// Do whatever you need to here
db.SALES_ITEM_IMAGES.Add(sALE_ITEM_IMAGES);
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
Debug.Write(errorMessages);
}
return "success";
}
Here are my Models
public partial class SALE_ITEMS
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public SALE_ITEMS()
{
this.SALES_ITEM_IMAGES = new HashSet<SALES_ITEM_IMAGES>();
}
public decimal SALE_ID { get; set; }
public string USERID { get; set; }
public string NAME { get; set; }
public string PHONE { get; set; }
public string EMAIL { get; set; }
public string ITEM { get; set; }
public string DESCRIPTION { get; set; }
public string ADMIN_APPROVAL { get; set; }
public Nullable<System.DateTime> CREATED_AT { get; set; }
public Nullable<System.DateTime> UPDATED_AT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SALES_ITEM_IMAGES> SALES_ITEM_IMAGES { get; set; }
}
}
and
public partial class SALES_ITEM_IMAGES
{
public decimal ID { get; set; }
public decimal SALE_ITEM_ID { get; set; }
public byte[] IMAGE { get; set; }
public Nullable<System.DateTime> CREATED_AT { get; set; }
public virtual SALE_ITEMS SALE_ITEMS { get; set; }
}
Again, all I'm trying to do is access the base64 IMAGE bind from my Controller.
your view model CreateSalesVM at the client should match the same property names with server side model.
i modified your code, try this
// client side
var urlPath = window.location.pathname;
var CreateSalesVM = {
SALES_ITEM_IMAGES: ko.observableArray([{ //same as ICollection at server side
IMAGE: ko.observableArray([]) // same as byte[] at server side
}]),
btnCreateSales: function() {
var data = ko.toJSON(this);
console.log("Ko is ", data);
$.ajax({
url: urlPath,
type: 'post',
dataType: 'json',
data: data,
contentType: 'application/json',
success: function(result) {
console.log("This was a success");
// window.location.href = urlPath + '/';
console.log(result);
},
error: function(err) {
console.log("Ko is ", data);
if (err.responseText == "success") {
console.log("This was an error success", urlPath);
// window.location.href = urlPath + '';
} else {
alert(err.responseText);
// console.log("This was an error ", urlHostPath );
}
},
complete: function() {}
});
}
};
ko.applyBindings(CreateSalesVM);
and
// server side
[HttpPost]
public string Create(SALE_ITEMS item)
{
try
{
Debug.Write("SALES DATA is", item);
db.SALE_ITEMS.Add(item);
db.SaveChanges();
// Getting id from primary to store record in foreign
decimal newID = item.SALE_ID;
Debug.Write("SALES DATA is", newID.ToString());
// loop Images
foreach (var image in item.SALE_ITEM_IMAGES)
{
image.SALE_ITEM_ID = newID;
// Do whatever you need to here
db.SALES_ITEM_IMAGES.Add(image);
db.SaveChanges();
}
}
catch (DbEntityValidationException ex)
{
string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
Debug.Write(errorMessages);
}
return "success";
}
my entity
public class Agent
{
[Key]
[JsonProperty(PropertyName = "agentId")]
public int AgentId { get; set; }
[JsonProperty(PropertyName = "codeName")]
public string CodeName { get; set; }
[JsonProperty(PropertyName = "firstName")]
public string FirstName { get; set; }
[JsonProperty(PropertyName = "lastName")]
public string LastName { get; set; }
[JsonProperty(PropertyName = "imagePath")]
public string ImagePath { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
}
my Viewmodel
public class AgentVm
{
public int AgentId { get; set; }
public string CodeName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string ImagePath { get; set; }
public string Description { get; set; }
}
my Get web api controller
public IQueryable<AgentVm> GetAgents()
{
var agents = from b in db.Agents
select new AgentVm()
{
AgentId = b.AgentId,
FirstName = b.FirstName,
LastName = b.LastName,
CodeName = b.CodeName,
ImagePath = b.ImagePath
};
return agents;
}
my post web api controller
public async Task<HttpResponseMessage> PostAgent(Agent agent)
{
if (agent != null)
{
// Extract the image from the image string
string regEx = "data:(.+);base64,(.+)";
Match match = Regex.Match(agent.ImagePath, regEx);
if (match.Success)
{
// Get the content-type of the file and the content
string imageType = match.Groups[1].Value;
string base64image = match.Groups[2].Value;
if (imageType != null && base64image != null)
{
// Verify the content-type is an image
string imageRegEx = "image/(.+)";
match = Regex.Match(imageType, imageRegEx);
if (match.Success)
{
// Get the file extension from the content-type
string fileExtension = match.Groups[1].Value;
// Get the byte-array of the file from the base64 string
byte[] image = Convert.FromBase64String(base64image);
string path = HttpContext.Current.Server.MapPath("~/images");
string fileName = agent.FirstName + agent.LastName;
// Generate a unique name for the file (add an index to it if it already exists)
string targetFile = fileName + "." + fileExtension;
int index = 0;
while (File.Exists(Path.Combine(path, targetFile)))
{
index++;
targetFile = fileName + index + "." + fileExtension;
}
// Write the image to the target file, and update the agent with the new image path
File.WriteAllBytes(Path.Combine(path, targetFile), image);
agent.ImagePath = "images/" + targetFile;
db.Agents.Add(agent);
await db.SaveChangesAsync();
// Create the Location http header
var response = Request.CreateResponse(HttpStatusCode.Created, agent);
string uri = Url.Link("GetAgent", new { id = agent.AgentId});
response.Headers.Location = new Uri(uri);
return response;
}
}
}
}
throw new HttpResponseException(Request.CreateErrorResponse(
HttpStatusCode.BadRequest, "Could not deserialize agent"));
}
and this is my js
var ViewModel = function() {
var self = this;
self.agents = ko.observableArray();
self.error = ko.observable();
self.agent = ko.observableArray();
self.newAgent = {
FirstName: ko.observable(),
LastName: ko.observable(),
CodeName: ko.observable(),
Description: ko.observable(),
ImagePath: ko.observable()
}
var agentsUrl = "/api/agents/";
function ajaxHelper(uri, method, data) {
self.error(""); // Clear error message
return $.ajax({
type: method,
url: uri,
dataType: "json",
contentType: "application/json",
data: data ? JSON.stringify(data) : null
}).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
function getAllAgents() {
ajaxHelper(agentsUrl, "GET").done(function (data) {
self.agents(data);
});
}
self.addAgent = function (formElement) {
var agent = {
AgentId: self.newAgent.Agent().AgentId,
FirstName: self.newAgent.FirstName(),
LastName: self.newAgent.LastName(),
CodeName: self.newAgent.CodeName(),
Description: self.newAgent.Description(),
ImagePath: self.newAgent.ImagePath()
};
ajaxHelper(agentsUrl, 'POST', agent).done(function (item) {
self.agents.push(item);
});
}
getAllAgents();
};
ko.applyBindings(new ViewModel());
and this is my image element
<img data-bind="attr:{ src: ImagePath }"/>
but the image is not displaying and i can't figure out to add an upload,
please someone help , i don't need angular , just a simple mvvm such as knockout js but am relative new in it.
Look at the generated <img> element with Chrome console, or Firebug from firefox (specially the src property). Then copy the URL in a new tab and check if its displayed. I think your problem is that the element is rendered correctly, but your project cannot render direct images, as MVC will try to use the route logic to find the controller/action you are requesting, returning an HTTP 404. Check this response for a solution
You can create a simple form to upload files, or perhaps you can use jquery $.post, if you want to use ajax. Here is a sample for that
I am passing a collection of values through ajax, then i can not able to retrieve these values from webmethod by foreach procedure.
my collection variable is var Leave = { "Date": [], "Half": [] };
Passing Leave to webmethod but it is not possible to retrieve values
.pls help me.
my code is
empid = document.getElementById("hdnemployee").value;
if (empid != "") {
var Leave = { "Date": [], "Half": [] };
$('.leave_item').each(function () {
var cur = $(this);
var thisdate = cur.find('.txtdate').val();
Leave.Date.push(thisdate);
if (cur.find('.ckbhalfday').is(':checked'))
Leave.Half.push(1);
else
Leave.Half.push(0);
});
var arr = new Array();
console.log(Leave);
arr[0] = document.getElementById('drpLeavetype').value;
//arr[1] = document.getElementById('TxtDatefrom').value;
//arr[2] = document.getElementById('TxtDateTo').value;
arr[3] = document.getElementById('Txtnumdays').value;
arr[4] = document.getElementById('txtDiscription').value;
if (arr[4] != "")
{
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
url: "Applyleave.aspx/saveleaveApply",
data: JSON.stringify({ empid: empid,Leave:Leave, arr: arr }),
success: function (msg) {
// document.getElementById("tblleaveapply").innerHTML = "";
$('#tblleaveapply').empty();
alert(msg.d);
resettxtfields();
BindLADetails();
},
error: function (msg) { alert(msg.d); }
});
}
else
{
alert("Give Reason");
}
}
else {
alert("Select employee");
}
WebMethod:-
[WebMethod]
public static string saveleaveApply(string empid, object Leave, params string[] arr)
{
foreach( var c in Leave)
{
}
}
You can't use a foreach statement on an object unless it implements IEnumerable or IEnumerable<T> interface. What you need to do is define a Type in your code behind which will map to the JSON object something like this:-
public class Leave
{
public string[] Date { get; set; }
public string[] Half { get; set; }
}
Then you can modify your WebMethod as follows and iterate over the items:-
[WebMethod]
public static string saveleaveApply(string empid, Leave Leave, params string[] arr)
{
foreach( var c in Leave.Date)
{
}
foreach( var c in Leave.Half)
{
}
}
Update:
Although, I personally won't use this type, instead I will use:-
public class Leave
{
public string Date { get; set; }
public string Half { get; set; }
}
You need to fill this type in JS like this:-
var leave = new Array();
$('.leave_item').each(function() {
var cur = $(this);
var thisdate = cur.find('.txtdate').val();
var thishalf;
if (cur.find('.ckbhalfday').is(':checked'))
thishalf = 1;
else
thishalf = 0;
leave.push({ "Date": thisdate, "Half": thishalf });
});
And Finally the WebMethod will look like this:-
[WebMethod]
public static string saveleaveApply(string empid, Leave[] Leave, params string[] arr)
{
foreach( var c in Leave)
{
}
}
Refer to the comment inside the ajax success function:
function CreateProjectTree(sc)
{
$.ajax({
type: "POST",
url: "../api/projects/SearchProjects",
data: sc,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data)
{
if ($(data).length === 1)
{
window.location.replace("../ViewProjectDetails.aspx?ProjectId=" + //here's where I need to get the id;
}
else
{
buildTree(data);
}
},
});
}
This is what the controller looks like for the post:
public class ProjectsController : ApiController
{
public List<Item> SearchProjects(GBLProjectSearchCriteria searchCriteria)
{
var ProjectSearchResult = new ProjectSearchResultController();
searchCriteria.SearchType = "P";
searchCriteria.QueryString = "?ProjectId=";
var GBLProjectSearchResultListData = ProjectSearchResult.GetProjectSearchResultList(searchCriteria);
var projectList = (from GBLProjectSearchResult item in GBLProjectSearchResultListData
select new Item
{
Id = item.Id,
Title = item.Title,
Url = item.NavigateUrl + item.QueryString
}).ToList();
foreach (var project in projectList)
{
//seasons
project.Items = new List<Item>();
var SeasonSearchResult = new ProjectSearchResultController();
searchCriteria.Id = project.Id;
searchCriteria.SearchType = "S";
searchCriteria.QueryString = "?ProjectId=" + project.Id + "&SeasonId=";
var GBLSeasonSearchResultListData = SeasonSearchResult.GetProjectSearchResultList(searchCriteria);
foreach (var season in from GBLProjectSearchResult item in GBLSeasonSearchResultListData
select new Item
{
Id = item.Id,
Title = item.Title,
Url = item.NavigateUrl + item.QueryString
})
{
project.Items.Add(season);
project.HasChildren = (project.Items.Count > 0);
}
foreach (var season in project.Items)
{
//episodes
season.Items = new List<Item>();
var episodeSearchResult = new ProjectSearchResultController();
searchCriteria.Id = season.Id;
searchCriteria.SearchType = "E";
searchCriteria.QueryString = "?ProjectId=" + project.Id + "&SeasonId=" + season.Id + "&EpisodeId=";
var GBLEpisodeSearchResultListData = episodeSearchResult.GetProjectSearchResultList(searchCriteria);
foreach (GBLProjectSearchResult item in GBLEpisodeSearchResultListData)
{
var episode = new Item
{
Id = item.Id,
Title = item.Title,
Url = item.NavigateUrl + item.QueryString
};
season.Items.Add(episode);
season.HasChildren = (season.Items.Count > 0);
}
}
}
return projectList;
}
public class Item
{
readonly string take2Root = ConfigurationManager.AppSettings["Take2Root"];
private string url;
public int Id
{
get;
set;
}
public string Title
{
get;
set;
}
public bool HasChildren
{
get;
set;
}
public List<Item> Items
{
get;
set;
}
public string Url
{
get
{
return url;
}
set
{
url = take2Root + value.Replace("..", "");
}
}
}
}
I need to get the ID of the parent node returned by this controller.
I would know how to work with a GET request, however, I have to do a POST here and I'm unsure on how to extract the ID inside the ajax success function.
Can someone give me a hand?
Thanks!
inside your if ($(data).length === 1) statement you can add debugger; (or set a break-point) then examine the data object using chrome's developer tools. The id you're after will be something like data.objects[0].id
I have been having a issue when I post form data to my webservice. When I debug the web service the parameter messagepost has a count of 1 but the object data is empty, but when I look at the object in the request I can see that the object is populated. I've been searching and racking my brain for an hour and can't see me to get it to work. So maybe someone here can help me out.
Javascript
function getEmptyLeg() {
var chkTail = $("#elTail").is(':checked');
var chkType = $("#elType").is(':checked');
var chkNBAA = $("#chkNBAA").is(':checked');
var chkCategory = $("#elCategory").is(':checked');
var itineraryList = new Array();
var itinerary = new Object();
itinerary.Time = "";
itinerary.Arrival = $("#elTo").val();
itinerary.Departure = $("#elFrom").val();
itinerary.ArrivalDate = getDate("#elEndDate");
itinerary.DepartureDate = getDate("#elStartDate");
itineraryList.push(itinerary);
var messagepost = new Object();
messagepost.Types = "";
messagepost.Categories = "";
messagepost.ShowTail = chkTail;
messagepost.ShowType = chkType;
messagepost.SendToNBAA = chkNBAA;
messagepost.DirectoryAircraft = false;
messagepost.ShowCategory = chkCategory;
messagepost.Price = $("#elPrice").val();
messagepost.NBAAEmail = $("#txtEmail").val();
messagepost.MessageItinerary = itineraryList;
messagepost.AircraftID = $("select#elAircraft").val();
return messagepost;
}
function saveMessage() {
var options = "";
var type = $("#hdfType").val();
var userid = $('#<%= hdfUserID.ClientID %>').val();
var message = $("#<%= txtMessage.ClientID %>").val();
var timezone = $('#<%= hdfTimezone.ClientID %>').val();
$('#<%= sltUsers.ClientID %> option:selected').each(function (i) {
options += $(this).val() + ",";
});
var messagepost = new Array();
messagepost.push(getEmptyLeg());
$.ajax({
type: "Post",
async: false,
dataType: "json",
contentType: "application/json; charset=utf-8",
url: "/Resources/MessageWebService.asmx/SaveMessage",
data: "{ 'message':'" + message + "',"
+ "'options':'" + options + "',"
+ "'url':'" + $(location).attr('href') + "',"
+ "'userid':'" + userid + "',"
+ "'messageid':'" + 0 + "',"
+ "messagepost:" + JSON.stringify(messagepost) + ","
+ "'postType':'" + type + "' }",
success: function (data) {
$('#messages').prepend($(data.d).fadeIn('slow'));
growlMessage('Message was successfully');
},
error: function (data) {
showError(data.responseText);
}
});
}
web service
[WebMethod]
public string SaveMessage(string message, string options, string url, string userid, string messageid, List<MessagePost> messagepost, string postType) {
}
Request from chrome
{ 'message':'empty leg','options':'Public,','url':'http://localhost/portal/quote.aspx?qid=254','userid':'d2703dd0-c743-4995-ac93-5cfab7fa5205','messageid':'0',messagepost:[{"Types":"","Categories":"","ShowTail":true,"ShowType":true,"SendToNBAA":true,"DirectoryAircraft":false,"ShowCategory":true,"Price":"2500","NBAAEmail":"chad.neiro#avianis.com","MessageItinerary":[{"Time":"","Arrival":"KSAN","Departure":"ENNA","ArrivalDate":"12/21/2012","DepartureDate":"12/21/2012"}]}],'postType':'4' }
message post class
public class MessagePost
{
Boolean ShowTail { get; set; }
Boolean ShowType { get; set; }
Boolean SendToNBAA { get; set; }
Boolean ShowCategory { get; set; }
Boolean DirectoryAircraft { get; set; }
string Types { get; set; }
string Price { get; set; }
string NBAAEmail { get; set; }
string AircraftID { get; set; }
string Categories { get; set; }
List<MessageItinerary> ItineraryList { get; set; }
}
public class MessageItinerary
{
string Time { get; set; }
string Arrival { get; set; }
string Departure { get; set; }
string ArrivalDate { get; set; }
string DepartureDate { get; set; }
string Preference { get; set; }
}
Like saarps suggests in the comments, I also believe this has to do with JSON and deserialization of the data.
I gave up paramaters in my WebMethods early, and retrieve the data from the Request instead.
Example, the following code:
[WebMethod]
public string SaveMessage(string message) {
//Do something
}
would instead be written like this:
[WebMethod]
public string SaveMessage() {
string message = HttpContext.Current.Request.Form["message"];
//Do something
}