четверг, 27 сентября 2012 г.

C# шлем email, используя TLS и SSL

Рассказывать ( как всегда много не буду)
Просто пример рабочего кода, где шлется сообщение на gmail используя TLS, к сожалению System.Net.Mail.SmtpClient не шлет сообщения используя SSL протокол через порт 465.

using System;
using System.Net;
using System.Windows.Forms;
using System.Net.Mail;

namespace Mailer
{

        private void Send()
        {
            //Создаем сообщение
            MailMessage message = new MailMessage("from_email@gmail.com", "to_email@gmail.com");
            message.Subject = "Test";
            message.Body = "Test";
            
            //Создаем клиента для отправки
            SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587);

            //Логин+пароль
            NetworkCredential credentials = new NetworkCredential(
                "login",
                "password");
            
           
            smtpClient.Credentials = credentials;
            //Включаем SSL
            smtpClient.EnableSsl = true;
            //Посылаем
            smtpClient.Send(message);
        }
}

А вот что бы слать с SSL можно воспользоватся компонентом CDO
Вот здесь можно прочитать подробный мануал http://support.microsoft.com/kb/310212.
Ну а я представляю кусок кода


 private void Send2()
        {
                string yourEmail = "..............@gmail.com";

                CDO.Message message = new CDO.Message();
                CDO.IConfiguration configuration = message.Configuration;
                ADODB.Fields fields = configuration.Fields;

                Console.WriteLine(String.Format("Configuring CDO settings..."));

                // Set configuration.
                // sendusing:               cdoSendUsingPort, value 2, for sending the message using the network.
                // smtpauthenticate:     Specifies the mechanism used when authenticating to an SMTP service over the network.
                //                                  Possible values are:
                //                                  - cdoAnonymous, value 0. Do not authenticate.
                //                                  - cdoBasic, value 1. Use basic clear-text authentication. (Hint: This requires the use of "sendusername" and "sendpassword" fields)
                //                                  - cdoNTLM, value 2. The current process security context is used to authenticate with the service.

                ADODB.Field field = fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"];
                field.Value = "smtp.gmail.com";

                field = fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"];
                field.Value = 465;

                field = fields["http://schemas.microsoft.com/cdo/configuration/sendusing"];
                field.Value = CDO.CdoSendUsing.cdoSendUsingPort;

                field = fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"];
                field.Value = CDO.CdoProtocolsAuthentication.cdoBasic;

                field = fields["http://schemas.microsoft.com/cdo/configuration/sendusername"];
                field.Value = yourEmail;

                field = fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"];
                field.Value = "**********";

                field = fields["http://schemas.microsoft.com/cdo/configuration/smtpusessl"];
                field.Value = "true";

                fields.Update();

                Console.WriteLine(String.Format("Building CDO Message..."));

                message.From = yourEmail;
                message.To = yourEmail;
                message.Subject = "Test message.";
                message.TextBody = "This is a test message. Please disregard.";

 

                // Send message.
                message.Send();
        }

среда, 29 августа 2012 г.

WPF. Ресурсы и стили

Ресурсы очень важная часть WPF.
Тут я кратко опишу как создать ресурс и подключить его к форме, что бы испорльзовать.
Создаем ResourceDictionary
В моем случае в нем будет один стиль, который определяется для ТулБара.  Назвем его ToolBarStyle.xaml.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="SimpleToolBar" TargetType="{x:Type ToolBar}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToolBar}">
                    <Border x:Name="Border"  CornerRadius="3" 
                      BorderThickness="1"
                      BorderBrush="#404040">
                        <DockPanel >
                            <Thumb x:Name="ToolBarThumb" Width="10"/>
                            <ToolBarPanel x:Name="PART_ToolBarPanel"   IsItemsHost="true" Margin="0,1,2,2"/>
                        </DockPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Для того что бы подключить его в форму нужно написать следующее 
<Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary 
                  Source="ToolBarStyle.xaml">
                </ResourceDictionary>               
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

Теперь наша форма будет видеть стили описанные в словаре ресурсов.
И соответственно используем
   <ToolBar  Name="toolBar1" Style="{StaticResource SimpleToolBar}"

вторник, 7 августа 2012 г.

Определить сообщение написано латинью или кирилицой (актуально для смс)

Простенькая функция, которая определяет является ли написанной на латыне строка или на кирилице.


         /// <summary>
        /// Определяем тип сообщения (кирилица или латынь)
        /// </summary>
        /// <param name="message"></param>
        /// <returns>cyr - если кирилица, lat - если латынь</returns>
        static public string CheckTypeOfMessage(string message)
        {
            //проверяем на наличие кириличных символов, если они есть - кирилица, нет - латынь
            foreach (char c in message)
            {
                int unicode = (int)c;
                if ((unicode >= 1040) && (unicode <= 1111))
                    return "cyr";

            }
            return "lat";

        }

C# Конвертация из одной кодировки в другую

Иногда возникает задача : конвертировать инфу из одной кодировки в другую. Это очень легко делается с помощью класса  Encoding, для того что бы не создавать велосипед

