System.Collections.Generic.List`1[System.String]" JSON error - json

I'm trying to use JSON and I was use PostMan to return Response
this error happent
System.Collections.Generic.List`1[System.String]"}
public ActionResult SendVFCode(string Phone_Number)
{
var jsonSerialiser = new JavaScriptSerializer();
string error = "";
var SearchData ="";
if (Phone_Number == null)
{
error = "Must enter your phone number";
}
else if ( (db.PhoneNumbers.Select(x =>x.Id).Count() < 0)
&& (db.Assistant.Select(x =>x.Id).Count()) < 0)
{
error = "There are no data or your account is not activated";
}
else
{
SearchData = db.PhoneNumbers.Include(x => x.Assistant)
.Where(x => x.PhoneNumber == Phone_Number
&& x.Assistant.IsActive == true).Select(xx =>xx.PhoneNumber).ToList().ToString();
}
json = new
{
err = error,
ResultSearchData = SearchData
};
return Content(jsonSerialiser.Serialize(json));
}

SearchData is not a string. Don't declare it as string and don't try to shove a string into it. It's a List (probably of type List<string> or whatever your Phonenumber type is).
var SearchData =""
Should be:
List<string> SearchData;
And your database call should end in .ToList(), not .ToList().ToString().

Note that ToList() followed with ToString() returns fully-qualified name of the list instead of the list contents, hence you should use List<string> to hold result strings (also the list must be instantiated first before used inside if-block). The correct setup should be like this:
public ActionResult SendVFCode(string Phone_Number)
{
var jsonSerialiser = new JavaScriptSerializer();
string error = "";
var SearchData = new List<string>(); // instantiate list of strings
var phoneCount = db.PhoneNumbers.Select(x => x.Id).Count();
var assistantCount = db.Assistant.Select(x => x.Id).Count();
if (Phone_Number == null)
{
error = "Must enter your phone number";
}
else if (phoneCount < 0 && assistantCount < 0)
{
error = "There are no data or your account is not activated";
}
else
{
// assign list from query results
SearchData = db.PhoneNumbers.Include(x => x.Assistant)
.Where(x => x.PhoneNumber == Phone_Number && x.Assistant.IsActive == true)
.Select(xx => xx.PhoneNumber).ToList();
}
var json = new
{
err = error,
ResultSearchData = SearchData
};
return Content(jsonSerialiser.Serialize(json));
}

Related

How can I return two entity objects from web api?

What I am trying to do is getting two entity and returning from a single return using Json Object so getting this exception:-
Self referencing loop detected for property 'Job' with type 'System.Data.Entity.DynamicProxies
Here is what I am doing in code
[Route("api/Listing/GetAllList/{id:Guid}")]
[HttpGet]
public ResponseWrapper<GenericResponseModel> GetAllList(Guid id)
{
var heightSafety = database.HeightSafetyForms.Where(j => j.JobId == id).FirstOrDefault();
var chimneyTower = database.ChimneyTowerForms.Where(j => j.JobId == id).FirstOrDefault();
return ResponseService.ReturnResponse(() =>
{
if (heightSafety == null || chimneyTower == null)
{
return new GenericResponseModel(false, "Job could not be found.", null);
}
else
{
return new GenericResponseModel(true, string.Empty, Json(new
{
heightSafety = heightSafety,
chimneyTower = chimneyTower
}));
}
}, Request);
}
}
}
Created ModelHelper Class for ChimneyTower and HieghtSafety and assigned the values of the object of ChimneyTower to ChimneyTowerModelHelper object and then returned in the return statement

How do I consume a JSon object that has no headers?

