25. januar 2006 - 10:52Der er
33 kommentarer og 1 løsning
Asp:TemplateField og FileUpload
Hejsa,
Jeg har et DetailsView, der fremviser data om et medlem fra en database. DetailsView skal samtidig stå for indsættelse og opdatering af medlemmer og det virker da også ok.
Jeg har dog et lille problem med hensyn til upload af billede til et medlem. I mit DetailsView har jeg et TemplateField, hvor der er en FileUpload kontrol.
Før indsættelse af et eventuelt billede, skal der først valideres på det valgte billede. Dette gør jeg så i "dt_MemberDetails_ItemInserting", der er den event der køres før selve DetailsView_ItemInserted kaldes.
"dt_MemberDetails_ItemInserting" har jeg så følgende kode:
FileUpload fu = dt_MemberDetails.Rows[8].FindControl("fu_LogoUpload") as FileUpload; if (fu.HasFile) { string fileFolder = Server.MapPath("../grafik/logo/"); string filePath = null;
ArrayList fileList = new ArrayList(); fileList.Add("image/jpeg"); fileList.Add("image/gif"); fileList.Add("image/png");
if (fileList.Contains(fu.PostedFile.ContentType)) { if (fu.PostedFile.ContentLength <= 10000) { filePath = fileFolder + fu.FileName; fu.SaveAs(filePath); } else { label_Response.Text += " Logo kan højst være 10 kilobyte"; label_Response.ForeColor = Color.FromName("Red"); } } else { label_Response.Text += " Filnavn ikke godkendt<br>Filer af typen .jpg, .gif eller .png forventet"; label_Response.ForeColor = Color.FromName("Red"); } }
Fint nok. Ser ud til at fungere når jeg udskriver filnavnet der er det der skal skrives til databasen, men....
Hvordan får jeg tilknyttet filnavnet fra FileUpload kontrollen til mit objekt? Altså det objekt DetailsView gør brug af til fremvisning af brugerdata og som sendes med ned til mine metoder i min dataklasse?
public class Medlem { private int id; private string firmanavn; private string kontaktperson; private string adresse; private string postnummer; private string bynavn; private string telefon; private string hjemmeside; private string email; private string logo; private int brancheId; private string branchenavn;
public Medlem() {}
// FirmaId public int Id { get { return id; } set { id = value; } }
// Firmanavn public string Firmanavn { get { return firmanavn; } set { firmanavn = value; } }
// Kontaktperson public string Kontaktperson { get { return kontaktperson; } set { kontaktperson = value; } }
// Adresse public string Adresse { get { return adresse; } set { adresse = value; } }
// Postnummer public string Postnummer { get { return postnummer; } set { postnummer = value; } }
// Bynavn public string Bynavn { get { return bynavn; } set { bynavn = value; } }
// Telefon public string Telefon { get { return telefon; } set { telefon = value; } }
// Hjemmeside public string Hjemmeside { get { return hjemmeside; } set { hjemmeside = value; } }
// Email public string Email { get { return email; } set { email = value; } }
// Logo public string Logo { get { return logo; } set { logo = value; } }
// BrancheId public int BrancheId { get { return brancheId; } set { brancheId = value; } }
// Branchenavn public string Branchenavn { get { return branchenavn; } set { branchenavn = value; } } }
Synes godt om
Slettet bruger
25. januar 2006 - 11:27#3
Så det jeg konkret vil gøre er, at sætte Medlem.Logo = FileUpload.FileName (Ikke skrevet korrekt her). Og derefter sende objektet ned til InsertMember, som er en metode i mit datalag, der er sat til at modtage objekter af typen Medlem.
for at kunne gøre det skal du have fat i det objekt der bruges i objectdatasourcen og vises med detailsview. Har du mulighed for at få fat i det objekt eller gemme det i en session eller lignende ?
Synes godt om
Slettet bruger
25. januar 2006 - 11:56#5
Ja, jeg benytter en ObjectDataSource med et dataobject som kilde/parameter. Det ligger ikke i session, men hentes ved hver forespørgsel - altså når der er valgt et medlem fra gridview.
Bemærk at TemplateField med fileUpload ikke er der, da jeg har testet videre uden dette, da det gav mig en fejl om at System.Boolean ikke kunne konverteres til System.String.
du skal have fat i det objekt som Filename skal tilhøre . til det skal du bruge det id som identificerer det som du har i dit details view. Den skulle meget gerne ligge i dt_MemberDetails.DataKeys[0].Value. Med den kan du hente det rigtige objekt og sætte filename på den.
Synes godt om
Slettet bruger
25. januar 2006 - 14:09#9
Mit spørgsmål er så. Hvordan tilgår jeg objektet? Du har da ledt mig en lille bitte smule på vej, men udgangspunktet var at jeg ikke kunne finde en måde at tilgå objektet i detailsview. Jeg går ikke ud fra at jeg skal oprette et helt nyt objekt, men bare tilgå det eksisterende objekt og skrive til attributten Logo fra min eventhandler (ItemInserting eller ItemUpdating).
Jeg tror måske at det vil være nemmest at oprette et nyt objekt og indlæse de eksisterende data og så opdatere detailsview.
Synes godt om
Slettet bruger
25. januar 2006 - 14:16#11
I min DetailsView_ItemInserting eventhandler gør jeg nu følgende: ods_MemberDetails.InsertParameters.Add("Logo", "TestLogo");
Dette hvis der er et filename.
Den kombilerer, men indsætter ikke logo-strengen i databasen.
Hvordan ville du gøre det andet du beskriver?
Synes godt om
Slettet bruger
25. januar 2006 - 14:17#12
Vil egentlig helst være fri for at oprette et nyt objekt, da det at tilføje i mine øjne gør at fejl nemmest undgåes. Kan jeg ikke på en måde tilføje parametre til det eksisterende objekt?
jo men så skal du have fat i det eksisterende objekt. Det kan du måske gøre i objectdatasource selected. hvor du kan får en returnvalue. prøv at case den til dit medlems object og se om den ikke indeholder de oplysninger som vises i dit detailsview.
hvis du tilføjer et Selected event til den objectdatasource og laver en funktion i codebehind: protected void DataSource_selected(object sender, ObjectDataSourceStatusEventArgs e) { Medlem m= (Medlem)e.ReturnValue; Response.Write(m.Firmanavn); }
Virker fint. Men jeg kan ikke bruge den fra min ItemInserting-event. Er det ikke der jeg skal finde FileUpload.FileName og lægge den på objektet?
Synes godt om
Slettet bruger
25. januar 2006 - 14:54#18
Det kunne forestille mig at lave ville være noget i retning af:
Tjek det valgte logo til upload FileUpload fu = dt_MemberDetails.Rows[8].FindControl("fu_LogoUpload") as FileUpload; if (fu.HasFile) { string fileFolder = Server.MapPath("../grafik/logo/"); string filePath = null;
ArrayList fileList = new ArrayList(); fileList.Add("image/jpeg"); fileList.Add("image/gif"); fileList.Add("image/png");
if (fileList.Contains(fu.PostedFile.ContentType)) { if (fu.PostedFile.ContentLength <= 10000) { filePath = fileFolder + fu.FileName; fu.SaveAs(filePath);
Medlem m = ods_MemberDetails.(hent objekt fra objektdatasource); m.Logo = fu.FileName; ods_MemberDetails.(tilføj objektet overskriv/eller tilføj værdien for logo) } else { label_Response.Text += " Logo kan højst være 10 kilobyte"; label_Response.ForeColor = Color.FromName("Red"); } } else { label_Response.Text += " Filnavn ikke godkendt<br>Filer af typen .jpg, .gif eller .png forventet"; label_Response.ForeColor = Color.FromName("Red"); } }
Er det helt umuligt at lave det? Det virker omsonst at oprette et helt nyt objekt og overskrive det valgte fra ObjektDataSource. Kan man ikke referere til objektet og kalde dets properties direkte og dermed bare tilføje en streng til det?
Synes godt om
Slettet bruger
25. januar 2006 - 15:27#19
Hejsa.
Har prøvet med den eventhandler du snakkede om for ObjectDataSource-kontrollen:
Jeg har så erlæret m i toppen som en protected Medlem variabel.
Derfra kan jeg så tilgå properties på m i min ItemInserting eventhandler:
m.Logo = "TesterIgenLogo";
Men, men... Logo bliver så bare ikke skrevet med til den underliggende database. Har du nogen ide om hvordan jeg "attacher" den nye værdi så den rent faktisk bliver skrevet til objectdatasource'en?
for(int i=0; i<e.InputParameters.Count; i++) { System.Diagnostics.Debug.WriteLine(e.InputParameters[i].ToString()) } System.Diagnostics.Debug.WriteLine skriver en linie i output vinduet og er genialt til debugging. genvejen til vinduet er ctrl+alt+o
Synes godt om
Slettet bruger
26. januar 2006 - 09:59#28
Jeg har ændret lidt på det hele. Kom i tanker om at jeg jo ikke kan bruge:
Da det jo er en insert sætning og der derfor ikke findes en selected. Eller måske gør der, men så er det jo et andet objekt.
"prøv at lave en objectdatasource updating event og tilhørende funktion. protected void objectData_Updating(object sender, ObjectDataSourceMethodEventArgs e) { e.InputParameters["Logo"] = m.Logo; }"
Ovenstående kan jeg åbenbart heller ikke, får fejlen:
System.NotSupportedException: The OrderedDictionary is readonly and cannot be modified. at System.Collections.Specialized.OrderedDictionary.set_Item(Object key, Object value) at Medlemmer.ods_MemberDetails_Inserting(Object sender, ObjectDataSourceMethodEventArgs e).
selected burde vise det rigtige objekt da den afvikles hver eneste gang der foretages en select af object datasourcen og dermed også når du vil se detajler i dit detailsview.
vender lige tilbage om lidt skal lige undersøge noget
du kan bestemme værdierne som ryger ned til din update funktion på denne måde: protected void objectData_Updating(object sender, ObjectDataSourceMethodEventArgs e) { IDictionary paramsFromPage = e.InputParameters;
Jeg går ud fra at det er den sidste der bliver afviklet i mit tilfælde. Jeg får fejlen:
System.NullReferenceException: Object reference not set to an instance of an object. at Medlemmer.ods_MemberDetails_Inserting(Object sender, ObjectDataSourceMethodEventArgs e) in *************************************:line 167 at System.Web.UI.WebControls.ObjectDataSourceView.OnInserting(ObjectDataSourceMethodEventArgs e) at System.Web.UI.WebControls.ObjectDataSourceView.ExecuteInsert(IDictionary values) at System.Web.UI.DataSourceView.Insert(IDictionary values, DataSourceViewOperationCallback callback)
Det er nogle gange svært at se skoven for bar' træer. Jeg har nu lavet det på den måde, at mit detailsview itemInserting event indeholder selve koden, der tjekker om en fil er postet. Hvis den er postet, sættes detailsviewEventargs values["Logo"] lig med det postede filename og filen lægges samtidig op i en mappe.
Havde jeg bare vidst at det ikke var på objectdatasource kontrollen ændringerne skulle sættes, men der i mod på selve detailsview før den blev sendt til objectdatasource :-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.