My Ajax block looks like so:
$('#btnTest').click(function(){
$.getJSON('/User/ViewMessages',function(result) {
// TODO: update the DOM with the items
$("table#tblMessages").append("<tr><td>"+result.MESSAGETEXT+"</td><td>"+result.DATESENT+"</td>");
});
});
My Action in my Controller looks like such:
public ActionResult ViewMessages()
{
var recipient = Convert.ToInt32(HttpContext.Session["User_Id"]);
var query = (from m in context.Messages
from rec in context.Recipients
where rec.RECIPIENT == recipient
where rec.MESSAGEID == m.MESSAGEID
select new
{
m.MESSAGETEXT,
m.DATESENT
}).ToList();
return Json(query.ToList());
}
When Debugging, my query variable returns:
{ MESSAGETEXT = "seresr", DATESENT = {9/15/2011 11:06:45 AM} }
The thing is, my table is added with "undefined" for both my values. Where have i gone wrong? I have already added the maproute as well, but I'm still out of luck.
It looks like you're returning a list, which will be represented in JSON as an array. So your result object is a JavaScript array rather than a single object. To loop through all the items and add a table row for each, try something like this:
$.getJSON('/User/ViewMessages', function(result) {
for (var i in result) {
var row = result[i];
$("table#tblMessages").append("<tr><td>" + row.MESSAGETEXT
+ "</td><td>" + row.DATESENT + "</td>");
}
});
Related
Im struggling with a json object.
I create the object (RO) with the following code and that Works fine.
string reply = #"" + client.UploadString(url, "POST", LS_json);
RootObject RO = new RootObject();
RO = JsonConvert.DeserializeObject<RootObject>(reply);
RO now contains all the data I have recieved through the json search.
Now, when iterating through the object the foreach iterate one more than (RO) contains:
cnt_V = 0;
foreach (object obj_attributtertype in RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter[cnt_V].type)
{
if (Convert.ToString(RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes[cnt_V].values[0].value);
}
cnt_V++;
}
The thing is that when cnt_V == 4 and "points" to the last entry attributes[cnt_V] then LS_ande is filled as supposed (=="KEY_VALUES").
But then the foreach iterates again (cnt_V == 5), no problem here, but when it is assigned to LS_ande then it dumps (of cource because there is no entry with data for cnt_V == 5).
I dont understand whats wrong. Please be gentle with me and feel free to ask for further information.
Thanks in advance.
While I can't answer this definitively because I don't have the data, this is what I would start with:
//take out the long and lengthy parts to make the rest clearer
//I see there are two things here, intentional?
var something = RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter;
var somethingElse = RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes;
cnt_V = 0;
//Here, you are iterating over something[cnt_V].type, but also change cnt_V in the body.
//Are you sure this is correct?
foreach (object obj_attributtertype in something[cnt_V].type)
{
if (Convert.ToString(somethingElse[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(somethingElse[cnt_V].values[0].value);
}
cnt_V++;
}
And looking at it that way, here is my stab in the dark.
Iterate with a for over the Count() of items in something
var something = RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter;
var somethingElse = RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes;
for (var cnt_V = 0; cnt_V < something.Count(); ++cnt_V)
{
if (Convert.ToString(somethingElse[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(somethingElse[cnt_V].values[0].value);
}
cnt_V++;
}
This is my controller:
public JsonResult PostFunction(Post post,IEnumerable<int> MultipleTags)
{
post.PostedBy = User.Identity.GetUserId<int>();
post.PostedDate = DateTime.UtcNow;
foreach (var tagId in MultipleTags)
{
var tag = new Tag { TagId = tagId };
db.Tags.Attach(tag); // this avoids duplicate tags
post.Tags.Add(tag);
}
db.Posts.Add(post);
db.SaveChanges();
var usr = db.Users.FirstOrDefault(x => x.Id == post.PostedBy);
{
Message = post.Message,
// here, i am getting nothing but it should return back tagnames
TagName = string.Join(",", post.Tags.Select(t => t.TagName)),
PostedBy = post.PostedBy,
PostedByName = post.ApplicationUser.UserName,
};
return Json( ret,JsonRequestBehavior.AllowGet);
}
Howerever, data is properly got inserted into the database but this ret var is giving System.NullReferenceException. The line which is causing problem is TagName which should return comma seperated values.
If i Try something like this, then it works fine but it will not return the last inserted Post. means if in database, 7 posts are already there and after this new insertion, total no. of post are increased to 8 so it should return all 8 but it returns only 7 post excluding the latest one added.
var ret = from data in db.Posts.Include(x=> x.Tags)
.OrderByDescending(x => x.PostedDate).ToList()
select new
{
TagName = string.Join(",", data.Tags.Select(t => t.TagName)),
Now, how should i modify this anonymous function so that it should dynamically append the tags relating each post.
Actually, there is a textbox with multi select drop down. all the values from text box and dropdown goes to this controller but after submit button, the latest submitted post should be added to the page. but this anonymous function is causing error.it should pass correct data to knockout binding but the code get stuck here.I am sure there is nothing to do with knockout here.
I have also tried to put a variable with all the selected tags and then assign it to TagName like this:
var result = post.Tags.SelectMany(e => e.TagName);
// and in ret var,
TagName = string.Join(",", result)
but still getting NullReferenceException.
Please suggest me what should i try here.
You have to set the value for TagName where you create the tag:
foreach (var tagId in MultipleTags)
{
var tag = new Tag { TagId = tagId, TagName = "something" };
db.Tags.Attach(tag); // this avoids duplicate tags
post.Tags.Add(tag);
}
I'm passing a list of guids in a GET request from a JQuery Ajax call.
on my ASP.NET controller side I want to iterate through the list and update the Display_Sort column to match my newly sorted list.
My ID is a Guid and I'm getting a type error in the following code, because it's a string that I'm passing to the Db. However, I can't seem to convert the item(string) into a Guid.
I've tried Guid(item) and it would allow the constructor. Not sure what I'm missing.
Here is the code:
//REORDER HOME ASSETS
public ActionResult ReOrderHome()
{
using (var db = new IFEntities())
{
var myString = Request.QueryString;
var i = 1;
foreach (var item in myString)
{
var myObj = db.HomeContents.Find(item);
myObj.display_order = i;
db.SaveChanges();
i++;
}
}
You can convert item to GUID and then compare like this.
var myObj = db.HomeContents.Find(new Guid(item));
Or, you can use select instead of find. Syntax for select --
foreach (var item in myString)
{
var myObj = db.HomeContents.Select(p => p.<GUID_COLUMN_NAME> == item);
myObj.display_order = i;
db.SaveChanges();
i++;
}
Replace GUID_COLUMN_NAME with actual column name.
C# MVC web application
I have a button that adds input fields dynamically to my web page on a form.
I specifically give the dynamically added elements an id and name to conform to my Model so that they get passed back as an collection of like items to match a “Artists” collection property in my model.
So the input elements name and ids are for example
Artists[0].artist
Artists[1].artist
Artists[2].artist
In my model I have:
public Collection<Artist> Artists { get; set; }
public class Artist
{
public string artist { get; set; }
}
And here is my script to add remove an element:
var artists = new Array();
var AddArtist = function (e) {
artistname = $("#artistinput").val();
artists.push($("#artistinput").val());
var addDiv, artistVal;
addDiv = $("#artist");
artistVal = $("#artistinput").val();
var input_append = $('<div />'),
label = $('<input />', {
style: 'background-color:#e0ffff',
Value: artistVal,
id: 'artists[' + (artists.length - 1) + '].artist',
name: 'artists[' + (artists.length - 1) + '].artist',
readonly: true
}),
image = $('<img />', {
id: 'removeartist',
src: '/Content/bootstrap/img/cross-button.png',
on: {
click: function () {
input_append.remove();
artists.splice(artists.length - 1, 1);
var test = (artists.length - 1);
alert(test);
}
}
}
);
addDiv.append(input_append.append(label, image));
};
I can add/remove the elements on the actual page. The problem is, if I remove an element from the middle or beginning, the sequence of the name ids are broken and when the collection get passed back to my model the Artists collection is now empty.
So instead of
Artists[0].artist
Artists[1].artist
Artists[2].artist
This may be passed back:
Artists[0].artist
Artists[2].artist
Which is no longer a collection based on how the view is mapped to the model.
I need to rename all the name/ids in a ordered sequence once an item has been removed.
What’s the easiest solution for this problem.
So that this gets passed back
Artists[0].artist
Artists[1].artist
Okay here's what I used in a previous project to revise the IDs and names of inputs to allow model binding when posted to an MVC controller.
The first function takes an object and searches for all inputs, selects and textareas contained within it. The object you pass would probably be a row or div that contains all related inputs per Artist.
// Applies new id and name with correct number sequence to set fields
function reviseFieldNameAndId(obj, newNumber) {
obj.find('input,select,textarea').each(function () {
var parts = this.id.split(/_[\d+]__/); // Everything can be obtained from id only
this.id = parts[0] + '_' + newNumber+ '__' + parts[1]; // Payments_0__PaymentReasonId
this.name = parts[0] + '[' + newNumber+ '].' + parts[1]; // eg. Payments[0].PaymentReasonId
});
}
function reviseAllFieldNamesAndIds() {
$('#artists .row').each(function (index) {
reviseFieldNameAndId($(this), index);
});
}
Use the second function to go through all rows and perform the apply the new sequence.
PS - your answer is near enough the same as this but only works with artists whereas mine will work with different names and ids
I gave each dynamically added input item the same class name then used JavaScript to update and reorder every element id and name in an ordered sequence:
$('.divArtist').each(function (i, obj) {
this.id = 'artists[' + i + '].artist';
this.name = 'artists[' + i + '].artist';
});
I have list that have values like"
[0] = "{ id = ES10209005, views = 501 }"
[1] = "{ id = HYT0209005, views = 5678}"
[3] = "{ id = POI0209005, views = 4568}"
I would like to pass the values(id,views) to a method using a for each loop.
method(id,views)
Something like:
foreach (string v in updatereponse)
{
method()
}
How do I isolate each value(id,views) from each row in the list then pass it to the method?
The list contains just a bunch of strings, anything based on this to fix the problem would be just a workaround (e.g. string parsing). You should really switch to a strongly typed model, e.g. define a class ViewCount:
public class ViewCount
{
public string Id {get;set;}
public int Views {get;set;}
}
You can then use a List<ViewCount> populate the list:
List<ViewCount> viewcounts = new List<ViewCount>();
viewCounts.Add(new ViewCount() { Id = "ES10209005", Views = 501 });
Since each ViewCount instance has Id and Views properties you can now do the proper thing:
foreach (var item in updatereponse)
{
method(item.Id, item.Views);
}
If you are saving this data in a file, an alternative would be to use XML instead of custom strings, then you could use Linq to XML to populate a List<ViewCount>, e.g. using a simple XML like this:
<ViewCounts>
<ViewCount id="ES10209005" views="501" />
</ViewCounts>
You can then load your list:
XElement viewXml = XElement.Load("test.xml");
List<ViewCount> viewCounts = viewXml.Descendants("ViewCount")
.Select(x => new ViewCount()
{
Id = (string)x.Attribute("id"),
Views = (int)x.Attribute("views")
}).ToList();
foreach (string v in updateresponse)
{
var values = v.Split(",");
var id = values[0].Replace("{ id = ", "").Trim();
var view = values[1].Replace("views = ", "").("}","").Trim();
method(id, value);
}
Here's another way...you may want to add error checking:
String Data = "{ id = ES10209005, views = 501 }";
String[] Segments = Data.Split(new char[] { ' ', ',' });
string ID = Segments[3];
int views = int.Parse(Segments[7]);
Assuming the structure of your String is like you showed us always, this can work for you.
// First split id and views part.
String[] firstSplit = v.Split(',');
// Get the respected value for each part.
String id = firstSplit[0].Split('=')[1].Trim();
String views = firstSplit[1].Split('=')[1].Trim().Replace("}","");
You can use String methods to retrieve the items (use Split and SubString for example) or you can use a regular expression.
E.g.
var list = UpdateResponse[0].Split("=,} ") ;
will result in a list split by all these characters (including space).
Then check the correct indices to use (use a debugger for that). Then you get something like:
var id = list[5];
var views = list[8];
(note: check the indices 5 or 8, they are just a guess).