Display Image of IFormFile saved as Byte in database - asp.net

This is my code in ASP.NET CORE 3.0, when I save the image using type as IFormFile in View Model and as Byte in model. Now I want to retrieve this image in Edit Method. I am Unable to display image. Here is my code
var formData = new Student()
{
AppUserID = userId,
FirstName = model.FirstName,
MatricMarks = model.MatricMarks,
CollegeName = model.CollegeName,
HSSCMarks = model.HSSCMarks,
};
if (model.Profile != null && model.Profile.FileName != "" && model.Profile.FileName != null)
{
IFormFile file = model.Profile;
if (file.Length > 0)
//Convert Image to byte and save to database
{
using (var stream = new MemoryStream())
{
await file.OpenReadStream().CopyToAsync(stream);
formData.Profile = stream.ToArray();
}
}
}
ViewModel
public class StudentSignUpViewModel
{
public string Username { get; set; }
public string CollegeName { get; set; }
public string HSSCMarks { get; set; }
public IFormFile Profile { get; set; }
}
here is Model class
public string MatricMarks { get; set; }
public string CollegeName { get; set; }
public string HSSCMarks { get; set; }
[Required]
public byte[] Profile { get; set; }
And here is Edit[GET] Method where Im trying to display image, please guide what went wrong
public IActionResult Edit(int? id)
{
StudentSignUpViewModel model = new StudentSignUpViewModel();
if (id == null)
{
return NotFound();
}
var student = _context.Students.Where(x => x.StudentId == id.Value).Include(x=>x.AppUser).FirstOrDefault();
model.MatricMarks = student.MatricMarks;
model.CollegeName = student.CollegeName;
model.HSSCMarks = student.HSSCMarks;
model.CoursesArray = student.Courses;
var base64 = Convert.ToBase64String(student.Profile);
ViewBag.imgSrc = string.Format("data:image/jpg;base64,{0}",model.Profile, base64);
}
View Method where I'm Trying to display image
<div class="form-group">
<img src="#ViewBag.imgSrc" class="profile-user-img img-responsive img-circle" alt="User profile picture" />
<label asp-for="Username" class="control-label"></label>
<input asp-for="Username" class="form-control" />
Note: Irrelevant Code is cut out.

To display binary image using base64 string, please modify your code as below.
var base64 = Convert.ToBase64String(student.Profile);
ViewBag.imgSrc = string.Format("data:image/jpg;base64,{0}", base64);
Besides, you can also save these image file(s) on your web server rather than storing them in database, so that your app can serve these images directly to clients.
For more information about serving static files, please check: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-3.1

Related

Dynamically Bind Image to Crystal Report from ViewModel and string type Image Property