My C# MVC5 Razor page returns a Newtonsoft json link object to my controller (the "1" before \nEdit |" indicates that the checkbox is checked:
"{\"0\": [\"6146\",\"Kimball\",\"Jimmy\",\"General Funny Guy\",\"277\",\"Unite\",\"Jun 2019\",\"\",\"\",\"1\",\"\nEdit |\nDetails\n\n \n\"],\"1\": [\"6147\",\"Hawk\",\"Jack\",\"\",\"547\",\"Painters\",\"Jun 2019\",\"\",\"\",\"on\",\"\nEdit |\nDetails\n\n \n\"]}"
How do I parse this?
I am using a WebGrid to view and I want to allow the users to update only the lines they want (by checking the checkbox for that row), but it doesn't include an id for the 's in the dom. I figured out how to pull the values, but not the fieldname: "Last Name" , value: "Smith"... I only have the value and can't seem to parse it... one of my many failed attempts:
public ActoinResult AttMods(string gridData)
{
dynamic parsedArray = JsonConvert.DeserializeObject(gridData);
foreach (var item in parsedArray)
{
string[] itemvalue = item.Split(delimiterChars);
{
var id = itemvalue[0];
}
}
I finally sorted this one out..If there is a more dynamic answer, please share... I'll give it a few days before I accept my own (admittedly clugy) answer.
if(ModelState.IsValid)
{
try
{
Dictionary <string,string[]> log = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string[]>>(gridData);
foreach (KeyValuePair<string,string[]> keyValue in log)
{
if (keyValue.Value[9] == "1")//Update this row based on the checkbox being checked
{
var AttendeeID = keyValue.Value[0];
int intAttendeeID = 0;
if (int.TryParse(AttendeeID, out intAttendeeID))//Make sure the AttendeeID is valid
{
var LName = keyValue.Value[1];
var FName = keyValue.Value[2];
var Title = keyValue.Value[3];
var kOrgID = keyValue.Value[4];
var Org = keyValue.Value[5];
var City = keyValue.Value[7];
var State = keyValue.Value[8];
var LegalApproval = keyValue.Value[9];
tblAttendee att = db.tblAttendees.Find(Convert.ToInt32(AttendeeID));
att.FName = FName;
att.LName = LName;
att.Title = Title;
att.kOrgID = Convert.ToInt32(kOrgID);
att.Organization = Org;
att.City = City;
att.State = State;
att.LegalApprovedAtt = Convert.ToBoolean(LegalApproval);
}
}
}
db.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
You can avoid assigning the var's and just populate the att object with the KeyValue.Value[n] value, but you get the idea.

Json data serialized with JsonConvert.SerializeObject is always string in ASP.NET Web API

I am developing a ASP.NET MVC Web Api. Project. I am returning data with JSON format. Before I return data to user I serialize data using JsonConvert.SerializeObject to change their json property names.My code return data in JSON format. But with an issue. That is it always return data into string even if the data is array or object.
This is my action method that returns json.
public HttpResponseMessage Get()
{
IEnumerable<Region> dbRegions = regionRepo.GetCachedRegions();
List<ContentRegion> regions = new List<ContentRegion>();
if(dbRegions!=null && dbRegions.Count()>0)
{
foreach(var region in dbRegions)
{
ContentRegion contentRegion = new ContentRegion
{
Id = region.Id,
ImageUrl = Url.AbsoluteContent(region.ImagePath),
SmallImageUrl = (String.IsNullOrEmpty(region.ImagePath))?null:Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath,AppConfig.SmallThumbSuffix)),
MediumImageUrl = (String.IsNullOrEmpty(region.ImagePath))?null:Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath,AppConfig.MediumThumbSuffix)),
Name = region.Name,
MmName = region.MmName,
Description = region.Description,
MmDescription = region.MmDescription,
Latitude = region.Latitude,
Longitude = region.Longitude
};
regions.Add(contentRegion);
}
}
string json = JsonConvert.SerializeObject(regions);
if(!string.IsNullOrEmpty(json))
{
json = json.Trim(new char[] { '"' });
}
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ObjectContent(json.GetType(),json,Configuration.Formatters.JsonFormatter)
};
}
Actually this code should return Json array. But when I parse data from client (from Android using Volley). It cannot be parsed into Json Array.
This is the data I get:
As you can see the double quote both in the beginning and at the end. The reason I cannot parse it into array in Volley is it is returning as a string because of that double. How can I serialize it trimming that quote? I used trim, but not removed.
You are unnecessarily complicating things. In Web API you can return JSON just by returning any object inside the built-in methods, the framework will serialize it for you.
public IHttpActionResult Get()
{
IEnumerable<Region> dbRegions = regionRepo.GetCachedRegions();
List<ContentRegion> regions = new List<ContentRegion>();
if(dbRegions != null && dbRegions.Count() > 0) {
foreach(var region in dbRegions)
{
ContentRegion contentRegion = new ContentRegion
{
Id = region.Id,
ImageUrl = Url.AbsoluteContent(region.ImagePath),
SmallImageUrl = (String.IsNullOrEmpty(region.ImagePath))?null:Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath,AppConfig.SmallThumbSuffix)),
MediumImageUrl = (String.IsNullOrEmpty(region.ImagePath))?null:Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath,AppConfig.MediumThumbSuffix)),
Name = region.Name,
MmName = region.MmName,
Description = region.Description,
MmDescription = region.MmDescription,
Latitude = region.Latitude,
Longitude = region.Longitude
};
regions.Add(contentRegion);
}
}
return Ok(regions);
}
As an aside: from what I can see you are mapping manually your domain objects into DTOs: take into consideration the use of an automatic mapping mechanism like AutoMapper.
I am not sure this is the best solution or not. I solved the problem using this way.
This is my action method
public HttpResponseMessage Get()
{
try
{
IEnumerable<Region> dbRegions = regionRepo.GetCachedRegions();
List<ContentRegion> regions = new List<ContentRegion>();
if (dbRegions != null && dbRegions.Count() > 0)
{
foreach (var region in dbRegions)
{
ContentRegion contentRegion = new ContentRegion
{
Id = region.Id,
ImageUrl = Url.AbsoluteContent(region.ImagePath),
SmallImageUrl = (String.IsNullOrEmpty(region.ImagePath)) ? null : Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath, AppConfig.SmallThumbSuffix)),
MediumImageUrl = (String.IsNullOrEmpty(region.ImagePath)) ? null : Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath, AppConfig.MediumThumbSuffix)),
Name = region.Name,
MmName = region.MmName,
Description = region.Description,
MmDescription = region.MmDescription,
Latitude = region.Latitude,
Longitude = region.Longitude
};
regions.Add(contentRegion);
}
}
string json = JsonConvert.SerializeObject(regions);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(json, Encoding.Default, "application/json")
};
}
catch
{
return Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}
It's not required to convert object to json string.
You can try :
return Request.CreateResponse<List<ContentRegion>>(HttpStatusCode.OK,regions);
Not tested.
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Use this line in your WebApiConfig.
And here your code should be
public HttpResponseMessage Get()
{
IEnumerable<Region> dbRegions = regionRepo.GetCachedRegions();
List<ContentRegion> regions = new List<ContentRegion>();
HttpResponseMessage temp = ControllerContext.Request.CreateResponse(HttpStatusCode.OK, "");
if (dbRegions != null && dbRegions.Count() > 0)
{
foreach (var region in dbRegions)
{
ContentRegion contentRegion = new ContentRegion
{
Id = region.Id,
ImageUrl = Url.AbsoluteContent(region.ImagePath),
SmallImageUrl = (String.IsNullOrEmpty(region.ImagePath)) ? null : Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath, AppConfig.SmallThumbSuffix)),
MediumImageUrl = (String.IsNullOrEmpty(region.ImagePath)) ? null : Url.AbsoluteContent(CommonHelper.GetImageUrl(region.ImagePath, AppConfig.MediumThumbSuffix)),
Name = region.Name,
MmName = region.MmName,
Description = region.Description,
MmDescription = region.MmDescription,
Latitude = region.Latitude,
Longitude = region.Longitude
};
regions.Add(contentRegion);
}
}
temp = ControllerContext.Request.CreateResponse(HttpStatusCode.OK, regions);
return temp;
//string json = JsonConvert.SerializeObject(regions);
//if (!string.IsNullOrEmpty(json))
//{
// json = json.Trim(new char[] { '"' });
//}
//return new HttpResponseMessage(HttpStatusCode.OK)
//{
// Content = new ObjectContent(json.GetType(), json, Configuration.Formatters.JsonFormatter)
//};
}

