First
id (int)
name (varchar)
picture (image)
Second
id (int)
post (varchar)
age (int)
I want to add a record in first table.
Then I want to combine these two table using id.
Then I want to fill a gridview where the post is "manager".
(Especially I want to know how to insert image to database and how to display them using grid view.)
To insert an image to your table , you can try something like this on click of your save button
string fileName = FileUpload1.FileName;
byte[] fileByte = FileUpload1.FileBytes;
Binary binaryObj = new Binary(fileByte);
DataClasses1DataContext context = new DataClasses1DataContext();
//mem_images is the name of the table you dragged , use your table name here
context.mem_images.InsertOnSubmit(new mem_image { mem_img=binaryObj });
context.SubmitChanges();
Response.Write("<script>alert('Image Has Been Saved Successfully'</script>);
To retrieve the image from the database table you will need to use a generic handler(.ashx) file , right click on your project and then go to add and then new item and finally Generic Handler.Here is the code for your .ashx file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace CwizBankApp
{
/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
public class ShowImage : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//context.Response.ContentType = "text/plain";
// context.Response.Write("Hello World");
string id =context.Request.QueryString["Id"];
context.Response.ContentType = "image/jpeg";
Stream strm = ShowEmpImg(id);
byte[] buffer = new byte[4096];
int byteSeq = strm.Read(buffer, 0, 4096);
while (byteSeq > 0)
{
context.Response.OutputStream.Write(buffer, 0, byteSeq);
byteSeq = strm.Read(buffer, 0, 4096);
}
}
public Stream ShowEmpImg(string id)
{
DataClasses1DataContext context1 = new DataClasses1DataContext();
var r = (from a in context1.mem_images where a.image_id==id select a).First() ;
return new MemoryStream(r.mem_img.ToArray());
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Then finally in the click event of your show image or whatever do this
custImage1.ImageUrl = "~/ShowImage.ashx?Id="+textbox.text
Hope this helps you , if you have issues further , reply back
Related
How do i after i take a picture/ select an image (either will overwrite the same image variable regardless), save the image locally and then save the file path as a string into a variable to be inserted into an existing SQLite db.
I had the same exact issue-
Here's how I got it to work
First, in your model where you've created the columns for your tables, make sure there is a property for the string that will be the imagepath
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Image { get; set; }
Then we need a method to upload and save your Image locally and another to get the file path and set it to a string. Assuming this will be in your code-behind, first add these:
public static string photofilename;
public static string imagePath;
static SQLiteConnection db;
YourModel yourmodel = new YourModel();
Then the LoadPhoto method
async void LoadPhotoAsync(FileResult photo)
{
// canceled
string PhotoPath;
if (photo == null)
{
PhotoPath = null;
return;
}
// save the file into local storage
var newFile = Path.Combine(FileSystem.AppDataDirectory, photo.FileName);
using (var stream = await photo.OpenReadAsync())
using (var newStream = File.OpenWrite(newFile))
await stream.CopyToAsync(newStream);
PhotoPath = newFile;
}
Then a method to upload/save the photo (In this case I'm having the user upload from the device) which I have attached to an Upload Image button. In this method, I display the image to the Image in my XAML called ImageViewer, but this might not be necessary for you.
async void Image_ClickedAsync(System.Object sender, System.EventArgs e)
{
try
{
var photo = await MediaPicker.PickPhotoAsync();
LoadPhotoAsync(photo);
photofilename = photo.FileName;
imagePath = Path.Combine(FileSystem.AppDataDirectory, photofilename);
}
catch (FeatureNotSupportedException fnsEx)
{
// Feature is not supported on the device
}
catch (PermissionException pEx)
{
// Permissions not granted
}
catch (Exception ex)
{
Console.WriteLine($"CapturePhotoAsync THREW: {ex.Message}");
}
ImageViewer.Source = imagePath;
ImageViewer.IsVisible = true;
}
What this has done is open up MediaPicker, Allow the user to choose an Image and set the Image Path to the string imagePath. In my case here, I also have "ImageViewer" which is an Image in my XAML used to display the image, but we're not done yet- we haven't yet saved it to your SQLite db. Here's the method I used attached to a "Save" button-
private void SaveEvent(object sender, EventArgs e)
{
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "yourdb.db");
db = new SQLiteConnection(databasePath);
yourmodel.Image = imagePath;
db.Insert(yourmodel);
}
Then, assuming your using ListView or something bound to the Tables in the db, you'll have an image in your XAML like so
<Image HeightRequest="340" WidthRequest="550" x:Name="Image" Source="{Binding Image}"/>
and that should do the trick- Let me know if this works for you!
Now I'm working on my Cloud Storage Project and the main idea of it is to use authorization system provided by Identity Framework and let users upload and download files to an existing table (AspNetFiles - created by me). Moreover, it's important to save all uploaded files to folder in project directory (~/wwwroot/Files/). Now I'm on the way to build upload files system, so:
I made new table AspNetFiles in the direction of other AspNet... tables provided by Identity and Upload-Database NuGet func after creating Migration;
Created new "WorkSpaceController" in "~/Controllers/" for managing files (upload, sort in grid and download) for every logged in user;
Created functions for FileManager view (this is the page for displaying upload, grid and delete files experience) + some other functions for saving files in wwwroot, getting logged in user "Id" and etc.
My dbo.AspNetFiles has the next columns:
FileID (PK, int, not null) with identity (1,1) parameter
FileName (varchar(60), not null)
FileData (varbinary(max), not null) - for store uploaded file data in table
FileExtension (varchar(15), not null)
FileDate (varchar(20), not null)
Id (FK, nvarchar(450), not null) as the primary key of logged in user from dbo.AspNetUsers
After debugging application I get some errors:
InvalidCastException: Object must implement IConvertible. System.Convert.ChangeType(object value, Type conversionType, IFormatProvider provider)
InvalidCastException: Failed to convert parameter value from a FormFile to a Byte[]. Microsoft.Data.SqlClient.SqlParameter.CoerceValue(object value, MetaType destinationType, out bool coercedToDataFeed, out bool typeChanged, bool allowStreaming)
So yeah I know that I use a IFormFile type for "FileData: from "FileDataModel" but it's for saving file locally in project folder as I mentioned previously (~/wwwroot/Files/).
I'm a new user in ASP.NET Core, so I tried many ways from YouTube and articles of how to save files locally and in table of SQL database, but I didn't find any way to do it both and save files with existing Identity Framework with connection to logged in user by foreing key "Id" in table for upload files and download to pc.
Hope u can help me with it. Don't gudge too much :D
This is the code:
FileDataModel (in ~/Models/)
namespace TextCloud.Models
{
public class FileDataModel
{
public string FileName { get; set; }
public IFormFile FileData { get; set; }
public string FileExtension { get; set; }
public string FileDate { get; set; }
public string Id { get; set; }
}
}
WorkSpaceController (in ~/Controllers/)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Configuration;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Protocols;
using System.Data;
using System.Data.SqlClient;
using TextCloud.Models;
using Microsoft.Data.SqlClient;
using Microsoft.AspNetCore.Hosting;
using TextCloud.Areas.Identity.Data;
namespace TextCloud.Controllers
{
public class WorkSpaceController : Controller
{
private readonly IWebHostEnvironment webHostEnvironment;
private readonly UserManager<TextCloudUser> _userManager;
public WorkSpaceController(IWebHostEnvironment webHostEnvironment, UserManager<TextCloudUser> userManager)
{
this.webHostEnvironment = webHostEnvironment;
_userManager = userManager;
}
public IConfigurationRoot GetConnection()
{
var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appSettings.json").Build();
return builder;
}
public IActionResult FileManager()
{
return View();
}
[HttpPost]
public IActionResult FileManager(FileDataModel model)
{
if (ModelState.IsValid)
{
string uniqueFileName = null;
if (model.FileData != null)
{
DateTime FileDate = DateTime.Now;
model.FileDate = FileDate.ToString("dd/MM/yyyy");
model.Id = _userManager.GetUserId(HttpContext.User);
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "Storage");
uniqueFileName = Guid.NewGuid().ToString() + "_" + model.FileData.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
model.FileExtension = Path.GetExtension(model.FileName);
model.FileName = model.FileData.FileName;
if (model.FileDate != null)
{
string connctn = "Server=DESKTOP-LRLFA5K\\SQLEXPRESS;Database=TextCloud;Trusted_Connection=True;MultipleActiveResultSets=true";
SqlConnection con = new SqlConnection(connctn);
con.Open();
string commnd = "insert into AspNetFiles(FileName, FileData, FileExtension, FileDate, Id) values (#FileName, #FileData, #FileExtension, #FileDate, #Id)";
SqlCommand com = new SqlCommand(commnd, con);
com.Parameters.Add("#FileName", SqlDbType.VarChar).Value = model.FileName;
com.Parameters.Add("#FileData", SqlDbType.VarBinary).Value = model.FileData;
com.Parameters.Add("#FileExtension", SqlDbType.VarChar).Value = model.FileExtension;
com.Parameters.Add("#FileDate", SqlDbType.VarChar).Value = model.FileDate;
com.Parameters.Add("#Id", SqlDbType.NVarChar).Value = model.Id;
com.ExecuteScalar();
con.Close();
model.FileData.CopyTo(new FileStream(filePath, FileMode.Create));
}
}
}
return View();
}
}
}
According to your description, I found you directly pass the iformfile to the FileData. You should read the byte array from the iformfile, then store the byte arrary into the database.
More details, you could refer to below codes:
[HttpPost]
public IActionResult FileManager(FileDataModel model)
{
if (ModelState.IsValid)
{
string uniqueFileName = null;
if (model.FileData != null)
{
DateTime FileDate = DateTime.Now;
model.FileDate = FileDate.ToString("dd/MM/yyyy");
model.Id = _userManager.GetUserId(HttpContext.User);
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "Storage");
uniqueFileName = Guid.NewGuid().ToString() + "_" + model.FileData.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
model.FileExtension = Path.GetExtension(model.FileName);
model.FileName = model.FileData.FileName;
if (model.FileDate != null)
{
using (MemoryStream stream = new MemoryStream())
{
model.FileData.OpenReadStream().CopyTo(stream);
string connctn = #"Server=DESKTOP-LRLFA5K\\SQLEXPRESS;Database=TextCloud;Trusted_Connection=True;MultipleActiveResultSets=true";
SqlConnection con = new SqlConnection(connctn);
con.Open();
string commnd = "insert into AspNetFiles(FileName, FileData, FileExtension, FileDate, Id) values (#FileName, #FileData, #FileExtension, #FileDate, #Id)";
SqlCommand com = new SqlCommand(commnd, con);
com.Parameters.Add("#FileName", SqlDbType.VarChar).Value = model.FileName;
com.Parameters.Add("#FileData", SqlDbType.VarBinary).Value = stream.ToArray();
com.Parameters.Add("#FileExtension", SqlDbType.VarChar).Value = model.FileExtension;
com.Parameters.Add("#FileDate", SqlDbType.VarChar).Value = model.FileDate;
com.Parameters.Add("#Id", SqlDbType.NVarChar).Value = model.Id;
com.ExecuteScalar();
con.Close();
stream.CopyTo(new FileStream(filePath, FileMode.Create));
}
}
}
}
return View();
}
I have a MasterDetailPage that creates several Department objects. I want to grab the current department number so I can use it to sort a list later on in my program. How do I go about doing that? I have tried binding it to a label and then getting the data from that (very hacky, I know) but that's the only thing I could think of.
Department[] departments = {
new Department ("D", 1),
new Department ("De", 7),
new Department ("G", 4),
new Department ("M", 9),
new Department ("Pr", 167),
new Department ("Fr", 187),
new Department ("H", 169),
new Department ("B", 11),
new Department ("S", 399),
new Department ("N", 407),
new Department ("O", 201),
new Department ("U", 023)
};
ListView listView = new ListView {
ItemsSource = departments
};
this.Master = new ContentPage {
Title = "Departments", // Title required!
Content = new StackLayout {
Children = {
header,
listView
}
}
};
DetailPage2 detailPage = new DetailPage2 ();
this.Detail = detailPage; //detail page is where I want to use deptNum for sorting
listView.ItemSelected += (sender, args) => {
// Set the BindingContext of the detail page.
this.Detail.BindingContext = args.SelectedItem;
// Show the detail page.
this.IsPresented = false;
};
// Initialize the ListView selection.
listView.SelectedItem = departments [0];
}
}
}
Then in my detailpage I want to be able to pull the departmentNumber out and use it as an int
using System;
using Xamarin.Forms;
namespace irisxamarin
{
public class Department :BindableObject
{
public Department (string name, int deptNumber)
{
this.Name = name;
this.DeptNum = deptNumber;
}
public string Name { private set; get; }
public int DeptNum { private set; get; }
public override string ToString ()
{
return Name;
}
}
}
And here is some logic in the detailpage. This is where I would like to grab the current deptNum.
namespace irisxamarin
{
public class DetailPage2 : ContentPage
{
public DetailPage2 ()
{
Request request = new Request ();
Button settingsButton = new Button {
Text = "Settings",
TextColor = Color.Gray
};
//......................
//code above and below
ListView itemsList = new ListView {
ItemsSource = request.GetList (deptNum) //USE INT HERE
};
itemsList.ItemSelected += (sender, args) => {
this.BindingContext = args.SelectedItem;
};
itemLabel.SetBinding (Label.TextProperty, "DeptNum");
//DeptNum is the data I want but not in a label, just the int val
var listFrame = new Frame {
Content = itemsList,
OutlineColor = Color.Silver,
};
Each page is just a C# class. You can pass a value to it the way you would do with any class - generally the easiest way is to
pass values in the constructor
or if the page already exists, create public properties and set the value via the setter
If you want to set a value globally for use throughout your app, you can create a static class that is available everywhere and set state values in that class.
I'm currently building a music browser/player of the music on a the device. I sucessufully populated the a listview with the names of the songs and their artist but I'm not able to show the albumart associated with the song. I'm not quite sure what is the correct path to get the album art & also how to correlate it with the songs. The code builds but not album art is showed up. I guess that
albumArtUri is not good. Could you please help me to get the right albumart Uri?
Thank you for your help, it's appreciated :)
Julien
Here is my SongAdapter Code:
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Provider;
using Android.Database;
using Android.Net;
namespace project
{
public class SongsAdapter:CursorAdapter
{
List<Song> songsList;
Activity context;
public SongsAdapter (Activity context, ICursor cursor, List<Song> theSongs): base(context,cursor)
{
this.context = context;
songsList = theSongs;
}
public override void BindView(View view, Context context, ICursor cursor)
{
var song_title = view.FindViewById<TextView> (Resource.Id.song_title);
var song_artist = view.FindViewById<TextView> (Resource.Id.song_artist);
var song_album_art = view.FindViewById<ImageView> (Resource.Id.song_album_art);
song_title.Text = songsList [cursor.Position].Title;
song_artist.Text = songsList [cursor.Position].Artist;
//If there is an image to display, it will display it. If not, it will use a default image
if (songsList [cursor.Position].AlbumId == null) {
song_album_art = view.FindViewById<ImageView> (Resource.Id.song_album_art);
song_album_art.SetImageResource (Resource.Drawable.ic_action_user); //Image needs to be set
} else {
var songUri = ContentUris.WithAppendedId (MediaStore.Audio.Media.ExternalContentUri, songsList [cursor.Position].Id);
var albumArtUri = Android.Net.Uri.WithAppendedPath(songUri,MediaStore.Audio.Albums.EntryContentType);
song_album_art.SetImageURI (albumArtUri);
}
}
public override View NewView(Context context, ICursor cursor, ViewGroup parent)
{
return this.context.LayoutInflater.Inflate(Resource.Layout.songslistitem, parent, false);
}
}
}
Here is how I call the SongAdapter:
ListView listView;
view = LayoutInflater.From (container.Context).Inflate (Resource.Layout.songlist, container, false);
listView = view.FindViewById<ListView> (Resource.Id.List);
List<Song> songsList;
var uri = MediaStore.Audio.Media.ExternalContentUri;
string[] projection = {
MediaStore.Audio.Media.InterfaceConsts.Id,
MediaStore.Audio.Media.InterfaceConsts.AlbumId,
MediaStore.Audio.Media.InterfaceConsts.Title,
MediaStore.Audio.Media.InterfaceConsts.Artist,
};
var loader = new CursorLoader (container.Context, uri, projection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground ();
songsList = new List<Song> ();
if (cursor.MoveToFirst ()) {
do {
songsList.Add (new Song {
Id = cursor.GetLong (cursor.GetColumnIndex (projection [0])),
AlbumId = cursor.GetString (cursor.GetColumnIndex (projection [1])),
Title = cursor.GetString (cursor.GetColumnIndex (projection [2])),
Artist = cursor.GetString (cursor.GetColumnIndex (projection [3]))
});
} while (cursor.MoveToNext ());
}
listView.Adapter = new SongsAdapter (context,cursor,songsList);
I was able to solve my issue by doing this in the song adapter:
long album_id = cursor.GetLong(cursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
var songCover = Android.Net.Uri.Parse ("content://media/external/audio/albumart");
var songAlbumArtUri = ContentUris.WithAppendedId (songCover, album_id);
song_artist.Text = songAlbumArtUri.ToString();
song_album_art.SetImageURI (songAlbumArtUri);
I found the answer thanks to this stackoverflow answer: Getting album art from the audio file Uri
I need to bind text which may contain hyperlinks to RichTextBox so it could show text as normal text and links as hyperlinks.
For example I have following text:
Join us on social networks
http://www.facebook.com/
I want that links in a text be hyperlinks so the result in RichTextBox would be like this:
Join us on social networks
http://www.facebook.com/
I implemented what I need
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Text.RegularExpressions;
using System.Windows.Media;
namespace NazarGrynko.UI.Controls
{
public class MyRichTextBox : RichTextBox
{
private const string UrlPattern = #"(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,#?^=%&:/~\+#]*[\w\-\#?^=%&/~\+#])?";
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof (string), typeof(MyRichTextBox ), new PropertyMetadata(default(string), TextPropertyChanged));
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
private static void TextPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var richTextBox = (MyRichTextBox)dependencyObject;
var text = (string) dependencyPropertyChangedEventArgs.NewValue;
int textPosition = 0;
var paragraph = new Paragraph();
var urlMatches = Regex.Matches(text, UrlPattern);
foreach (Match urlMatch in urlMatches)
{
int urlOccurrenceIndex = text.IndexOf(urlMatch.Value, textPosition, StringComparison.Ordinal);
if (urlOccurrenceIndex == 0)
{
var hyperlink = new Hyperlink
{
NavigateUri = new Uri(urlMatch.Value),
TargetName = "_blank",
Foreground = Application.Current.Resources["PhoneAccentBrush"] as Brush
};
hyperlink.Inlines.Add(urlMatch.Value);
paragraph.Inlines.Add(hyperlink);
textPosition += urlMatch.Value.Length;
}
else
{
paragraph.Inlines.Add(text.Substring(textPosition, urlOccurrenceIndex - textPosition));
textPosition += urlOccurrenceIndex - textPosition;
var hyperlink = new Hyperlink
{
NavigateUri = new Uri(urlMatch.Value),
TargetName = "_blank",
Foreground = Application.Current.Resources["PhoneAccentBrush"] as Brush
};
hyperlink.Inlines.Add(urlMatch.Value);
paragraph.Inlines.Add(hyperlink);
textPosition += urlMatch.Value.Length;
}
}
if (urlMatches.Count == 0)
{
paragraph.Inlines.Add(text);
}
richTextBox.Blocks.Add(paragraph);
}
}
}
Using example:
<MyRichTextBox Text="{Binding Message}"/>
Parse the Hyperlink, and create following structure (With C#, of course):
<RichTextBlock>
<Run>Hello World!</Run>
<Hyperlink NavigateUri="http://www.stackoverflow.com">http://www.stackoverflow.com</Hyperlink>
Thanks for the solution!
One minor modification I made was right at the end, I replaced the check on the count, with a line that just adds a substring of the full text, this way it does not truncate everything after the last URL, all text is retained.
paragraph.Inlines.Add(text.Substring(textPosition, text.Length - textPosition));
//if (urlMatches.Count == 0)
//{
// paragraph.Inlines.Add(text);
//}