I have joined 3 tables(Employee,Department,Designation) in a viewmodel. and follow up the BLL,DAL pattern is asp.net.
My problem is I want to generate report of individual employee based on their unique EmployeeId.
Somehow I managed to retrieve information of each employee except their Image. The Image is set to database as ImageLocation
EmployeeReportVM.cs
public class EmployeeReportVM
{
public string Image { get; set; }
public string EmployeeName { get; set; }
public string EmployeeId { get; set; }
public string Department { get; set; }
public string Designation { get; set; }
public string Grade { get; set; }
public string BloodGroup { get; set; }
public string Phone { get; set; }
public string JoiningDate { get; set; }
}
EmployeeDAL.cs
public List<EmployeeReportVM> EmployeeReport(string employeeId)
{
var emp = (from e in db.Employees
join de in db.Designation on e.DesignationId equals de.DesignationId
join dp in db.Department on e.DepartmentId equals dp.DepartmentId
where e.EmployeeId == employeeId
select new EmployeeReportVM
{
Image = e.Image,
EmployeeName = e.FirstName + " " + e.LastName,
EmployeeId = e.EmployeeId,
Department = dp.DepartmentName,
Designation = de.DesignationName,
Phone = e.MobileNo
}).ToList();
return emp;
}
EmployeBLL.cs
EmployeeDAL employeeDal = new EmployeeDAL();
public List<EmployeeReportVM> EmployeeReportVM(string employeeId)
{
var data = employeeDal.EmployeeReport(employeeId);
return data;
}
EmployeeController.cs
EmployeeBLL employeeBll=new EmployeeBLL();EmployeeBLL employeeBll=new EmployeeBLL();
public ActionResult DownloadEmployeeReport(string employeeId)
{
//ApplicationDbContext db = new ApplicationDbContext();
var data = employeeBll.EmployeeReportVM(employeeId);
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports"), "EmployeeReport.rpt"));
rd.SetDataSource(data.Select(c => new
{
Image = c.Image,
EmployeeName = c.EmployeeName,
EmployeeId = c.EmployeeId,
Department = c.Department,
Designation = c.Designation
}).Where(x => x.EmployeeId == employeeId));
//string pathString = Path.Combine(#"D:\Sayeem\Project\NassaHRMS\Content\Images");
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
rd.PrintOptions.PaperOrientation = CrystalDecisions.Shared.PaperOrientation.Landscape;
rd.PrintOptions.ApplyPageMargins(new CrystalDecisions.Shared.PageMargins(5, 5, 5, 5));
rd.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.PaperA5;
//rd.SetDatabaseLogon("root","", "NassaHRMS", "DESKTOP-PN96TKB");
Stream stream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", "EmployeeDetails.pdf");
}
EmployeeList.cshtml
#using (Html.BeginForm("Edit", "Account", new { id = #item.EmployeeId }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<a class="btn btn-sm btn-outline-info" target="_blank" href="#Url.Action("DownloadEmployeeReport", "Employee",new { #employeeId = item.EmployeeId})"><i class="fa fa-print" title="Print Card"></i></a>
}
The Location of Crystal Report
enter image description here
Here you are doing everything right i guess. Just some issue in picture2 graphic location. What does your database image column contains ? is it only contains image name like someimage.jpg then your graphic location should be like below.
D:\Sayeem\Project\NassaHRMS\EmployeeImage\ + NassaHRMS_ViewModels_EmployeeReportVM.Image
If it contains full Physical Path like D:\Sayeem\Project\NassaHRMS\EmployeeImage\someimage.jpg then your graphic location should be like below
NassaHRMS_ViewModels_EmployeeReportVM.Image

HttpClient copy data from Request.Form .NET Core

I have POST query with Form data with files and I need to send the same data to another POST request.
I'm going to use for this HttpClient class.
Is there a way to copy all Request.Form data and insert them to new request? Or I need to add every param?
I mean something like this:
var httpClient = new HttpClient();
var httpResponseMessage = await httpClient.PostAsync("some_url", Request.Form);
Is there a way to copy all Request.Form data and insert them to new request? Or I need to add every param?
You need to add every param like below:
Model in ProjectA:
public class FormData
{
public int Id { get; set; }
public IFormFile File { get; set; }
public string Name { get; set; }
}
View in ProjectA:
#model FormData
<form asp-action="Post" enctype="multipart/form-data">
<div>
Id:<input asp-for="Id"/>
</div>
<div>
Name:<input asp-for="Name"/>
</div>
<div>
FIle:<input asp-for="File" />
</div>
<div>
<input type="submit" value="create" />
</div>
</form>
Controller in ProjectA:
[HttpPost]
public async Task<IActionResult> Post(FormData formData)
{
HttpClient client = new HttpClient();
// var formData = HttpContext.Request.Form;
client.BaseAddress = new Uri("http://localhost:63331");//your applicationUrl
client.DefaultRequestHeaders.Accept.Clear();
var multiContent = new MultipartFormDataContent();
var file = formData.File;
if (file != null)
{
var fileStreamContent = new StreamContent(file.OpenReadStream());
multiContent.Add(fileStreamContent, "File", file.FileName);
}
multiContent.Add(new StringContent(formData.Id.ToString()), "id");
multiContent.Add(new StringContent(formData.Name.ToString()), "name");
var response = await client.PostAsync("/api/values", multiContent);
//do your stuff...
return Ok();
}
Model in ProjectB:
public class FormDataModel
{
public int Id { get; set; }
public IFormFile File { get; set; }
public string Name { get; set; }
}
Controller in ProjectB:
[HttpPost]
public void Post([FromForm]FormDataModel model)
{
//...
}
Result:

