Display picture from database - c#

I have a database with a photo column, I am trying to display it on a website.
I am coding in Visual studio 2019. It's an MVC project in c#
The two photos show what I got given. The link from the second picture doesn't go anywhere

There are 2 possibilities:
1st option:
Store the path of the image in your database and dynamically set the src of an <img>
2nd option:
Save the image data in your database and reconstruct it on load, your <img> src has to be a controller action that loads, constructs and returns the image.
Edit
Quick example for option 2:
In your cshtml define your image like this:
<img src="#Url.Action("GetFromDB", "Image", new { id = 1234 })" />
Note, you can set the id of your picture dynamically, depending on your scenario. Lets say you have a user class which has a profile picture assigned, you just need to use this id.
On the backend you need a action that handles this request, in this example in the ImageController:
public ActionResult GetFromDB(int id)
{
var image = _dbContext.Find(id);
return File(image.PictureData, image.ContentType);
}
This assumes you have a simple database model for images like this:
class Image
{
[Key]
public int ID { get; set; }
public byte[] PictureData { get; set; }
public string ContentType { get; set; }
}
To save your image to the database, you just need to get it's bytes and content type, for example like this:
using (var ms = new MemoryStream())
{
using (var uploadedImage = Image.FromStream(formFile.OpenReadStream(), true, true))
{
uploadedImage.Save(ms, ImageFormat.Jpeg); // you can actually chose this yourself, depending on your scenario
}
var image = new Model.Image()
{
PictureData = ms.ToArray(),
ContentType = "image/jpeg" // needs to match what you chose above
};
_dbContext.Pictures.Add(image);
_dbContext.SaveChanges();
}

Related

How to receive form data and process the data in Web API

I am new to web API ,Here sending the form data from Angular 4 application to web API.
the form data contains a user registration details as mFormData and the user image as mImage .
I want to store the image in the system folder ex : D:/uplodedImages
and need to store all the user details in database .
I am struggling to do the above things .
service.ts(angular 4)
CreateNewComitteeMember(mFormData, mImage) {
const formData: FormData = new FormData();
formData.append('ImageFile', mImage, mImage.name);
formData.append('mFormData', JSON.stringify(mFormData));
return this.http.post(this.BASE_URL + `/api/CreateNewComitteeMember`, formData)
}
API
[AllowAnonymous]
[HttpPost]
[Route("api/CreateNewComitteeMember")]
public Task<HttpResponseMessage> CreateNewComitteeMember()
{
//How to do the remaining things here.
}
can anyone help me to solve this .
You can simply get the data by accessing the name that you used while appending your data.
But since java object will not be recognized by ASP.NET. You will need to serialize the "mFormData". So, the request will change like this.
formData.append('mFormData', JSON.stringify(mFormData));
Now in you Web API create a model that replicates your "mFormData", lets call it MFormData.
Example,
public class MFormData
{
public string Name {get; set;}
public int Age {get; set;}
public string Xyz {get; set;}
public string ImageUrl {get; set;}
...
}
Now, In your API you can access the data like this.
[AllowAnonymous]
[HttpPost]
[Route("api/CreateNewComitteeMember")]
public Task<HttpResponseMessage> CreateNewComitteeMember()
{
var imageData = HttpContext.Current.Request.Params["mImage"];
var formData = new JavaScriptSerializer()
.Serialize<MFormData>(HttpContext.Current.Request.Params["mFormData"]);
try
{
//Function to save the file and get the URL
formData.ImageUrl = new ApplicationBussinessLayer().SaveFileInDir(imgeData);
//Function to save data in the DB
var saveData = await new AppicationBussinessLayer().SaveUserInfo(formData);
}
catch(Exception ex)
{
return Request.Create(HttpStatusCode.Code, "Some error");
}
return Request.Create(HttpStatusCode.OK, "Data Saved");
}

WPF dynamic layout using user config file

