Render ASP .NET MVC ActionResult to string - c#

I'm trying to render the FileContentResult's (.png files in my case) into a base64 strings to return them into json.
I've found an interesting approach from here: http://approache.com/blog/render-any-aspnet-mvc-actionresult-to/ , that supposedly doing what i need, but when I'm trying to do something like
public async ActionResult GetUsers()
{
...
var query = from user in otherUsers
join file in allFiles on user.Profile.Id equals file.Profile.Id into usersWithFiles
from userWithFile in usersWithFiles.DefaultIfEmpty(new File(){Content = new byte[0], ContentType = "image/png"})
select new UserFriendModel { Id = user.Id, UserName = user.UserName, ProfileId = user.Profile.Id, File = File(userWithFile.Content, userWithFile.ContentType).Capture(ControllerContext) };
return Json(query.ToList(), JsonRequestBehavior.AllowGet);
}
I'm getting
System.Web.HttpException:"OutputStream is not available when a custom
TextWriter is used" thrown at result.ExecuteResult(controllerContext);
line.

You can get the file (png image) in a separate query, transform the data into text format by using your text writer, and then inject it into your data model.
Some psudo code like this:
var file = GetFileQuery();
var fileString = TextWriter.Convert(file);
var query = from user in otherUsers
join file in allFiles on user.Profile.Id equals file.Profile.Id into usersWithFiles
from userWithFile in usersWithFiles.DefaultIfEmpty(new File(){Content = new byte[0], ContentType = "image/png"})
select new UserFriendModel { Id = user.Id, UserName = user.UserName, ProfileId = user.Profile.Id, File = fileString };
Another way to do it is to use 2 different action to handle the request. First action returns all the normal data for your data model, and 2nd action only returns you the image. This way you have more flexibility with your image format, i.e. you can return it in OutputStream as PNG image (without explicit serialization/deserialization).
That's my 2 cents.
Henry

Related

How to execute RawSql against the context

I currently have a project that I'm working on, which has a database connected to it. In said database I need to query some tables that don't have a relationship. I need to get a specific set of data in order to display it on my user interface. However I need to be able to reference the returned data put it into a list and convert it into json. I have a stored procedure that needs to just be executed against the context because it's retrieving data from many different tables.
I've tried using ExecuteSqlCommand but that doesn't work, because it returns -1 and can't put it into a list.
I've tried using linq to select the columns I want however it's really messy and I cannot retrieve the data as easily.
I've tried using FromSql, however that needs a model to execute against the context which is exactly what I don't want.
public string GetUserSessions(Guid memberId)
{
string sql = $"EXECUTE dbo.GetUserTrackByMemberID #p0";
var session = _context.Database.ExecuteSqlCommand(sql, memberId);
var json = JsonConvert.SerializeObject(session);
return json;
}
This is the ExecuteSqlCommand example, this returns -1 and cannot be put into a list as there will be more than one session.
public string GetUserSessions(Guid memberId)
{
var session = _context.MemberSession.Where(ms => ms.MemberId == memberId).Select(s => new Session() { SessionId =
s.SessionId, EventId = s.Session.EventId, CarCategory = s.Session.CarCategory, AirTemp = s.Session.AirTemp,
TrackTemp = s.Session.TrackTemp, Weather = s.Session.Weather, NumberOfLaps = s.Session.NumberOfLaps, SessionLength = s.Session.SessionLength,
Event = new Event() { EventId = s.Session.Event.EventId, TrackId = s.Session.Event.TrackId, Name = s.Session.Event.Name, NumberOfSessions =
s.Session.Event.NumberOfSessions, DateStart = s.Session.Event.DateStart, DateFinish = s.Session.Event.DateFinish, TyreSet = s.Session.Event.TyreSet,
Track = new Track() { TrackId = s.Session.Event.Track.TrackId, Name = s.Session.Event.Track.Name, Location = s.Session.Event.Track.Location, TrackLength
= s.Session.Event.Track.TrackLength, NumberOfCorners = s.Session.Event.Track.NumberOfCorners} } });
var json = JsonConvert.SerializeObject(session);
return json;
}
This is using Linq, however it's really messy and I feel there's probably a better way to do this, and then when retrieving the data from json it's a lot bigger pain.
public string GetUserSessions(Guid memberId)
{
var session = _context.MemberSession.FromSql($"EXECUTE dbo.GetUserSessionByMemberID {memberId}").ToList();
var json = JsonConvert.SerializeObject(session);
return json;
}
This is the ideal way I would like to do it, however since I'm using the MemberSession model it will only retrieve that data from the stored procedure which is in the MemberSession table, however I want data that is in other tables as well....
public string GetUserSessions(Guid memberId)
{
var session = _context.MemberSession.Where(ms => ms.MemberId == memberId).Include("Session").Include("Event").ToList();
var json = JsonConvert.SerializeObject(session);
return json;
}
I tried this way but because the Event table has no reference / relationship to MemberSession it returns an error.
As I've previously stated in the RawSql example I'm only getting the table data that is in the MemberSession table, no other tables.
There are no error messages.
using (var context = new DBEntities())
{
string query = $"Exec [dbo].[YOUR_SP]";
List<ResponseList> obj = context.Database.SqlQuery<ResponseList>(query).ToList();
string JSONString = JsonConvert.SerializeObject(obj);
}

