Receiving a csv text file in XData

I need to receive a csv text file that is being sent via a web app using an HTML Form tag.
Wagner pointed me to the code I needed - pasted below.

Could someone please describe to me how I use this? If I call this from a service, how do I define the service? What params are required and of what type?

Thanks,
Paul

uses {...}, Sparkle.Multipart.FormDataReader;

procedure ProcessRequest(const C: THttpServerContext);
var
  Reader: TMultipartFormDataReader;
  I: integer;
  Part: TMultipartFormDataPart;
  vres: string;
begin
  Reader := TMultipartFormDataReader.Create(C.Request.ContentStream, C.Request.Headers.Get('content-type'));
  try
    vres := '';
    while Reader.Next do
    begin
      Part := Reader.PartInfo;
      vres := vres + 'Name: ' + Part.Name + #13#10;
      if Part.FileName <> '' then
        vres := vres + 'FileName: ' + Part.FileName + #13#10;
      vres := vres + 'MediaType: ' + Part.MediaType + #13#10;
      vres := vres + 'Charset: ' + Part.Charset + #13#10;
      vres := vres + 'Content-Disposition: ' + Part.ContentDisposition + #13#10;

      vres := vres + '=== Params ==='#13#10;

      for I := 0 to Part.ParamCount - 1 do
        vres := vres + Part.ParamName[I] + ': ' + Part.ParamValue[I] + #13#10;

      if (Part.FileName <> '') and (Part.MediaType <> '') then
        TFile.WriteAllBytes(
          (TPath.Combine(ExtractFilePath(ParamStr(0)), TPath.GetFileName(Part.FileName))),
          Reader.ContentAsBytes)
      else
        vres := vres + 'Content: ' + Reader.ContentAsString + #13#10;
      vres := vres + #13#10;
    end;

    C.Response.StatusCode := 200;
    C.Response.ContentType := 'text/plain;charset=UTF-8';
    C.Response.Close(TEncoding.UTF8.GetBytes(vres));
  finally
    Reader.Free;
  end;
end;
1 Like

Hi Paul, just create a regular XData service that receives a TStream parameter.
Then instead of using C.Request.ContentStream you can simply use the parameter name.

Thanks Wagner. What should I do about the other "C" properties and methods that are used in the procedure, such as:

C.Request.Headers.Get
C.Response.StatusCode
C.Response.ContentType
C.Response.Close

And should my XData service call the ProcessRequest procedure, or should the code be integrated directly into the XData service function?

Cheers,
Paul

C.Request.Headers.Get

Keep it.

C.Response.StatusCode

No need, it's set automatically by XData. But in any case, for different status codes, you can use

TXDataOperationContext.Current.Handler.SetStatusCode(200);

C.Response.ContentType

Keep it.

C.Response.Close

No need. You don't need to answer anything, actually, so all vres code can be removed. It's up to you what to return in your XData method.

or should the code be integrated directly into the XData service function?

Directly.

Thanks again Wagner. I've got it working, but just wanted to check I am doing the right thing.

Am I using the correct object and properties for the second parameter in the TMultipartFormDataReader.Create? pPartsFile is the passed TStream.

Cheers,
Paul

    Reader := TMultipartFormDataReader.Create(pPartsFile, TXDataOperationContext.Current.Request.Headers.Get('content-type'));

Yes, it's correct.