Вот собственно пример с пояснениями

/// <summary>
    /// Класс для конвертации из одной кодировки в другую
    /// </summary>
    public class EncoderConvertor
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="To">Кодировка назначения</param>
        /// <param name="From">Кодировка, с которой кодируем</param>
        /// <param name="myString">Текст</param>
        /// <returns>Тескт в заданной кодировке</returns>
        public static string GetEncoding(Encoding To, Encoding From, String myString)
        {
        return  To.GetString(Encoding.Convert(From, To, From.GetBytes(myString)));
        }


        /// <summary>
        /// Кодирует из Unicode в UTF-8
        /// </summary>
        /// <param name="myString">Текст</param>
        /// <returns></returns>
        public static string GetEncoding(String myString)
        {
           return Encoding.UTF8.GetString(
                Encoding.Convert(
                Encoding.Unicode,
                Encoding.UTF8,
                Encoding.Unicode.GetBytes(myString)));
        
        }
    }



понедельник, 30 июля 2012 г.

C#. Garbage collection comics


C#/ DataGridView. Делаем некоторые ячейки в строке только для чтения.

Иногда возникает задача, сделать так, что бы некоторые ячейки в строке были только для чтения, ну или выделялись другим шрифтом и т.д.. Достигается это очень просто. Вот так собственно

           //обьявляем ячейки

            DataGridViewCheckBoxCell cell1 = new DataGridViewCheckBoxCell(false);
            DataGridViewTextBoxCell cell2 = new DataGridViewTextBoxCell();
           //поскольку запрещать редактировать мы будем чекбокс ему нужно задать дуфолтное значение для нула, иначе программа будет выдать ошибки
            cell1.EditingCellFormattedValue = false;
         
           //Обьявляем колонки
            DataGridViewColumn col1 = new DataGridViewColumn(cell1);
            col1.DefaultCellStyle.NullValue = false;
            DataGridViewColumn col2 = new DataGridViewColumn(cell2);

         
           //Добавляем их в грид
            this.dataGridView1.Columns.Add(col1);
            this.dataGridView1.Columns.Add(col2);
         
           //Создаем строку, которую можно изменять
            DataGridViewRow row = new DataGridViewRow();

            row.Cells.AddRange(col1.CellTemplate, col2.CellTemplate);  //или вот так row.CreateCells(dataGridView1);
            row.Cells[0].ReadOnly = false;
            row.Cells[1].Value = "ReadOnly = false";

           //Отображаем в ячейке текст полужирным
            row.Cells[1].Style.Font = new Font(Font, FontStyle.Bold);

            this.dataGridView1.Rows.Add(row);
         
            //Создаем строку, в которой первую ячейку изменять нельзя
            cell1 = new DataGridViewCheckBoxCell();
            cell2 = new DataGridViewTextBoxCell();
            row = new DataGridViewRow();
            row.Cells.AddRange(cell1, cell2);
            //Говорим ячейке что она только для чтения
            row.Cells[0].ReadOnly = true;


            row.Cells[1].Value = "ReadOnly = true";
       
            this.dataGridView1.Rows.Add(row);

вторник, 29 мая 2012 г.

WPF. Используем Microsoft.Practices.Prism

Очень удобная штука Microsoft.Practices.Prism.
И так используем Microsoft.Practices.Prism.Commands. Он содержит CompositeCommandDelegateCommand,DelegateCommand<T> и DelegateCommandBase.
Использовать мы будем DelegateCommand.

Объявляем в нашем ViewModel поле типа DelegateCommand

        /// <summary>
        /// Загрузка
        /// </summary>
         private DelegateCommand loadExec;

и свойство


        /// <summary>
        /// Загрузка
        /// </summary>
         public DelegateCommand LoadExec
         {
             get { return this.loadExec; }
             set { this.loadExec=value; }
         }

Прописываем функцию

        /// <summary>
        /// Загрузка
        /// </summary>
         private void Load()
         {
             DoSomething();           
         }
И привязываем все это дело
    this.loadExec = new DelegateCommand(Load);

А в XAML добавляем
 <Button   Command="{Binding Path=LoadExec,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

Ну вот теперь при нажатие на кнопку у нас будет выполнятся функция Load().


MVVM (модель-представление-модель представления))

О самом шаблоне можно почитать тут и тут. (Ну и еще много где).
Но иногда нам нужно разделить логику и представление на разные проекты.
Так вот сдесь я выложу клас, с помощью которого можно отвязать вьюв от самых форм.

1. Проект с представлениями доолжен оканчиваться на ViewModel
2. Проект с самими XAML должен оканчиваться на WPF.


 public static bool? ShowWindowAsDialog(object viewModel,  Hashtable param = null)
        {
            Window view = GetView(viewModel, param);
            view.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            return view.ShowDialog();
        }