Create document not working - C# DocumentDB/CosmosDB

I think I am on the right path, but my C# code is not creating document in Azure CosmosDB.
Below is my documentdb code:
using (var client = new DocumentClient(new Uri(endpoint), authkey))
{
Database database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'db'").AsEnumerable().First();
var query = new SqlQuerySpec
{
QueryText = "SELECT * FROM c WHERE c.id = #id",
Parameters = new Microsoft.Azure.Documents.SqlParameterCollection { new Microsoft.Azure.Documents.SqlParameter { Name = "#id", Value = collectionId }
}
};
DocumentCollection collection = client.CreateDocumentCollectionQuery(database.SelfLink,query).AsEnumerable().First();
dynamic document1Definition = new
{
name = "Admin",
address = 1,
};
var result = client.CreateDocumentAsync(collection.SelfLink, document1Definition);
}
Also want to point out, currently there are no columns named as "name" and "address" in my collection. So according to my knowledge they are suppose to be created dynamically. Please let me know what wrong are you doing?
See last statement, you are using c# Async method without await.
Use await client.CreateDocumentAsync(collection.SelfLink, document1Definition); or your code will exit before document creation is finished.
Note that your method should change to public async Task methodname(), you will see related tip shown by VS.
Some references for you
Async and Await
How and when to use async and-await

Get everything after Slash c#

I'm trying to figure out the best way to get everything before the / character in a string. Some example strings are below.
var url = dr.FindElements(By.XPath("//*[#id=\"u_0_3\"]/div/h1/a"));
foreach (var item in url)
{
if (item.GetAttribute("href").ToString().Contains("https://www.facebook.com/"))
{
listBox4.Items.Add("here");
}
}
the href is like that = "http://facebook.com/xxx"
want the xxx which is username want to get it alone in my listbox without the rest of the url
If you're at the point where you've got the string you want to work with, here are two ways to do this:
Split the string by / and take the last part
var stringToProcess = "https://www.facebook.com/ProfileName";
var partsOfString = stringToProcess.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var profileName = partsOfString.Last();
Use the Uri class to extract the last part
var stringToProcess = "https://www.facebook.com/ProfileName";
var stringToProcessAsUri = new Uri(stringToProcess);
var profileNameFromUri = stringToProcessAsUri.Segments.Last();
This is the "strictly better" way as it will give you a clean result even if the profile address has a query string attached to it, i.e:
var stringToProcess = "https://www.facebook.com/ProfileName?abc=def";
var stringToProcessAsUri = new Uri(stringToProcess);
var profileNameFromUri = stringToProcessAsUri.Segments.Last();
You'll still have the variable profileNameFromUri returned containing only ProfileName

How to convert Json in C#?

I am using c#.net with ASP.Net MVC.
I have following code
var lstrelations = _people.GetAllUsers();
List<string> lstEmailAddresses = lstrelations.Select(p =>p.EmailID).ToList<string>();
return Json(lstEmailAddresses, JsonRequestBehavior.AllowGet);
This is generating output like
["xxy#xct.com", "text13#tds.com", "sdxxa#xys.com"]
but I want generate Json like
["EmailID:xxy#xct.com", "EmailID:text13#tds.com", "EmailID:sdxxa#xys.com"]
I want to put name of each address like "EmailID"
try with this code...
var lstrelations = _people.GetAllUsers();
var lstEmailAddresses = lstrelations.Select(p => new { EmailID = p.EmailID }).ToList();
Json(lstEmailAddresses, JsonRequestBehavior.AllowGet);

Filtering set of images from MongoDB

I have written some codes to store image files in MongoDB. Now I want to filter and retrieve some images from the mongoDB. I want to filter out some images which has some set of characters on the image name.
For Ex: say I have stored aaaa_DEX.jpg, bbbb_DEX.jpg, cccc_BVX.jpg, dddd_OUI.jpg, eeee_DEX.jpg images in mongoDB and I want to get all the images which has the "DEX" on there names. Will it be possible with Query builder? How can I do this?
To upload I use:
public JsonResult UploadPrimaryImage(string hotelCode)
{
var db = _hoteldbObj.Instance();
var primaryImageBucket = new MongoGridFS(db, new MongoGridFSSettings() {Root = "HotelPrimaryImage"});
foreach (string httpFile in Request.Files)
{
var postedFile = Request.Files[httpFile];
if(postedFile == null)
throw new InvalidOperationException("Invalid file");
var bytes = ReadToEnd(postedFile.InputStream);
using (var c = primaryImageBucket.Create(hotelCode, new MongoGridFSCreateOptions() { ContentType = postedFile.ContentType }))
{
c.Write(bytes, 0, bytes.Length);
c.Flush();
c.Close();
}
}
return new JsonResult();
}
Thank You
Performing a .find("ABC") where ABC is your filename will handle this if querying on the full file name.
If you want to query on a substring within the file name, my suggestion would be to save the substring as part of the metadata object. See this post for an example of working with metadata.

Categories

Resources