Posts Tagged solution
WCF and Email Attachments
Posted by Kelly's Chronicles in .NET, C#, MVC, WCF on September 27, 2015
First off I want to apologize for being away so long. It has been a crazy ride to say the least.
So a colleague of mine ran into an issue with WCF and emailing attachments and asked for help. In this block of code below it would always fail at:
Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);” The error is : “Value cannot be null.
Parameter name: stream”
EmailSendInput emailSendInput = new EmailSendInput
{
Attachments = new List<Attachment>(),
Body = model.Body,
To = new List<string> { model.EmailTo },
From = model.EmailFrom,
Subject = model.EmailSubject
};
if (model.Files != null)
{
foreach (var currAttachment in model.Files)
{
if (currAttachment != null && currAttachment.ContentLength > 0)
{
// the filename needs to be nice looking
string fileName =
currAttachment.FileName.Substring(
currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
currAttachment.FileName.Length
– currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);
var attachment = new Attachment(currAttachment.InputStream, fileName);
emailSendInput.Attachments.Add(attachment);
}
}
}
B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
if (!emailSendResponse.Success)
{
throw new Exception(emailSendResponse.Message);
}
}
public EmailSendResponse SendEmail(EmailSendInput input)
{
EmailSendResponse retVal = new EmailSendResponse();
try
{
string smtpServer = “”
string smtpPort = “”
using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
{
var mail = new MailMessage
{
From = new MailAddress(input.From),
Subject = input.Subject,
Body = input.Body
};
input.To.ForEach(t => mail.To.Add(t));
if (input.Attachments != null && input.Attachments.Count > 0)
{
foreach (var fileAttachment in input.Attachments)
{
//Code Crashes here
Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);
mail.Attachments.Add(attachment);
}
}
client.Send(mail);
}
retVal.Success = true;
}
catch (Exception exception)
{
retVal.Success = false;
LogUtil.LogException(exception);
retVal.Message = exception.ToString();
}
return retVal;
}
and then the contract:
[DataContract]
public class EmailSendInput
{
[DataMember]
public string From { get; set; }
[DataMember]
public List<string> To { get; set; }
[DataMember]
public string Subject { get; set; }
[DataMember]
public string Body { get; set; }
[DataMember]
public List<Attachment> Attachments { get; set; }
}
Implemented as:
public EmailSendResponse SendEmail(EmailSendInput input)
{
try
{
return this.dataAgent.SendEmail(input);
}
catch (Exception e)
{
this.logger.LogException(e, 2);
throw new FaultException(“An error occured in SendEmail. Error details : ” + this.BuildMessage(e));
}
}
and the Email response:
[DataContract]
public class EmailSendResponse
{
[DataMember]
public bool Success { get; set; }
[DataMember]
public string Message { get; set; }
}
So now we have the problem. I basically had to recreate his datamember for attachment in the contract EmailSendInput to a
public List<EmailEncodedAttachment> Attachments { get; set; }
and added a new contract called EmailEncodedAttachment and process how he was handling the attachment differently. I’ve also included the MVC controller calls in case it might help you as well.
SOLUTION:
[DataContract]
public class EmailSendInput
{
[DataMember]
public string From { get; set; }
[DataMember]
public List<string> To { get; set; }
[DataMember]
public string Subject { get; set; }
[DataMember]
public string Body { get; set; }
[DataMember]
public List<EmailEncodedAttachment> Attachments { get; set; }
}
[DataContract]
public class EmailEncodedAttachment
{
[DataMember]
public string Base64Attachment;
[DataMember]
public string Name;
/// <summary>
/// One of the System.Net.Mime.MediaTypeNames
/// </summary>
[DataMember]
public string MediaType;
}
}
retVal.Message = exception.ToString();
}
return retVal;
}
public EmailSendResponse SendEmail(EmailSendInput input)
{
EmailSendResponse retVal = new EmailSendResponse();
try
{
string smtpServer = ConfigurationManager.AppSettings[“SmtpServer”] ?? “url”;
string smtpPort = ConfigurationManager.AppSettings[“SmtpPort”] ?? “portnum”;
using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
{
var mail = new MailMessage
{
From = new MailAddress(input.From),
Subject = input.Subject,
Body = input.Body
};
input.To.ForEach(t => mail.To.Add(t));
if (input.Attachments != null && input.Attachments.Count > 0)
{
foreach (var fileAttachment in input.Attachments)
{
mail.Attachments.Add(this.CreateAttachment(fileAttachment));
}
}
client.Send(mail);
}
retVal.Success = true;
}
catch (Exception exception)
{
retVal.Success = false;
LogUtil.LogException(exception);
retVal.Message = exception.ToString();
}
return retVal;
}
The MVC controller action calls the service like so:
EmailSendInput emailSendInput = new EmailSendInput
{
Attachments = new List<EmailEncodedAttachment>(),
Body = model.Body,
To = new List<string> { model.EmailTo },
From = model.EmailFrom,
Subject = model.EmailSubject
};
if (model.Files != null)
{
foreach (var file in model.Files)
{
if (file != null && file.ContentLength > 0)
{
// the filename needs to be nice looking
string prettyFileName =
file.FileName.Substring(
file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
file.FileName.Length
– file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);
var attachment = this.CreateAttachment(prettyFileName, file.InputStream);
emailSendInput.Attachments.Add(attachment);
}
}
}
B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
if (!emailSendResponse.Success)
{
throw new Exception(emailSendResponse.Message);
}
and finally the encoding method which makes this possible:
private EmailEncodedAttachment CreateAttachment(string fileName, Stream stream)
{
EmailEncodedAttachment att = new EmailEncodedAttachment
{
Name = fileName,
MediaType = System.Net.Mime.MediaTypeNames.Text.Plain
};
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
att.Base64Attachment = Convert.ToBase64String(buffer);
return att;
}
There you have it folks. I hope you have a great Sunday!
.NET, action, AppSettings, Attachment, Attachments, Body, BuildMessage, byte, c#, client, CODE, colleague, ConfigurationManager, ContentLength, ContentStream, controller, Convert, Count, Crashes, CreateAttachment, DataContract, DataMember, Email, EmailEncodedAttachment, EmailFrom, EmailSendInput, EmailSendResponse, EmailSubject, EmailTo, error, Exception, FaultException, filename, Files, foreach, From, InputStream, LastIndexOf, Length, List, LogException, LogUtil, MailMessage, MediaType, MediaTypeNames, Message, method, Mime, MVC, Name, Ordinal, parameter, Plain, prettyFileName, Read, response, retVal, Send, SendEmail, SmtpClient, SmtpPort, SmtpServer, solution, Stream, StringComparison, Subject, System, Text, Value, WCF
C# Application linked to SharePoint List Web Service
Posted by Kelly's Chronicles in .NET, C#, SharePoint on April 29, 2012
This weekend found myself knee deep in a crisis that my friend who had migrated from SharePoint 2003 to 2007 (there were reasons he couldn’t go to 2010). Simply put the migration from SharePoint 2003 to 2007 had broken his application (tracking program that submitted data to a 2003 SharePoint List) because in SharePoint 2007 you can’t do this while not on the actual server if you have “Web Page Security Validation” enabled. So for the code below you have to have SPWeb.AllowUnsafeUpdates = true; . Obviously not the ideal solution for my friend but we didn’t have time to screw around. Here is what I did….
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Xml;
using System.ServiceModel;
using System.Net;
namespace Trigger_Tracker
{
public partial class Form1 : Form
{//form move on click and drag
bool FormMoving;
Point initialPoint;
TriggerTrackerPictureBox frmPicture;
public Form1()
{//form move on click and drag
InitializeComponent();
comboBox1.SelectedIndex = 0;
FormMoving = false;
frmPicture = new TriggerTrackerPictureBox();
frmPicture.localForm = this;
frmPicture.Owner = this;
frmPicture.Show();
frmPicture.Width = 68;
frmPicture.Height = 65;
SetPositionOfPictureForm();
}
private void SetPositionOfPictureForm()
{
frmPicture.Top = this.Top + 26;
frmPicture.Left = this.Left + 87;
}
private void TrackerButton(object sender, EventArgs e)
{
string listGUID = “A93E1A7E-67D0-4D7D-A4ED-803D7DFE684B”;
string viewGUID = “6B2F3EF2-4B0C-41E1-B87E-0C3185B587DD”;
//string viewGUID2 = “6B2F3EF2-4B0C-41E1-B87E-0C3185B587DD”;
int ItemCounter = 1;
ServiceList.Lists listService = new ServiceList.Lists();
// RetentionLists.ListsSoapClient listService = new RetentionLists.ListsSoapClient();
//////
listService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
//listService.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
XmlNode activeItemData = listService.GetListItems(listGUID, viewGUID, null, null, “100”, null);
XmlDocument xDoc = new XmlDocument();
string tmpString = activeItemData.InnerXml.Replace(“\r\r”, “”);
xDoc.LoadXml(tmpString);
XmlNamespaceManager nsManager = new XmlNamespaceManager(xDoc.NameTable);
nsManager.AddNamespace(“z”, “#RowsetSchema”);
nsManager.AddNamespace(“rs”, “urn:schemas-microsoft-com:rowset”);
XmlNodeList xNode = xDoc.SelectNodes(“/rs:data/z:row”, nsManager);
foreach (XmlNode tmpNode in xNode)
ItemCounter++;
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append(“<Method ID='” + ItemCounter + “‘ Cmd=’New’>”);
strBuilder.Append(“<Field Name=’Attachments’>” + “0” + “</Field>”);
strBuilder.Append(“<Field Name=’Title’>” + PolicyNumber.Text + “</Field>”);
strBuilder.Append(“<Field Name=’Reason’>” + comboBox1.Text + “</Field>”);
strBuilder.Append(“</Method>”);
string strBatch = strBuilder.ToString();
XmlDocument newDoc = new XmlDocument();
XmlElement newElement = newDoc.CreateElement(“Batch”);
newElement.SetAttribute(“OnError”, “Continue”);
newElement.SetAttribute(“ViewName”, viewGUID);
newElement.InnerXml = strBatch;
XmlNode returnNode = listService.UpdateListItems(listGUID, newElement);
this.comboBox1.Text = “Please Select….”;
this.PolicyNumber.Text = “”;
this.PolicyNumber.Mask = “0000000000”;
comboBox1.Focus();
}
public void Form1_MouseUp(object sender, MouseEventArgs e)
{//form move on click and drag
FormMoving = false;
}
public void Form1_MouseMove(object sender, MouseEventArgs e)
{//form move on click and drag
if (FormMoving)
{
if ((Left + e.X – initialPoint.X) <= 0)
Left = 0;
else if ((Right + e.X – initialPoint.X) >= Screen.PrimaryScreen.Bounds.Right)
Left = Screen.PrimaryScreen.Bounds.Right – Width;
else
Left = Left + e.X – initialPoint.X;
if ((Top + e.Y – initialPoint.Y) <= 0)
Top = 0;
else if ((Bottom + e.Y – initialPoint.Y) >= Screen.PrimaryScreen.Bounds.Bottom)
Top = Screen.PrimaryScreen.Bounds.Bottom – Height;
else
Top = Top + e.Y – initialPoint.Y;
}
SetPositionOfPictureForm();
}
public void Form1_MouseDown(object sender, MouseEventArgs e)
{//form move on click and drag
FormMoving = true;
initialPoint = new Point(e.X, e.Y);
}
public void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{//form move on click and drag
FormMoving = true;
initialPoint = new Point(e.X, e.Y);
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
}
private void pictureBox1_MouseHover(object sender, EventArgs e)
{
}
public void label1_MouseHover(object sender, EventArgs e)
{
FormMoving = false;
}
public void label1_MouseUp(object sender, MouseEventArgs e)
{
FormMoving = false;
}
public void Form1_MouseHover(object sender, EventArgs e)
{
this.Opacity = 1;
}
public void Form1_MouseLeave(object sender, EventArgs e)
{
if(!PolicyNumber.Focused)
this.Opacity = .25;
}
public void pictureBox1_MouseLeave(object sender, EventArgs e)
{
this.Opacity = 1;
}
public void pictureBox1_MouseHover_1(object sender, EventArgs e)
{
this.Opacity = 1;
}
public void Form1_Click(object sender, EventArgs e)
{
comboBox1.Focus();
}
}
}
.NET Framework, 2003, 2010, activeItemData, AddNamespace, AllowUnsafeUpdates, Append, Application, Attachments, Batch, Bottom, Bounds, c#, ChannelFactory, ClientCredential, Collections, ComponentModel, Continue, CreateElement, CredentialCache, Credentials, crisis, csharp, Data, DefaultNetworkCredentials, EventArgs, Field, Focus, Form, Forms, friend, Generic, GetListItems, InitializeComponent, initialPoint, InnerXml, ItemCounter, knee, Left, Linq, List, listGUID, Lists, listService, ListsSoapClient, LoadXml, Mask, method, migration, MouseEventArgs, Name, NameTable, nsManager, OnError, Owner, PAGE, Point, PolicyNumber, Reason, Replace, RetentionLists, RowsetSchema, schemas, Select, SelectedIndex, SelectNodes, sender, server, Service, ServiceList, ServiceModel, SetAttribute, SetPositionOfPictureForm, SharePoint, solution, SPWeb, StringBuilder, System, Text, Title, TrackerButton, TriggerTrackerPictureBox, Trigger_Tracker, UpdateListItems, Validation, viewGUID, ViewName, Web Page Security, Width, Windows, xDoc, XmlDocument, XmlElement, XmlNamespaceManager, XmlNode, XmlNodeList, xNode
Get or Write Image Metadata with vb.net
Posted by Kelly's Chronicles in .NET, vb.net on September 1, 2011
I recently started a new contract with a local company and their project is quite image intensive. One of the tasks set before me was to store custom data in an image. Things such as the title, comments and keywords. Turned out to be quite an extensive undertaking. With the help of some other sources, I came up with this code. Ironically as it turned out we can’t use my solution because of some issues with custom image formats that are not respected in Microsoft Windows. But it is here for you! I will post the C# version soon. Also pay attention to your encoding. This was an issue that tripped me up here for a while.
Imports System.Collections.Generic
Imports System.Text
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Reflection
Imports System.IO
Public Class clsReadMetaData
Public Function ReadEXIFMetadata(ByVal filepath As String) As ImageMetadata
Dim fs As New FileStream(filepath, FileMode.Open, FileAccess.Read)
Dim image__1 As Image = Image.FromStream(fs)
Dim imagePropertyItems As PropertyItem() = image__1.PropertyItems
Dim imageMetadata As New ImageMetadata()
For Each pi As PropertyItem In imagePropertyItems
Select Case CType(pi.Id, EXIFProperty)
Case EXIFProperty.Title
imageMetadata.Title = Encoding.Unicode.GetString(pi.Value)
‘imageMetadata.Title = Encoding.UTF32.GetString(pi.Value)
Exit Select
Case EXIFProperty.Author
imageMetadata.Author = Encoding.Unicode.GetString(pi.Value)
‘imageMetadata.Author = Encoding.UTF8.GetString(pi.Value)
Exit Select
Case EXIFProperty.Keywords
imageMetadata.Keywords = Encoding.Unicode.GetString(pi.Value)
‘imageMetadata.Keywords = Encoding.UTF8.GetString(pi.Value)
Exit Select
Case EXIFProperty.Comments
imageMetadata.Comments = Encoding.Unicode.GetString(pi.Value)
‘imageMetadata.Comments = Encoding.UTF8.GetString(pi.Value)
Exit Select
Case Else
Exit Select
End Select
Next
fs.Close()
Return imageMetadata
End Function
Public Sub SaveEXIFMetadata(ByVal image As Image, ByVal metadata As ImageMetadata, ByVal filepath As String)
SaveEXIFMetadataProperty(image, EXIFProperty.Title, metadata.Title, filepath)
SaveEXIFMetadataProperty(image, EXIFProperty.Author, metadata.Author, filepath)
SaveEXIFMetadataProperty(image, EXIFProperty.Keywords, metadata.Keywords, filepath)
SaveEXIFMetadataProperty(image, EXIFProperty.Comments, metadata.Comments, filepath)
End Sub
Private Sub SaveEXIFMetadataProperty(ByVal image As Image, ByVal [property] As EXIFProperty, ByVal propertyValue As String, ByVal filepath As String)
Dim propertyItem As PropertyItem = CreatePropertyItem()
propertyItem.Id = CInt([property])
‘ Type=1 means Array of Bytes.
propertyItem.Type = 2
propertyItem.Len = propertyValue.Length
‘propertyItem.Value = Encoding.Unicode.GetBytes(propertyValue)
propertyItem.Value = Encoding.UTF8.GetBytes(propertyValue)
image.SetPropertyItem(propertyItem)
image.Save(filepath)
End Sub
Private Function CreatePropertyItem() As PropertyItem
Dim ci As System.Reflection.ConstructorInfo = GetType(PropertyItem).GetConstructor(BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.[Public], Nothing, New Type() {}, Nothing)
Return DirectCast(ci.Invoke(Nothing), PropertyItem)
End Function
End Class
Public Enum EXIFProperty
Title = 40091
Author = 40093
Keywords = 40094
Comments = 40092
End Enum
Public Class ImageMetadata
Private _title As String = String.Empty
Private _author As String = String.Empty
Private _keywords As String = String.Empty
Private _comments As String = String.Empty
Public Sub New()
Me._title = String.Empty
Me._author = String.Empty
Me._keywords = String.Empty
Me._comments = String.Empty
End Sub
Public Sub New(ByVal title As String, ByVal author As String, ByVal keywords As String, ByVal comments As String)
Me._title = title
Me._author = author
Me._keywords = keywords
Me._comments = comments
End Sub
Public Property Title() As String
Get
Return Me._title
End Get
Set(ByVal value As String)
Me._title = value
End Set
End Property
Public Property Author() As String
Get
Return Me._author
End Get
Set(ByVal value As String)
Me._author = value
End Set
End Property
Public Property Keywords() As String
Get
Return Me._keywords
End Get
Set(ByVal value As String)
Me._keywords = value
End Set
End Property
Public Property Comments() As String
Get
Return Me._comments
End Get
Set(ByVal value As String)
Me._comments = value
End Set
End Property
End Class
.NET Framework, Array, author, BindingFlags, Bytes, Case, Class, Close, Collections, Comments, ConstructorInfo, CreatePropertyItem, custom, Data, DirectCast, Enum, FileMode, filepath, FileStream, FromStream, FUNCTION, Generic, GetBytes, GetConstructor, GetType, Image, ImageMetadata, imagePropertyItems, Imports, instance, Keywords, Length, Metadata, Microsoft, NonPublic, Open, Private, PropertyItem, PropertyItems, propertyValue, Public, Read, ReadEXIFMetadata, Reflection, Return, Save, Select, SetPropertyItem, solution, System, tasks, Text, Title, Type, Unicode, Value, vb.net, version, Windows, Write, _author, _comments, _keywords, _title
Fluent C# Review : Chapter Three
Posted by Kelly's Chronicles in .NET, C#, Fluent on August 12, 2011
I am reviewing an advanced copy of the book Fluent C# by noted .NET author Rebecca Riordan.
My focus today will be on chapter three. Chapter three picks up where chapter two left off in describing the Visual Studio environment. It does an excellent job of reviewing the more intricate details of Visual Studio. Again, it ignores winforms and focuses on the Windows Presentation Foundation (WPF) forms and design editor. Encouraging the reader to customize the interface for themselves, it shows how to do that. I certainly have not seen that done before so early on in the process and in such an easygoing manner. It ends the first section explaining what Intellisense is. Later on in this chapter it goes into how members are listed. An excellent tutorial on refactoring and such is also discussed. It’s possible this discussion could have waited a bit until later on but it still works here.
We then move on to cover what a Visual Studio solution and project is and what it contains including a very helpful diagram, as they seem to always do in this book, explaining what the relationship between the various items in a Visual Studio solution and project are.
The next section introduces designer and source files, resources and your design documents. Covering how to add items to a solution or project comes next along with a graphical and step by step process of how to modify project properties. Changing the icon and window property is one such example they cover. Then we build the application to see the results of the changes.
Further customization of the Visual Studio environment is then discussed in the usual graphical and step by step nature this book is so good at.
Overall I wish I had had a book like this when I first started using Visual Studio so many eons ago!
The next chapter gets into debugging and deploying an application. Moving right along the user shouldn’t be overwhelmed with this patient, easy going manner of teaching.
.NET, author, basics, Chapter, csharp, diagram, discussion, editor, environment, example, Fluent, Foundation, graphical, icon, Intellisense, interface, items, manner, Presentation, properties, reader, Rebecca, Rebecca Riordan, relationship, resources, Review, Riordan, solution, Studio, Three, tutorial, user, Visual, Visual Studio, Windows, Windows Presentation Foundation, WPF
Recent Comments
Archives
- April 2018
- January 2018
- December 2017
- June 2017
- May 2017
- May 2016
- April 2016
- September 2015
- July 2014
- June 2014
- November 2012
- October 2012
- June 2012
- May 2012
- April 2012
- January 2012
- September 2011
- August 2011
- July 2011
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- August 2008
- July 2008
- June 2008
- May 2008
Get or Write Image Metadata with C#
Posted by Kelly's Chronicles in .NET, C#, vb.net on July 15, 2014
Good morning! it’s always fun when old code gets to get used again. And it gave me an opportunity to convert this snippet to C#. Basically what we are trying to do is write or get metadata to an image. As those folks who commented on the previous post noted, this code will not remove existing metadata. It is a problem I still have not found a solution for however. If any of you know the answer please let us know! Anyway here it is converted and still useable after all this time.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.IO;
public class clsReadMetaData
{
public ImageMetadata ReadEXIFMetadata(string filepath)
{
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
Image image__1 = Image.FromStream(fs);
PropertyItem[] imagePropertyItems = image__1.PropertyItems;
ImageMetadata imageMetadata = new ImageMetadata();
foreach (PropertyItem pi in imagePropertyItems)
{
switch ((EXIFProperty)pi.Id)
{
case EXIFProperty.Title:
imageMetadata.Title = Encoding.Unicode.GetString(pi.Value);
//imageMetadata.Title = Encoding.UTF32.GetString(pi.Value)
break;
case EXIFProperty.Author:
imageMetadata.Author = Encoding.Unicode.GetString(pi.Value);
//imageMetadata.Author = Encoding.UTF8.GetString(pi.Value)
break;
case EXIFProperty.Keywords:
imageMetadata.Keywords = Encoding.Unicode.GetString(pi.Value);
//imageMetadata.Keywords = Encoding.UTF8.GetString(pi.Value)
break;
case EXIFProperty.Comments:
imageMetadata.Comments = Encoding.Unicode.GetString(pi.Value);
//imageMetadata.Comments = Encoding.UTF8.GetString(pi.Value)
break;
default:
break;
}
}
fs.Close();
return imageMetadata;
}
public void SaveEXIFMetadata(Image image, ImageMetadata metadata, string filepath)
{
SaveEXIFMetadataProperty(image, EXIFProperty.Title, metadata.Title, filepath);
SaveEXIFMetadataProperty(image, EXIFProperty.Author, metadata.Author, filepath);
SaveEXIFMetadataProperty(image, EXIFProperty.Keywords, metadata.Keywords, filepath);
SaveEXIFMetadataProperty(image, EXIFProperty.Comments, metadata.Comments, filepath);
}
private void SaveEXIFMetadataProperty(Image image, EXIFProperty property, string propertyValue, string filepath)
{
PropertyItem propertyItem = CreatePropertyItem();
propertyItem.Id = Convert.ToInt32(property);
// Type=1 means Array of Bytes.
propertyItem.Type = 2;
propertyItem.Len = propertyValue.Length;
//propertyItem.Value = Encoding.Unicode.GetBytes(propertyValue)
propertyItem.Value = Encoding.UTF8.GetBytes(propertyValue);
image.SetPropertyItem(propertyItem);
image.Save(filepath);
}
private PropertyItem CreatePropertyItem()
{
System.Reflection.ConstructorInfo ci = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null);
return (PropertyItem)ci.Invoke(null);
}
}
public enum EXIFProperty
{
Title = 40091,
Author = 40093,
Keywords = 40094,
Comments = 40092
}
public class ImageMetadata
{
private string _title = string.Empty;
private string _author = string.Empty;
private string _keywords = string.Empty;
private string _comments = string.Empty;
public ImageMetadata()
{
this._title = string.Empty;
this._author = string.Empty;
this._keywords = string.Empty;
this._comments = string.Empty;
}
public ImageMetadata(string title, string author, string keywords, string comments)
{
this._title = title;
this._author = author;
this._keywords = keywords;
this._comments = comments;
}
public string Title
{
get
{
return this._title;
}
set
{
this._title = value;
}
}
public string Author
{
get
{
return this._author;
}
set
{
this._author = value;
}
}
public string Keywords
{
get
{
return this._keywords;
}
set
{
this._keywords = value;
}
}
public string Comments
{
get
{
return this._comments;
}
set
{
this._comments = value;
}
}
}
Join me on Facebook
Anyway, Array, author, BindingFlags, Bytes, Close, Collections, Comments, ConstructorInfo, Convert, CreatePropertyItem, FileMode, filepath, FileStream, FromStream, Generic, GetBytes, GetConstructor, Image, ImageMetadata, imagePropertyItems, instance, Keywords, Length, Metadata, NonPublic, Open, PropertyItem, PropertyItems, propertyValue, Public, Read, ReadEXIFMetadata, Reflection, Save, SaveEXIFMetadata, SetPropertyItem, snippet, solution, System, Text, Title, Type, Unicode, Value, Write, _author, _comments, _keywords, _title
Leave a comment