I have an application that receives IoT data. I would like to change the layout (that displays the data) depending on the configuration set by the user.
Eg: The user decides that 3 bytes will be device_id, 4th byte when multiplied by a value gives temperature value,etc. How can I create such a user config file and save it for later use ?
After saving the data, how can I display the data based on these config files? I am thinking of using labels to just match the data. Is there a better way to do this ?
So I have done as #Nobody suggested.
I have created a class with details like number of bytes, device id, etc and then took the data from user input via a form. Later used Basic Serialization to save the data and deserialization to read it back the next time I open the Application as per this link.
Code :
[Serializable()]
public class Config
{
public string DeviceId { get; set; }
public string Name { get; set; }
public int Length { get; set; }
}
using (Stream testFileStream = File.Create(pathString)) // Serialization code
{
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(testFileStream, config);
testFileStream.Close();
}
using (Stream testFileStream = File.OpenRead(pathString))
{
BinaryFormatter deserializer = new BinaryFormatter();
config = (Config)deserializer.Deserialize(testFileStream);
testFileStream.Close();
}

How to send array of images to rdlc reports?

I need to send a title and some images to a report, this is my class
public class ReportDataModel
{
public string Text { get; set; }
public IEnumerable<byte[]> Images { get; set; }
}
when i create a report file and set this class as the data source class and then in design i drag the image field on the report, on run time instead of images it shows "#Error".
thanks in advance.
Your current ReportDataModel uses a master-detail structure. It would not therefore be possible to drag drop images property to the report without showing "#Error", unless you are using an expression like First(Fields!Image.Value).
Change ReportDataModel to the following:
public class ReportDataModel
{
public string Text { get; set; }
public byte[] Image { get; set; }
}
Then instead of dragging the Image field directly on the report, drag an Image from the ToolBox, set image source to Database, select your image field and set MIME type.

With Asp.Net Mvc programmatically define section name in content page

I'm not talking about the RenderSection and my question is not related direcly with layout page.
First of all i want to tell you what im trying to do. I have a
public class Module
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int Ordering { get; set; }
public string Position { get; set; }
public bool Published { get; set; }
public string ModulePath { get; set; }
public bool ShowTitle { get; set; }
}
table named Module. Modules are like Widgets. Please pay attention to the Position and ModulePath fields.
Positions are like ContentPlaceHolder defined in Layout page. In Mvc i define position like below.
RenderSection("PositionName", required:false)
ModulePath field holds the PartialView's location. They will be rendered in layout.
Problem starts here. How to do this programmatically.
Normally we use;
#section PositionName
{
#html.Partial(...)
}
to define a section in content page.
In Asp.net WebForms it is very easy to do.
ContentPlaceHolder.FindControl(PositionName).Controls.Add(..)
I need to specify section names programmatically, which is in a content page
Actually i need something like this;
foreach(var item in Model.Modules)
{
this.AddSection(item.Position, item.ModulePath, item.Ordering)
}
Manual way
#section PositionName
{
#html.Partial("~/Views/Shared/AModule.cshtml")
#html.Partial("~/Views/Shared/AnotherModule.cshtml")
#html.Partial("~/Views/Shared/AnotherModule.cshtml")
}
I tried;
#section #SectionName
{
...
}
ofcource failed.
So its very good idea to dynamically place PartialViews anywhere of page which their positions setted at administration panel. Thats what im trying to do.
From my knowledge there's no option to do this within ASP.NET MVC, but it should be do-able.
As pages are rendered into HTML they get added to the ViewContext object, so I imagine you'd want to replace areas of the HTML with your rendered view. You can access the current rendered HTML as a string like so:
var htmlContent = string.Empty;
var view = ViewEngines.Engines.FindView(ControllerContext, relativePath, null);
using (var writer = new StringWriter())
{
var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
view.View.Render(context, writer);
writer.Flush();
htmlContent = writer.ToString();
}
With this in mind you could programatically replace areas of the string by using some kind of tag that you could match against.
You can define a section programmatically like this:
DefineSection("YoursectionName", async (a) =>
{
this.Write(await this.Component.InvokeAsync(widget.Name, widget.Parameters));
});
Essentially, you would do a Select over all the sections and define the section for each by invoking the given component and then writing the resulting HTML.
There's no way to dynamically add a section, but you can dynamically render things within an existing section. For example:
#section FooPosition
{
foreach (var module in models.Where(m => m.Position == "FooPosition"))
{
#Html.Partial(...);
}
}
In other words, you define sections for the available positions, and then allow the module to have only one of those available positions. Then, you just render whatever modules belong to that position inside the section.

