fredcaldera
Mon Sep 27 12:17:02 CDT 2004
Hi Chris,
I read you previous reply and wonder if the following is possible: Can I
attach a file to an email, using the ActivityAttachmentUpload.srf? I have
been trying to do it but no success so far. I followed your initial remarks
but nothing happens. It seems to me that because I do not know which
parameters are required (filename, size and content type), i cannot go
forward... do you have any idea? I want to avoid using other sw such as
modified web client..
Thanks
"Chris Ericoli" wrote:
> Sorry - Just re read your post, and realised that you are trying to upload
> an attachment to a note. Regardless, the code I've posted should work, as
> it is based on a the attachment ID. Let me know if you have problems, and
> I'll see if I can help.
>
> CHeers
>
> Chris
>
> "Chris Ericoli" <cericoliNOspm@removethisfamill.com.au> wrote in message
> news:un%23bV0TmEHA.3536@TK2MSFTNGP12.phx.gbl...
> > Hi Paul,
> >
> > I have done this, although in VB. I used an adapted version of the
> > webclient object, available from:
> >
> >
http://www.c-sharpcorner.com/Code/2003/May/DotNetBugs.asp
> >
> > Getting a file to attach to a CRM email was probably one of the most
> > frustrating and time consuming things I have ever done, and the result is
> a
> > culmination of numerous attempts at resolution, and therefore there is
> > probably some redundancy as a result trying different approaches.
> >
> > I'm sure by now you know how to use the SDK to create the email, and
> > subsequently the attachment. I am also sure that you have realised that
> the
> > emailattachment object returns the ID for the attachment, but does not
> allow
> > you to actually specify a file for upload.
> >
> > The script I wrote creates the email, sets the recipients, sets the
> sender,
> > inserts the body and saves the email. After which it creates a new
> > attachment and associates it with the email. Finally it uploads a
> > particular file (for my purposes I knew the filename, as it had been
> > previously created) to the attachment. Finally it uses some client side
> > script in order to launch a new browser window to display the created
> email
> > object, with the file already attached. I did not want to automate the
> > sendign of the email, as it does not give the user an opportunity to check
> > it over or attach further files.
> >
> > The following code assumes that you have downloaded the modified web
> client
> > object (norvanco.http.MultipartForm).
> >
> > So...
> >
> > Once you have created the email and obtained the ID for the attachment,
> this
> > is what you need to do:
> >
> > Public Sub UploadAttachment(ByVal userID As String, ByVal merchantID
> As
> > String, ByVal filename As String, ByVal attachID As String, ByVal emailID
> As
> > String)
> >
> > Dim _attachService As String
> > Dim _advWC As New norvanco.http.MultipartForm(_attachService)
> > Dim _advWCFields As New Specialized.NameValueCollection
> > Dim _reqCookies As String
> >
> > _attachService = "
http://" & AppSettings("crmServer") & "/" &
> > AppSettings("crmServicesDir") & "/ActivityAttachmentUpload.srf"
> >
> > 'Add the post data
> > 'From memory the 1001 value for AttachmentType comes from the CRM
> > Enumerations - but you may want to check
> > _advWCFields.Add("AttachmentType", 1001)
> > _advWCFields.Add("AttachmentId", attachID)
> > _advWCFields.Add("UserId", userID)
> > _advWCFields.Add("MerchantId", merchantID)
> >
> > 'The ErrorURL and SuccessURL can be anything. They are used in
> the
> > CRM Web Client to direct a user to a page
> > 'indicating the success/failure of the file upload - Obviously
> with
> > the webclient object, they are not relevant
> > _advWCFields.Add("ErrorURL",
> > "
http://localhost/custom/quotemgmt/test1.aspx")
> > _advWCFields.Add("SuccessURL",
> > "
http://localhost/custom/quotemgmt/test2.aspx")
> >
> > 'Set the post data fields in the modified web client
> > _advWC.setFields(_advWCFields)
> >
> > 'Set the protocol - although not sure if this is necessary
> > _advWC.TransferHttpVersion = New System.Version("1.0")
> >
> > 'Set the attachment type - in my usage, i know that it is going to
> > be an html file attachment
> > _advWC.FileContentType = "text/html"
> >
> > 'You need to transfer the current request's cookie string through
> to
> > the request made by the modified webclient
> >
> > _reqCookies = Page.Request.Headers.Get("Cookie") '(conversely you
> > could use http.context.current.request)
> >
> > 'The sendFile method does not return a value indicating success -
> so
> > you can either rely on a try/catch statement or modify accordingly
> > _advWC.sendFile(filename,
> > System.Net.CredentialCache.DefaultCredentials, _reqCookies)
> >
> > 'Open the email in a new window for the client
> >
> > Dim _sb As New Text.StringBuilder
> > Dim _emailURL As String = "
http://" & AppSettings("crmServer") &
> > "/Activities/Email/edit.aspx?id=" & emailID
> >
> > _sb.Append(vbCrLf + "<script>")
> > _sb.Append(vbCrLf + "var EmailWin = window.open('" & _emailURL &
> "',
> > 'email_win', 'toolbar=no, status=yes, location=no, menubar=no, top=50,
> > left=50, height=533, width=694', '');")
> > _sb.Append(vbCrLf + "</script>")
> >
> > Page.RegisterClientScriptBlock("OpenEmail", _sb.ToString)
> >
> > End Sub
> >
> > I've just checked the site for the Advanced WebClient, and there does not
> > appear to be any restriction on reposting the base code, so here is the
> code
> > including the modifications I made. You may want to check the original
> > against this to find my modifications.
> >
> > If you have any questions, feel free to reply, and I'll see what I can do.
> >
> > Cheers
> >
> > Chris
> >
> >
> >
> > using System;
> > using System.Net;
> > using System.Text;
> > using System.IO;
> > using System.Collections;
> >
> > namespace norvanco.http
> > {
> > /// <summary>
> > /// Allow the transfer of data files using the W3C's specification
> > /// for HTTP multipart form data. Microsoft's version has a bug
> > /// where it does not format the ending boundary correctly.
> > /// Written by: gregoryp@norvanco.com
> > /// </summary>
> > public class MultipartForm
> > {
> > /// <summary>
> > /// Holds any form fields and values that you
> > /// wish to transfer with your data.
> > /// </summary>
> > private System.Collections.Specialized.NameValueCollection
> coFormFields;
> > /// <summary>
> > /// Used mainly to avoid passing parameters to other routines.
> > /// Could have been local to sendFile().
> > /// </summary>
> > protected HttpWebRequest coRequest;
> > /// <summary>
> > /// Used if we are testing and want to output the raw
> > /// request, minus http headers, out to a file.
> > /// </summary>
> > System.IO.Stream coFileStream;
> > /// <summary>
> > /// Difined to build the form field data that is being
> > /// passed along with the request.
> > /// </summary>
> > static string CONTENT_DISP = "Content-Disposition: form-data; name=";
> > /// <summary>
> > /// Allows you to specify the specific version of HTTP to use for
> > uploads.
> > /// The dot NET stuff currently does not allow you to remove the
> > continue-100 header
> > /// from 1.1 and 1.0 currently has a bug in it where it adds the
> > continue-100. MS
> > /// has sent a patch to remove the continue-100 in HTTP 1.0.
> > /// </summary>
> > public Version TransferHttpVersion
> > {get{return coHttpVersion;}set{coHttpVersion=value;}}
> > Version coHttpVersion;
> >
> > /// <summary>
> > /// Used to change the content type of the file being sent.
> > /// Currently defaults to: text/xml. Other options are
> > /// text/plain or binary
> > /// </summary>
> >
> >
> > public string FileContentType
> > {get{return coFileContentType;}set{coFileContentType=value;}}
> > string coFileContentType;
> >
> > /// <summary>
> > /// Initialize our class for use to send data files.
> > /// </summary>
> > /// <param name="url">The web address of the recipient of the data
> > transfer.</param>
> > public MultipartForm(string url)
> > {
> > URL = url;
> > coFormFields = new
> > System.Collections.Specialized.NameValueCollection();
> > ResponseText = new StringBuilder();
> > BufferSize = 1024 * 10;
> > BeginBoundary = "---------------------------7d419e378304a0";
> > TransferHttpVersion = HttpVersion.Version10;
> > FileContentType = "text/html";
> > }
> > //---------- BEGIN PROPERTIES SECTION ----------
> > string _BeginBoundary;
> > /// <summary>
> > /// The string that defines the begining boundary of
> > /// our multipart transfer as defined in the w3c specs.
> > /// This method also sets the Content and Ending
> > /// boundaries as defined by the w3c specs.
> > /// </summary>
> > public string BeginBoundary
> > {
> > get{return _BeginBoundary;}
> > set
> > {
> > _BeginBoundary =value;
> > ContentBoundary = "--" + BeginBoundary;
> > EndingBoundary = ContentBoundary + "--";
> > }
> > }
> > /// <summary>
> > /// The string that defines the content boundary of
> > /// our multipart transfer as defined in the w3c specs.
> > /// </summary>
> > protected string ContentBoundary
> > {get{return _ContentBoundary;}set{_ContentBoundary=value;}}
> > string _ContentBoundary;
> > /// <summary>
> > /// The string that defines the ending boundary of
> > /// our multipart transfer as defined in the w3c specs.
> > /// </summary>
> > protected string EndingBoundary
> > {get{return _EndingBoundary;}set{_EndingBoundary=value;}}
> > string _EndingBoundary;
> > /// <summary>
> > /// The data returned to us after the transfer is completed.
> > /// </summary>
> > public StringBuilder ResponseText
> > {get{return _ResponseText;}set{_ResponseText=value;}}
> > StringBuilder _ResponseText;
> > /// <summary>
> > /// The web address of the recipient of the transfer.
> > /// </summary>
> > public string URL
> > {get{return _URL;}set{_URL = value;}}
> > string _URL;
> > /// <summary>
> > /// Allows us to determine the size of the buffer used
> > /// to send a piece of the file at a time out the IO
> > /// stream. Defaults to 1024 * 10.
> > /// </summary>
> > public int BufferSize
> > {get{return _BufferSize;}set{_BufferSize = value;}}
> > int _BufferSize;
> > //---------- END PROPERTIES SECTION ----------
> > /// <summary>
> > /// Used to signal we want the output to go to a
> > /// text file verses being transfered to a URL.
> > /// </summary>
> > /// <param name="path"></param>
> > public void setFilename(string path)
> > {
> > coFileStream = new
> > System.IO.FileStream(path,FileMode.Create,FileAccess.Write);
> > }
> > /// <summary>
> > /// Allows you to add some additional field data to be
> > /// sent along with the transfer. This is usually used
> > /// for things like userid and password to validate the
> > /// transfer.
> > /// </summary>
> > /// <param name="key">The form field name</param>
> > /// <param name="str">The form field value</param>
> >
> > public void
> setFields(System.Collections.Specialized.NameValueCollection
> > nv)
> > {
> > coFormFields = nv;
> > }
> > public void setField(string key, string str)
> > {
> > coFormFields[key] = str;
> > }
> > /// <summary>
> > /// Determines if we have a file stream set, and returns either
> > /// the HttpWebRequest stream of the file.
> > /// </summary>
> > /// <returns></returns>
> > public virtual System.IO.Stream getStream()
> > {
> > System.IO.Stream io;
> > if( null == coFileStream )
> > io = coRequest.GetRequestStream();
> > else
> > io = coFileStream;
> > return io;
> > }
> >
> > public virtual void getResponse()
> > {
> > if( null == coFileStream )
> > {
> > System.IO.Stream io;
> > WebResponse oResponse;
> > try
> > {
> > oResponse = coRequest.GetResponse();
> > }
> > catch(WebException web )
> > {
> > oResponse = web.Response;
> > }
> > if( null != oResponse )
> > {
> > io = oResponse.GetResponseStream();
> > StreamReader sr = new StreamReader(io);
> > string str;
> > ResponseText.Length = 0;
> > while( (str = sr.ReadLine()) != null )
> > ResponseText.Append(str);
> > oResponse.Close();
> > }
> > else
> > throw new Exception("MultipartForm: Error retrieving server
> > response");
> > }
> > }
> > /// <summary>
> > /// Here we actually make the request to the web server and
> > /// retrieve it's response into a text buffer.
> > /// </summary>
> >
> > /// <summary>
> > /// Transmits a file to the web server stated in the
> > /// URL property. You may call this several times and it
> > /// will use the values previously set for fields and URL.
> > /// </summary>
> > /// <param name="aFilename">The full path of file being
> > transfered.</param>
> > public void sendFile(string aFilename, ICredentials NetCreds, string
> > cks)
> > {
> > // The live of this object is only good during
> > // this function. Used mainly to avoid passing
> > // around parameters to other functions.
> >
> > coRequest = (HttpWebRequest) WebRequest.Create(URL);
> > // Set use HTTP 1.0 or 1.1.
> > coRequest.ProtocolVersion = System.Net.HttpVersion.Version10;
> > coRequest.Credentials = NetCreds;
> > coRequest.Method = "POST";
> > coRequest.ContentType = "multipart/form-data; boundary=" +
> > BeginBoundary;
> > coRequest.Headers.Add("Cache-Control","no-cache");
> > coRequest.KeepAlive = true;
> > coRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg,
> image/pjpeg,
> > application/x-shockwave-flash, application/vnd.ms-excel,
> > application/vnd.ms-powerpoint, application/msword, */*";
> > // coRequest.Referer = "
http://localhost/custom/quotemgmt/test.aspx";
> > coRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT
> 5.1;
> > .NET CLR 1.1.4322)";
> > coRequest.Headers.Add("Accept-Encoding","gzip, deflate");
> > coRequest.Headers.Add("Accept-Language","en-au");
> > coRequest.AllowAutoRedirect = false;
> >
> > coRequest.CookieContainer = new CookieContainer();
> >
> > coRequest.Headers.Add("Cookie:" + cks);
> >
> > string strFields = getFormfields();
> > string strFileHdr = getFileheader(aFilename);
> > string strFileTlr = getFiletrailer();
> >
> > FileInfo info = new FileInfo(aFilename);
> > coRequest.ContentLength = strFields.Length +
> > strFileHdr.Length +
> > strFileTlr.Length +
> > info.Length;
> > System.IO.Stream io;
> > io = getStream();
> > writeString(io,strFields);
> > writeString(io,strFileHdr);
> > this.writeFile(io, aFilename);
> > writeString(io,strFileTlr);
> >
> > getResponse();
> > io.Close();
> > // End the life time of this request object.
> > coRequest = null;
> >
> >
> > }
> >
> >
> > /// <summary>
> > /// Mainly used to turn the string into a byte buffer and then
> > /// write it to our IO stream.
> > /// </summary>
> > /// <param name="io">The io stream for output.</param>
> > /// <param name="str">The data to write.</param>
> > public void writeString(System.IO.Stream io, string str)
> > {
> > byte[] PostData = System.Text.Encoding.ASCII.GetBytes(str);
> > io.Write(PostData,0,PostData.Length);
> > }
> > /// <summary>
> > /// Builds the proper format of the multipart data that
> > /// contains the form fields and their respective values.
> > /// </summary>
> > /// <returns>The data to send in the multipart upload.</returns>
> > public string getFormfields()
> > {
> > string str="";
> >
> > int ct = coFormFields.Count - 1;
> > for (int i = 0; i<=ct ; i++)
> > {
> > str += ContentBoundary + "\r\n" +
> > CONTENT_DISP + '"' + coFormFields.Keys[i] + "\"\r\n\r\n" +
> > coFormFields.Get(i) + "\r\n";
> > }
> > return str;
> > }
> > /// <summary>
> > /// Returns the proper content information for the
> > /// file we are sending.
> > /// </summary>
> > /// <remarks>
> > /// Hits Patel reported a bug when used with ActiveFile.
> > /// Added semicolon after sendfile to resolve that issue.
> > /// Tested for compatibility with IIS 5.0 and Java.
> > /// </remarks>
> > /// <param name="aFilename"></param>
> > /// <returns></returns>
> > public string getFileheader(string aFilename)
> > {
> > return ContentBoundary + "\r\n" +
> > CONTENT_DISP +
> > "\"userFile\"; filename=\"" +
> > (aFilename) + "\"\r\n" +
> > "Content-type: " + FileContentType + "\r\n\r\n";
> > }
> > /// <summary>
> > /// Creates the proper ending boundary for the multipart upload.
> > /// </summary>
> > /// <returns>The ending boundary.</returns>
> > public string getFiletrailer()
> > {
> > return ContentBoundary + "\r\n" + CONTENT_DISP + "\"UPL\"" + "\r\n\r\n"
> > + "Submit" +
> > "\r\n" + EndingBoundary + "\r\n";
> > }
> > /// <summary>
> > /// Reads in the file a chunck at a time then sends it to the
> > /// output stream.
> > /// </summary>
> > /// <param name="io">The io stream to write the file to.</param>
> > /// <param name="aFilename">The name of the file to transfer.</param>
> > public void writeFile(System.IO.Stream io, string aFilename)
> > {
> > FileStream readIn = new FileStream(aFilename, FileMode.Open,
> > FileAccess.Read);
> > readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
> > byte[] fileData = new byte[BufferSize];
> > int bytes;
> > while( (bytes = readIn.Read(fileData,0, BufferSize)) > 0 )
> > {
> > // read the file data and send a chunk at a time
> > io.Write(fileData,0,bytes);
> > }
> > readIn.Close();
> > }
> > }
> > }
> >
> >
> >
> > "Paul Galvin" <anonymous@discussions.microsoft.com> wrote in message
> > news:9ed101c4977e$4d117640$a601280a@phx.gbl...
> > > Greetings,
> > >
> > > I would like to write a c# program to upload an attachment
> > > to a note.
> > >
> > > I've read what I can find that describes how to do this
> > > (including messages here on the board).
> > >
> > > My first effort is to use the WebClient object and its
> > > upload method. However, that's not working. I'm getting
> > > a response, 500 "Server error". The webclient is posting
> > > the file directly to the SRF. Can I use the webclient for
> > > this? The key difference between webclient and using a
> > > web browser is that the fields are added to the query
> > > string rather than a "posted" field.
> > >
> > > TIA and regards,
> >
> >
>
>
>