How to retrieve list of images from GridFS? - c#

This is to submit a view that uses ajax to pull the data.
I am trying to retrieve an image from MongoDb GridFS bucket. The download operation works. But the issue is, the view model that I use has:
public User User { get; set; }
public List<IFormFile> ImageUpload { get; set; }
I get the user from the db context, and use that to identify the image from the bucket and I want to return it to the view from the controller.
The following is my controller code:
public IActionResult AddEditUser(int id = 0)
{
if (id == 0)
{
return View(new UserImgBinder());
}
else
{
var userImageId = _context.User.Where(x => x.UserId.Equals(id)).Select(y => y.AvatarImg).ToString();
var stream = ContextNew.ImagesBucket.OpenDownloadStream(new ObjectId(userImageId.ToBson()));
var contentType = stream.FileInfo.Metadata["ContentType"].AsString;
//File(stream, contentType);
IFormFile file = new FormFile(stream, 0, stream.Length,"","");
var UserImgBinder = new UserImgBinder
{
User = _context.User.Where(x => x.UserId.Equals(id)).FirstOrDefault(),
ImageUpload = file
};
return View(UserImgBinder);
}
}
Since ImageUpload is of type List and what I am trying to feed it is not a list I am getting error.
What should I write to solve this? Is this approach bad?
Please help.
Thanks.

Try code like:
var UserImgBinder = new UserImgBinder
{
User = _context.User.Where(x => x.UserId.Equals(id)).FirstOrDefault(),
ImageUpload = new List<IFormFile> {
file
}
};

Related

ASP.NET 5 MVC JSON Response via Web Api, HTTP Error 502.3 - Bad Gateway

im trying to answer a Get Request in My Web Api with a JSON File in a poll application. When a user of my application uses a token, I want to response a PollParticipation object, which contains a a poll, a list of the options of the poll, a list of my UserPollOptions (The connection between the UserPoll and the Option) and a List with lists of userPollOption with the answers of other participants.
The problem is that I am receiving a HTTP Error 502.3 - Bad Gateway and I don't know why. Here is my code:
[HttpGet("{token}")]
[Route("pollway/{token}")]
public PollParticipation Participate(string token)
{
PollParticipation myPoll = new PollParticipation();
if (!_dbContext.UserPollModels.Any(u => u.UserPollToken == token))
{
return new PollParticipation();
}
UserPollModel userPoll = _dbContext.UserPollModels.FirstOrDefault(u => u.UserPollToken == token);
PollModel thisPoll = _dbContext.PollModels.FirstOrDefault(u => u.PollId == userPoll.PollId);
myPoll.poll = thisPoll;
// List of all Options
List<OptionModel> options = new List<OptionModel>();
options = _dbContext.OptionModels.Select(x => x).Where(y => y.PollId == thisPoll.PollId).ToList();
myPoll.options = options;
//List of all UserPollOptions from my UserPollId
List<UserPollOptionModel> myUserPollOptionModels = new List<UserPollOptionModel>();
myUserPollOptionModels =
_dbContext.UserPollOptionModels.Select(x => x).Where(y => y.UserPollId == userPoll.UserPollId).ToList();
myPoll.MyUserPollOptions = myUserPollOptionModels;
//List of all UserPolls, where the user already participated at the survey
List<UserPollModel> userPolls = new List<UserPollModel>();
userPolls = _dbContext.UserPollModels.Select(x => x).Where(y => y.PollId == thisPoll.PollId).Where(z => z.Participation != false).ToList();
//Delete my own UserPollId out of the List
foreach (var userPollModel in userPolls)
{
if (userPollModel.UserPollId == userPoll.UserPollId)
{
userPolls.Remove(userPollModel);
}
}
//Make a list of UserPollOptions for each UserPollRelation that participated
List<List<UserPollOptionModel>> otherUserPollOptionModels = new List<List<UserPollOptionModel>>();
foreach (var userPollModel in userPolls)
{
List<UserPollOptionModel> tempUserPollOptionModels =
_dbContext.UserPollOptionModels.Select(x => x)
.Where(y => y.UserPollId == userPollModel.UserPollId)
.ToList();
otherUserPollOptionModels.Add(tempUserPollOptionModels);
}
myPoll.OtherUserPollOptions = otherUserPollOptionModels;
return myPoll;
}
I also tried it using a false link then the application successfull send a PollParticipation (in line 8) where the attributes had the value Null:
{
poll: null,
options: null,
MyUserPollOptions: null,
OtherUserPollOptions: null
}
I also tried to change the return type to IActionResult or JSON result and tried it with "return new ObjectResult (myPoll)" or "return new JsonResult(myPoll). Another try was to just add only the Poll to the PollParticipation and not the lists. This also did not work.
This is what my PollParticipation class looks like, it is not mapped in the database:
public class PollParticipation
{
public PollModel poll { get; set; }
public List<OptionModel> options { get; set; }
public List<UserPollOptionModel> MyUserPollOptions { get; set; }
public List<List<UserPollOptionModel>> OtherUserPollOptions { get; set; }
}
Can somebody help me? Thank you!
EDIT + Solution
The solution is to write [JsonIgnore] above the virtual lists in the OptionModel and userPollOptionModel class. They were referencing them selfes in the building of the json File.