ASP.Net MVC : Binding Dropdownlist to a List on the Model [duplicate]

I'm developing an ASP.NET MVC 5 application, with C# and .NET Framework 4.6.1.
I have this View:
#model MyProject.Web.API.Models.AggregationLevelConfViewModel
[...]
#Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, (SelectList)Model.HelperCodeTypeItems, new { id = "Configurations[0].HelperCodeType" })
The ViewModel is:
public class AggregationLevelConfViewModel
{
private readonly List<GenericIdNameType> codeTypes;
private readonly List<GenericIdNameType> helperCodeTypes;
public IEnumerable<SelectListItem> CodeTypeItems
{
get { return new SelectList(codeTypes, "Id", "Name"); }
}
public IEnumerable<SelectListItem> HelperCodeTypeItems
{
get { return new SelectList(helperCodeTypes, "Id", "Name"); }
}
public int ProductionOrderId { get; set; }
public string ProductionOrderName { get; set; }
public IList<Models.AggregationLevelConfiguration> Configurations { get; set; }
public AggregationLevelConfViewModel()
{
// Load CodeTypes to show it as a DropDownList
byte[] values = (byte[])Enum.GetValues(typeof(CodeTypes));
codeTypes = new List<GenericIdNameType>();
helperCodeTypes = new List<GenericIdNameType>();
for (int i = 0; i < values.Length; i++)
{
GenericIdNameType cType = new GenericIdNameType()
{
Id = values[i].ToString(),
Name = EnumHelper.GetDescription((CodeTypes)values[i])
};
if (((CodeTypes)values[i]) != CodeTypes.NotUsed)
codeTypes.Add(cType);
helperCodeTypes.Add(cType);
}
}
}
And Models.AggregationLevelConfiguration is:
public class AggregationLevelConfiguration
{
public byte AggregationLevelConfigurationId { get; set; }
public int ProductionOrderId { get; set; }
public string Name { get; set; }
public byte CodeType { get; set; }
public byte HelperCodeType { get; set; }
public int PkgRatio { get; set; }
public int RemainingCodes { get; set; }
}
I need to set selected value in these properties:
public IEnumerable<SelectListItem> CodeTypeItems
{
get { return new SelectList(codeTypes, "Id", "Name"); }
}
public IEnumerable<SelectListItem> HelperCodeTypeItems
{
get { return new SelectList(helperCodeTypes, "Id", "Name"); }
}
But I can't set it in new SelectList(codeTypes, "Id", "Name"); or new SelectList(helperCodeTypes, "Id", "Name"); because the selected value are in Configurations array: fields AggregationLevelConfiguration.CodeType and AggregationLevelConfiguration.HelperCodeType.
I think I have to set selected value in the View, but I don't know how to do it.
How can I set the selected values?
Unfortunately #Html.DropDownListFor() behaves a little differently than other helpers when rendering controls in a loop. This has been previously reported as an issue on CodePlex (not sure if its a bug or just a limitation)
The are 2 option to solve this to ensure the correct option is selected based on the model property
Option 1 (using an EditorTemplate)
Create a custom EditorTemplate for the type in the collection. Create a partial in /Views/Shared/EditorTemplates/AggregationLevelConfiguration.cshtml (note the name must match the name of the type
#model yourAssembly.AggregationLevelConfiguration
#Html.DropDownListFor(m => m.HelperCodeType, (SelectList)ViewData["CodeTypeItems"])
.... // other properties of AggregationLevelConfiguration
and then in the main view, pass the SelectList to the EditorTemplate as additionalViewData
#using (Html.BeginForm())
{
...
#Html.EditorFor(m => m.Configurations , new { CodeTypeItems = Model.CodeTypeItems })
...
Option 2 (generate a new SelectList in each iteration and set the selectedValue)
In this option your property CodeTypeItems should to be IEnumerable<GenericIdNameType>, not a SelectList (or just make codeTypes a public property). Then in the main view
#Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, new SelectList(Model.CodeTypeItems, "Id", "Name", Model.Configurations[0].HelperCodeType)
Side note: there is no need to use new { id = "Configurations[0].HelperCodeType" - the DropDownListFor() method already generated that id attribute
I wrote this class to overcome an issue I was having with selecting an option in an html select list. I hope it helps someone.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace Login_page.Models
{
public class HTMLSelect
{
public string id { get; set; }
public IEnumerable<string> #class { get; set; }
public string name { get; set; }
public Boolean required { get; set; }
public string size { get; set; }
public IEnumerable<SelectOption> SelectOptions { get; set; }
public HTMLSelect(IEnumerable<SelectOption> options)
{
}
public HTMLSelect(string id, string name)
{
this.id = id;
this.name = name;
}
public HTMLSelect(string id, string name, bool required, IEnumerable<SelectOption> options)
{
this.id = id;
this.name = name;
this.required = required;
}
private string BuildOpeningTag()
{
StringBuilder text = new StringBuilder();
text.Append("<select");
text.Append(this.id != null ? " id=" + '"' + this.id + '"' : "");
text.Append(this.name != null ? " name=" + '"' + this.name + '"' : "");
text.Append(">");
return text.ToString();
}
public string GenerateSelect(IEnumerable<SelectOption> options)
{
StringBuilder selectElement = new StringBuilder();
selectElement.Append(this.BuildOpeningTag());
foreach (SelectOption option in options)
{
StringBuilder text = new StringBuilder();
text.Append("\t");
text.Append("<option value=" + '"' + option.Value + '"');
text.Append(option.Selected != false ? " selected=" + '"' + "selected" + '"' + ">" : ">");
text.Append(option.Text);
text.Append("</option>");
selectElement.Append(text.ToString());
}
selectElement.Append("</select");
return selectElement.ToString();
}
}
public class SelectOption
{
public string Text { get; set; }
public Boolean Selected { get; set; }
public string Value { get; set; }
}
}
And
public IEnumerable<SelectOption> getOrderTypes()
{
List<SelectOption> orderTypes = new List<SelectOption>();
if (this.orderType == "OptionText")
{
orderTypes.Add(new SelectOption() { Value = "1", Text = "OptionText", Selected = true });
} else
{
orderTypes.Add(new SelectOption() { Value = "2", Text = "OptionText2" });
}
}
And to use it:
#{
Login_page.Models.HTMLSelect selectElement = new Login_page.Models.HTMLSelect("order-types", "order-types");
}
#Html.Raw(selectElement.GenerateSelect(Model.getOrderTypes()));
I leave this in case it helps someone else. I had a very similar problem and none of the answers helped.
We had in a view this line at the top:
IEnumerable<SelectListItem> exitFromTrustDeed = (ViewData["ExitFromTrustDeed"] as IEnumerable<string>).Select(e => new SelectListItem() {
Value = e,
Text = e,
Selected = Model.ExitFromTrustDeed == e
});
and then below in the view:
#Html.DropDownListFor(m => m.ExitFromTrustDeed, exitFromTrustDeed, new { #class = "form-control" })
We had a property in my ViewData with the same name as the selector for the lambda expression and for some reason that makes the dropdown to be rendered without any option selected.
We changed the name in ViewData to ViewData["ExitFromTrustDeed2"] and that made it work as expected.
Weird though.

How to show the JSON data in asp.net web form

I am Beginner at Asp.net so can anyone plz help me to show the data provided in the below shown JSON Api in Asp.net Step by Step.It be of great help if this is answered.
http://fantasy.premierleague.com/web/api/elements/180/
A good way to use Json in C# is with Json.NET
JSON.NET - Official site will help you work with it.
Example to use it
public class User {
public User(string json) {
JObject jObject = JObject.Parse(json);
JToken jUser = jObject["user"];
name = (string) jUser["name"];
teamname = (string) jUser["teamname"];
email = (string) jUser["email"];
players = jUser["players"].ToArray();
}
public string name { get; set; }
public string teamname { get; set; }
public string email { get; set; }
public Array players { get; set; }
}
// Use
private void Run() {
string json = #"{""user"":{""name"":""asdf"",
""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}";
User user = new User(json);
Console.WriteLine("Name : " + user.name);
Console.WriteLine("Teamname : " + user.teamname);
Console.WriteLine("Email : " + user.email);
Console.WriteLine("Players:");
foreach (var player in user.players)
Console.WriteLine(player);
}

How to read dynamic rss feed

In my application i will have dynamic rss feed url saved by users. so i want to know that how can i read that xml which will be returned by rss feed. what will be the structure of that xml ? I have reviewed some feed url and i noticed that most of them have title and description tags but i am not sure to this. if i get these two tags then i will parse xml but if they are not always available then how can i parse xml in that case.
these two contains title and description tag
http://rss.news.yahoo.com/rss/entertainment
http://xml.weather.yahoo.com/forecastrss?p=USCA1116
At first you need to read a XML file for that I recommend you to use XPath or Linq to XML, and as you already said there are three main elements that make up a feed; "title", "link" and "description".
Not a very long time ago I wrote a code to do that, I hope this works for you.
I created this two entities.
public class RssFeed
{
public string Title { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public string PubDate { get; set; }
public string Language { get; set; }
public ObservableCollection<RssItem> RssItems { get; set; }
}
public class RssItem
{
public string Title { get; set; }
public string Description { get; set; }
public string Link { get; set; }
}
Then on this method I read every element from the XML file by using Linq to XML
private static void ReadFeeds()
{
string uri = #"http://news.yahoo.com/rss/entertainment";
WebClient client = new WebClient();
client.DownloadStringAsync(new Uri(uri, UriKind.Absolute));
client.DownloadStringCompleted += (s, a) =>
{
if (a.Error == null && !a.Cancelled)
{
var rssReader = XDocument.Parse(a.Result);
var feed = (from rssFeed in rssReader.Descendants("channel")
select new RssFeed()
{
Title = null != rssFeed.Descendants("title").FirstOrDefault() ?
rssFeed.Descendants("title").First().Value : string.Empty,
Link = null != rssFeed.Descendants("link").FirstOrDefault() ?
rssFeed.Descendants("link").First().Value : string.Empty,
Description = null != rssFeed.Descendants("description").FirstOrDefault() ?
rssFeed.Descendants("description").First().Value : string.Empty,
PubDate = null != rssFeed.Descendants("pubDate").FirstOrDefault() ?
rssFeed.Descendants("pubDate").First().Value : string.Empty,
Language = null != rssFeed.Descendants("language").FirstOrDefault() ?
rssFeed.Descendants("language").First().Value : string.Empty
}).Single();
var rssFeeds = (from rssItems in rssReader.Descendants("item")
select new RssItem()
{
Title = null != rssItems.Descendants("title").FirstOrDefault() ?
rssItems.Descendants("title").First().Value : string.Empty,
Link = null != rssItems.Descendants("link").FirstOrDefault() ?
rssItems.Descendants("link").First().Value : string.Empty,
Description = null != rssItems.Descendants("description").FirstOrDefault() ?
rssItems.Descendants("description").First().Value : string.Empty,
}).ToList();
feed.RssItems = new ObservableCollection<RssItem>(rssFeeds);
}
};
}
And finally you have your feed to be displayed wherever you want.

Resources