LINQ to SQL: How to setup associations between two tables to populate a list of strings

I have a simple database with two tables: Photo and Tag. There is a one-to-many (a photo can have many tags) relationship between the two tables. Here is a diagram:
Now I have made a Photo class and set it up for LINQ-to-SQL using attributes. The code for that class is below:
[Table]
public class Photo
{
[Column(IsDbGenerated = true, IsPrimaryKey = true, CanBeNull = false)]
public int ID { get; set; }
[Column(CanBeNull = false)]
public string Filename { get; set; }
[Column(CanBeNull = false)]
public string Description { get; set; }
[Column(CanBeNull = false)]
public DateTime DateTaken { get; set; }
public List<string> Tags { get; set; }
public override string ToString()
{
string result = String.Format("File: {0}, Desc: {1}, Date: {2}, Tags: ",
Filename, Description, DateTaken);
if (Tags != null)
foreach (string tag in Tags)
result += tag + ", ";
return result;
}
}
You will notice that currently I do not have any attributes for the Tags list. I would like to be able to setup the attributes (associations) for the Tags list so that it would be populated with Name field of the Tag table for all entries in the Tag table of a particular PhotoID. It would be preferable if I could do this directly (i.e. without having to setup a Tag class mimicking/relating to the Tag table). Since I'm only interested in one field (the Name in the Tag table) rather than many fields, I would think there is a way to do this.
Is this possible, and if so how would I further decorate the class with attributes and what would be the syntax for a simiple Select query using LINQ-to-SQL?
If it helps, here is the code I am using to simply add a new photo and then grab all of the photos out of the database (obviously the tag information is not pulled out as the code stands now).
DataContext context = new DataContext(connectionString);
// add new photo
Photo newPhoto = new Photo { Filename = "MyImage1.jpg", Description = "Me", DateTaken = DateTime.Now };
context.GetTable<Photo>().InsertOnSubmit(newPhoto);
context.SubmitChanges();
// print out all photos
var photoQuery = from m in context.GetTable<Photo>() select m;
foreach (Photo myPhoto in photoQuery)
textBox1.Text += Environment.NewLine + myPhoto.ToString();
First I'd suggest you to use a tool to generate your entity classes (the classes that correspond to the database tables). We'r using sqlmetal and it does the job very well.
Next, (if you have a Tag entity) than write a function that fetches the tags for some photos:
void GetTags(IEnumerable<Photo> photos)
{
var ids = photos.Select(p=>p.ID).ToList();
var tagsG = (from tag in context.GetTable<Tag>() where ids.Contains(tag.PhotoID) select new {PhotoID, Name}).GroupBy(tag=>tag.PhotoID);
foreach(ph in photos){
ph.Tags = tagsG[ph.ID].Select(tag=>tag.Name).ToList();
}
}
Note, the code might not compile I've written it in the browser...
You should refer to the Attribute Based Mapping article on msdn.
Also, this article shows how to decorate an EntitySet property with an Association attribute to accomplish the relationship modeling.
It would be preferable if I could do this directly (i.e. without having to setup a Tag class mimicking/relating to the Tag table).
Not possible. LinqToSql needs to know what is or isn't a table, so it can generate the proper sql text.
What you can do instead, is make one set of types for representing database structure, and another set of types for use elsewhere in your program. The second set of types could have a single class representing Photo and Tag data.
Write a query with the first set of types, then use them to construct instances of the second set.

Categories