Create and Read List<> from cookies

I'm trying to display recently viewed products and so far I have already done that. I have a Product table that has many products stored. I have HomeController which has an Action method of Details() that display product details.
I have wrote AddRecentProduct method which stores Recently Viewed Products (10) in the Session
Now I want to store these recent viewed product list into cookies for atleast 30days on visitors computer, because session expires. Just like Imdb Recently Viewed.
Also If I create another table in my database RecentlyViewed with columns rv_id, userId, productId how will I save recentlyViewedList data in this ? The userId column will hold loggedIn user's id but what if a user is a Guest (not registered) what's the solution then ? Do I need to use GUID then ?
RecentProduct.cs
public class RecentProduct
{
public int ProductId { get; set; }
public string ProdutName { get; set; }
public string ImageUrl { get; set; }
public DateTime LastVisited { get; set; }
}
Controller
public void AddRecentProduct(List<RecentProduct> list, int id, string name, int maxItems)
{
var item = recentProductList.FirstOrDefault(t => t.ProductId == id);
if (item == null)
{
list.Add(new RecentProduct
{
ProductId = id,
ProdutName = name,
LastVisited = DateTime.Now,
});
}
while (list.Count > maxItems)
{
list.RemoveAt(0);
}
}
public ActionResult Details(int? id)
{
if (id == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
Product product = db.Products.Find(id);
if (product == null)
return HttpNotFound();
var list = Session["RecentProductList"] as List<RecentProduct>;
if (list == null)
{
list = new List<RecentProduct>();
Session["RecentProductList"] = list;
}
AddRecentProduct(list, id.Value, product.Name, 10);
ViewData["RecentProductList"] = list;
return View(product);
}
ProductDetails View Page
<div class="col-sm-9">
#{
var recentProductList = ViewData["RecentProductList"] as List<Project.Models.RecentProduct>;
}
#foreach (var recentProduct in recentProductList)
{
<p>#recentProduct.ProdutName (id: #recentProduct.ProductId) </p>
}
</div>
I am getting the desired result with session, Now I want to do this same with cookies.
This is what I'm trying Creating cookie:
List<RecentProduct> yourList = new List<RecentProduct>();
RecentProduct rc = new RecentProduct();
rc.ProdutName = product.Name;
rc.ProductId = product.ProductId;
rc.ImageUrl = product.ImagePath;
rc.LastVisited = DateTime.Now;
yourList.Add(rc);
var yourListString = String.Join(",", yourList);
// Create a cookie
HttpCookie yourListCookie = new HttpCookie("YourList", yourListString);
// The cookie will exist for 7 days
yourListCookie.Expires = DateTime.Now.AddDays(7);
// Write the Cookie to your Response
Response.Cookies.Add(yourListCookie);
and In ProductDetails View Page reading cookies like this:
#if (Request.Cookies["YourList"] != null)
{
// Your cookie exists - grab your value and create your List
List<string> yourList = Request.Cookies["YourList"].Value.Split(',').Select(x => Convert.ToString(x)).ToList();
// Use your list here
<p>#yourList</p>
}
I'm not getting any result. How can I read cookie and values ?
the best solution for you is using Html5 Web Storage. it lets you store up to 5mb in local browser. you can only read and write via javascript.
example:
$('#btnLocalStorage').click(function()
{
var txtName = $("#txtName").val();
//set item
localStorage.setItem("EmpName", txtName);
});
$('#btnLocalStorageRemove').click(function()
{
//remove item
localStorage.removeItem("EmpName");
});
$('#btnLocalStorageClear').click(function()
{
//clear Local Storage
localStorage.clear();
});
$('#btnLocalStorageLength').click(function()
{
var localStoragelength = localStorage.length;
alert("The length of Local storage is " + localStoragelength);
});
By the way it has no expire time and u dont need guid.
If you are using cookies, why do you need RecentlyViewed table then? Storing recent product ids in cookie will work for both logged-in and anonymous user.