///Получаем наше View

 private static Window GetView(object viewModel, Hashtable param = null)
        {
            Type viewType = viewModel.GetType();
            string viewName = viewType.Name.Replace("ViewModel", String.Empty);
            string[] assemblyNameParts = viewType.Assembly.FullName.Split(new char[] { ',' });
            string assemblyName = assemblyNameParts[0].Replace("ViewModel", "Wpf" );
            Assembly assembly = Assembly.Load(assemblyName);

            Window view = null;
            if (param == null)
            {
                view = (Window)System.Activator.CreateInstance(assembly.GetType(String.Concat(assemblyName, ".", viewName)), new object[] { viewModel });
            }
            else
            {
                view = (Window)System.Activator.CreateInstance(assembly.GetType(String.Concat(assemblyName, ".", viewName)), new object[] { viewModel, param });
            }

            if (view == null)
                throw new Exception(String.Format("Cannot show window {0}", viewName));

            ElementHost.EnableModelessKeyboardInterop(view);
            return view;
}



WPF. Локализация форм.

При создании проекта автоматически создается папочка Properties. Там размещен дефолтный файл ресурсов Resources.resx.
Для того что бы все это дело красиво использовать сначала в файле ресурсов свойству Custom Tool присваиваем значение PublicResXFileCodeGenerator.

В сам файл добавляем названия переменных и их значения. Делаем еще один файл ресурсов, который назовем Resources.en.resx - для английской версии, туда переносим названия наших переменных и пишем значения на английском,
 например bonus - бонус, bonus - bonus.

В XAML добавляем строку
 xmlns:Properties="clr-namespace:название_вашего_простанства_имен.Properties"
и
 <Label Content="{x:Static Properties:Resources.bonus}"/>
теперь в зависимости от вашей локализации лейбл будет показывать "bonus" или "бонус" .

Просто и незатейливо:)

пятница, 6 января 2012 г.

C# Передаем и получаем данные с помощью HttpWebReques, HttpWebResponse


Так як розповідати я не вмію, то відразу вивішую код з коментами ( з них думаю і так все зрозуміло).

  /// <summary>  
 /// Класс для отправки запросов 
  /// </summary>   
 class HttpRequest   {    
  private string URI = String.Empty;  
   private string _method = "POST"; 
   /// <summary>     /// Дефолтный конструктор     /// </summary>     private HttpRequest()     { }   
  /// <summary>     /// Конструктор     /// </summary>     /// <param name="uri">Ссылка для работы с веб-интерфесом</param>     public HttpRequest(string uri)  
           {     
         this.URI = uri;
       }   
   /// <summary>     /// Конструктор     /// </summary>     /// <param name="uri">ССылка для работы с веб интерфесом</param>     /// <param name="method">метод (POST или GET)</param>  
   public HttpRequest(string uri, string method)  
    {       this.URI = uri;    
    this._method = method;     }    
   /// <summary>     /// Шлем запрос в виде xml     /// </summary>     /// <param name="doc">ответ веб-интерфейса</param>     /// <returns></returns>   
   public XmlDocument SendRequest(XmlDocument doc)
     {       HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(this.URI);  
      // Разрешаем авторедирект       httpWebRequest.AllowAutoRedirect = true;  
      // Создаем для запроса новый контейнер для хранения сессий       httpWebRequest.CookieContainer = new CookieContainer();   
     // Следующие строки итак понятны    
    httpWebRequest.Method = this._method;       httpWebRequest.ContentType = "application/x-www-form-urlencoded";       byte[] ByteQuery = System.Text.Encoding.ASCII.GetBytes(doc.OuterXml);      
 // Длинна запроса (обязательный параметр)    
 httpWebRequest.ContentLength = ByteQuery.Length;
       // Открываем поток для записи     
   Stream QueryStream = httpWebRequest.GetRequestStream();  
      // Записываем в поток (это и есть POST запрос)       QueryStream.Write(ByteQuery, 0, ByteQuery.Length);    
    // Закрываем поток       QueryStream.Close();     
   // Объект с ответом сервера       HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();     
   // Присваиваем сессию     
  httpWebResponse.Cookies = httpWebRequest.CookieContainer.GetCookies(httpWebRequest.RequestUri);       // Открываем поток для чтения   
     Stream stream = httpWebResponse.GetResponseStream();
       // Читаем из потока   
     StreamReader reader = new StreamReader(stream);  
      // Возвращаем результат запроса   
     XmlDocument document = new XmlDocument();       document.LoadXml(reader.ReadToEnd());    
     return document;  
    }   
  } * This source code was highlighted with Source Code Highlighter.

И еще один способ

        /// <summary>
        /// Посылает GET-запрос сервису и возвращает ответ в виде Xml документа.
        /// </summary>


 public XmlDocument SendRequest(string url)
        {
            XmlDocument xml = null;
            MemoryStream stream = null;
            WebClient client = null;
            try
            {
                client = new WebClient();               
                byte[] respBytes = client.DownloadData(url);
                stream = new MemoryStream(respBytes);
                xml = new XmlDocument();
                xml.Load(stream);
            }
            catch
            {
                throw new Exception("Ошибка при подключении!");
            }
            finally
            {
                if (stream != null)
                {
                    stream.Dispose();
                }

                if (client != null)
                {
                    client.Dispose();
                }
            }

            return xml;
        }