performing more than one Where in query return null!!! why? how to fix this?

i have wrote a method that filters output with provided query and return it. when one Where excuted; it return correct output but when more than one Where excuted; output is null and Exception occured with message "Enumeration yielded no results". why? how i can fix it?
public IQueryable<SearchResult> PerformSearch(string query, int skip = 0, int take = 5)
{
if (!string.IsNullOrEmpty(query))
{
var queryList = query.Split('+').ToList();
var results = GENERATERESULTS();
string key;
foreach (string _q in queryList)
{
if (_q.StartsWith("(") && _q.EndsWith(")"))
{
key = _q.Replace("(", "").Replace(")", "");
results = results.Where(q => q.Title.Contains(key, StringComparison.CurrentCultureIgnoreCase));
}
else if (_q.StartsWith("\"") && _q.EndsWith("\""))
{
key = _q.Replace("\"", "").Replace("\"", "");
results = results.Where(q => q.Title.Contains(key, StringComparison.CurrentCulture));
}
else if (_q.StartsWith("-(") && _q.EndsWith(")"))
{
key = _q.Replace("-(", "").Replace(")", "");
results = results.Where(q=> !q.Title.Contains(key, StringComparison.CurrentCultureIgnoreCase));
}
else
{
key = _q;
results = results.Where(q => q.Title.Contains(key, StringComparison.CurrentCulture));
}
}
this._Count = results.Count();
results = results.Skip(skip).Take(take);
this._EndOn = DateTime.Now;
this.ExecutionTime();
return results;
}
else return null;
}
thanks in advance ;)
string key;
foreach (string _q in queryList)
{
Ah, the expression binds to the key variable. You need a new key variable for each execution of the loop.
foreach (string _q in queryList)
{
string key;

AttachAll exception: type arguments for method cannot be inferred from the usage. Try specifying the type arguments explicitly

Scenario:
Trying to call the .AttachAll method on a table in my LinqToSql DataContext object.
Here's the relevant simplified snippet:
public void Update(Customer cust){
MyDataContext db = new MyDataContext();
db.CustomerInvoices.AttachAll(cust.Invoices); //exception raised here!
db.Customer.Attach(cust);
}
Exception raised by the Compiler:
The type arguments for method
'System.Data.Linq.Table(Invoices).AttachAll(TSubEntity)(System.Collections.Generic.IEnumerable(TSubEntity))'
cannot be inferred from the usage. Try
specifying the type arguments
explicitly.
Question: What is the proper way to cast the collection properly? Any other solutions besides a cast?
Tf cust.Invoices already refers to instances of the CustomerInvoices table, just doing
db.Customers.Attach(cust); db.Update(); should be all you need to do.
If CustomerInvoices is a different type from Customer.Invoice, you'll probably need to iterate through the collection, and cast each one.
else if (((CheckBox)item.Cells[2].FindControl("ckbSelect")).Checked == true && ((Label)item.Cells[2].FindControl("lblIsInuse")).Text == "1")
{
RolePage objTemp = new RolePage();
objTemp = new Helper().GetRolePagebyID(roleId, Convert.ToInt32(item.Cells[0].Text));
rp.RoleId = objTemp.RoleId;
rp.PageId = objTemp.PageId;
rp.RolePageId = objTemp.RolePageId;
rp.CreatedOn = objTemp.CreatedOn;
rp.Timestamp = objTemp.Timestamp;
//rp.RoleId = roleId;
//rp.PageId = Convert.ToInt32(item.Cells[0].Text);
//rp.RolePageId =Convert.ToInt32(((Label)item.Cells[2].FindControl("lblRolePageId")).Text.Trim());
rp.IsNew = false;
rp.IsDeleted = false;
rp.UpdatedOn = DateTime.Now;
erp.Add(rp);
}
public string Save(Role objRole)
{
string message = string.Empty;
System.Data.Common.DbTransaction trans = null;
try
{
Objdb.Connection.Open();
trans = Objdb.Connection.BeginTransaction();
Objdb.Transaction = trans;
if (objRole.RoleId == 0)
{
Objdb.Roles.InsertOnSubmit(objRole);
}
else
{
Objdb.Roles.Attach(objRole, true);
Objdb.RolePages.AttachAll(objRole.RolePages.Where(a => a.IsNew == false && a.IsDeleted == false), true);
Objdb.RolePages.InsertAllOnSubmit(objRole.RolePages.Where(a => a.IsNew == true && a.IsDeleted == false));
Objdb.RolePages.DeleteAllOnSubmit(objRole.RolePages.Where(a => a.IsNew == false && a.IsDeleted == true));
}
Objdb.SubmitChanges();
trans.Commit();
message = "Record saved successfully.";
}
catch (Exception ex)
{
trans.Rollback();
message = "Error : " + ex.Message;
}
return message;
}