Umbraco 7 Rendering media type images

Am trying to render a list of media images.
In my view I have:
View
#section pageSpecificJsBody {
<script src="/scripts/casestudieslist.js"></script>
<script>
$(function () { pdms.caseStudiesList.init(); });
</script>
}
Which is used to call a js file
The js file calls the following controller
Controller
[HttpGet]
public JsonResult List()
{
var CaseStudyContentTypeId = Services.ContentTypeService.GetContentType("CaseStudy").Id;
var CaseStudies = Services.ContentService.GetContentOfContentType(CaseStudyContentTypeId).Select(x => new CaseStudy {
BannerImage = Umbraco.Content(x.Id).GetPropertyValue("bannerimage"),
Url = Umbraco.Content(x.Id).Url.ToString(),
SectorName = Umbraco.Content(x.GetValue("selectSector")).Name, //x.GetValue("selectSector").ToString(),
BodyTextHeading = x.GetValue("bodyTextHeading").ToString(),
BannerHeading = x.GetValue("bannerheading").ToString()
});
Model
public class CaseStudy
{
public string SectorName { get; set; }
//public int Id { get; set; }
public string Url { get; set; }
public string BannerHeading { get; set; }
public string BannerImage { get; set; }
public string BodyTextHeading { get; set; }
}
Previously the Banner Image was using a media picker so the images could be accessed through Umbraco.Content, but I have now set them all to use a custom cropper which set them to media types
My question is... how can I now set the BannerImage property to get the relevant media image?
normally I could do something similar to this in a view.
var BannerImage = Model.Content.GetPropertyValue("bannerimage");
var MediaImage = Umbraco.TypedMedia((int)BannerImage);
<source srcset="#MediaImage.GetCropUrl("desktopMax")" />
But I don't have access to the model since am in the controller, and am really stuck, am still new to Umbraco and don't yet fully understand everything, so sorry if things are not clear.
Thanks in advance
You can get the #Umbraco helper in a lot of places (including the controller) by doing:
UmbracoHelper umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
I would probably rewrite your code to look like this:
var caseStudies = from caseStudy in Services.ContentService.GetContentOfContentType(CaseStudyContentTypeId)
let content = umbracoHelper.TypedContent(caseStudy.Id)
let bannerImage = umbracoHelper.TypedMedia(caseStudy.GetPropertyValue("bannerimage"))
let sector = umbracoHelper.TypedContent("selectSector")
select new CaseStudy {
BannerImage = bannerImage.Url,
Url = content.Url,
SectorName = sector.Name,
BannerHeading = caseStudy.GetPropertyValue<string>("bannerheading"),
BodyTextHeading = caseStudy.GetPropertyValue<string>("bodyTextHeading"
};
I found this post Here, which has a good suggestion on obtaining the crop url for an image.
Here's what I've wrote to solve the issue:
Controller
var CaseStudyContentTypeId = Services.ContentTypeService.GetContentType("CaseStudy").Id;
var CaseStudies = Services.ContentService.GetContentOfContentType(CaseStudyContentTypeId).Select(x => new CaseStudy
{
BannerImage = Umbraco.TypedMedia(x.GetValue<int>("bannerimage")).GetCropUrl("umbracoFile", "mobile"),
Url = Umbraco.Content(x.Id).Url.ToString(),
SectorName = Umbraco.Content(x.GetValue("selectSector")).Name, //x.GetValue("selectSector").ToString(),
BodyTextHeading = x.GetValue("bodyTextHeading").ToString(),
BannerHeading = x.GetValue("bannerheading").ToString()
});
Am going to debug and test out Sams method so I can work out the difference between both examples. If anyone (or Sam) could offer suggestions as to why they believe one way could potentially be more beneficial than the other please could you give an explanation.
Thanks in advance.

How to get urls of users profiles by theirs login names in sharepoint 2013?

Got this repository code.
public IEnumerable<FollowedPerson> ReadFollowedPersonsById(int id, SPList list)
{
var item = list.GetItemById(id);
if (item == null)
{
return null;
}
var likedByCollection = (SPFieldUserValueCollection)item["LikedBy"];
if (likedByCollection == null)
{
return null;
}
var followers = new Collection<FollowedPerson>();
foreach (var liker in likedByCollection)
{
followers.Add(new FollowedPerson
{
Name = liker.User.Name,
ImageUrl = string.Empty //TODO Urls of users avatars
});
}
return followers;
}
I want to get the collection of users that liked some list item. Collection item looks like this:
public class FollowedPerson
{
public string Name { get; set; }
public string ImageUrl { get; set; }
}
Getting their names works fine but I don`t know how I can get their avatar images by theirs login names.
liker.User //does not contain any url of user`s image
You can get this info from user profile. You may read about how to work with it here: Work with user profiles in SharePoint 2013.
There is code snippet for retrieve all user profile properties:
// Replace the following placeholder values with the target SharePoint site and
// target user.
const string serverUrl = "http://serverName/";
const string targetUser = "domainName\\userName";
// Connect to the client context.
ClientContext clientContext = new ClientContext(serverUrl);
// Get the PeopleManager object and then get the target user's properties.
PeopleManager peopleManager = new PeopleManager(clientContext);
PersonProperties personProperties = peopleManager.GetPropertiesFor(targetUser);
// Load the request and run it on the server.
// This example requests only the AccountName and UserProfileProperties
// properties of the personProperties object.
clientContext.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties);
clientContext.ExecuteQuery();
foreach (var property in personProperties.UserProfileProperties)
{
Console.WriteLine(string.Format("{0}: {1}",
property.Key.ToString(), property.Value.ToString()));
}

Why isn't my image displaying in my view?

I am storing images as byte arrays inside a SQL database.
Here is my Index method (inside the controller):
public ActionResult Index()
{
var list = db.UserProfiles.ToList();
Dictionary<int, ActionResult> picture = list.ToDictionary(item => item.CarID, item => CarPic(item.Picture));
ViewBag.CarPictures = picture;
return View(list);
}
Here is my CarPic method:
public ActionResult CarPic(byte[] imageBytes)
{
return imageBytes == null ? null : File(imageBytes, "image/jpeg");
}
Here is how I am trying to display the image inside my view:
foreach(var item in Model)
{
<img src="#ViewBag.CarPictures[item.CarID]"/>
}
This is what shows up in the web browser:
Here is a screenshot of Intellisense:
So Picture is not null, it is a byte array. The image itself is a JPEG. Here is the code I am using to convert the image to a byte array to store it in the database:
[Authorize]
[HttpPost]
public ActionResult Create(Stock stock, HttpPostedFileBase file)
{
if (file != null)
{
if (file.ContentType.Contains("image"))
{
using (var inputStream = file.InputStream)
{
var memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
var data = memoryStream.ToArray();
stock.Picture = data;
}
}
}
if (ModelState.IsValid)
{
db.UserProfiles.Add(stock);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(stock);
}
I have checked the Database and the field is indeed populated. Here is my Stock model:
[Table("Stock")]
public class Stock
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int CarID { get; set; }
public byte[] Picture { get; set; }
//etc etc
}
I am tearing my hair out here trying to work out why this isn't working, as I think I have done everything right. What am I doing wrong?
Thanks very much
You're misunderstanding the <img> tag.
<img src="..." /> allows you to display an image from a URL.
The src attribute must specify a URL that returns the actual image.
If you want to embed the image in the page, you can use a data: URI.

Categories

Resources