AspBucket offers ASP.NET, C#, VB, Jquery, CSS, Ajax, SQL tutorials. It is the best place for programmers to learn

Wednesday 25 May 2016

How to download a file from WCF Service?

In this article I will discuss a How to download a file from WCF Service? WCF does support streaming to export data. Please follow below steps to create a service.
Step 1-  Add new WCF service in your project

Step 2- Web.config Settings
Add following settings in your Web.Config file.
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0"/>
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Service">
        <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="IService"/>
        <!--<endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBindingHTTPS" contract="IMyService"/>-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="WebBehavior">
          <webHttp helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webBinding">
          <security mode="None">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
        <binding name="webBindingHTTPS">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

Step 3-Create new class for generic List Extensions for Data Output to Formatted String, CSV File, and Excel
All necessary comments are attached or code lines are self-explainable. The List extension methods should then be ready to use. 
 public static class ExtensionMetnods
    {
        #region---extension methods---
        public static void ToCSV<T>(this IList<T> list, string path = "", string include = "", string exclude = "")
        {
            CreateCsvFile(list, path, include, exclude);
        }
        private static string CreateCsvFile<T>(IList<T> list, string path, string include, string exclude)
        {
            //Variables for build CSV string
            StringBuilder sb = new StringBuilder();
            List<string> propNames;
            List<string> propValues;
            bool isNameDone = false;

            //Get property collection and set selected property list
            PropertyInfo[] props = typeof(T).GetProperties();
            List<PropertyInfo> propList = GetSelectedProperties(props, include, exclude);

            //Add list name and total count
            string typeName = GetSimpleTypeName(list);
            //sb.AppendLine(string.Format("{0} List - Total Count: {1}", typeName, list.Count.ToString()));
            if (list.Count > 0)
            {
                //Iterate through data list collection
                foreach (var item in list)
                {

                    propNames = new List<string>();
                    propValues = new List<string>();

                    //Iterate through property collection
                    foreach (var prop in propList)
                    {
                        //Construct property name string if not done in sb
                        if (!isNameDone) propNames.Add(prop.Name);

                        //Construct property value string with double quotes for issue of any comma in string type data
                        var val = prop.PropertyType == typeof(string) ? "\"{0}\"" : "{0}";
                        propValues.Add(string.Format(val, prop.GetValue(item, null)));
                    }
                    //Add line for Names
                    string line = string.Empty;
                    if (!isNameDone)
                    {
                        line = string.Join(",", propNames);
                        sb.AppendLine(line);
                        isNameDone = true;
                    }
                    //Add line for the values
                    line = string.Join(",", propValues);
                    sb.Append(line);
                    sb.AppendLine("");
                }
            }
            else
            {
                propNames = new List<string>();

                //Iterate through property collection
                foreach (var prop in propList)
                {
                    //Construct property name string if not done in sb
                    if (!isNameDone) propNames.Add(prop.Name);
                }
                //Add line for Names
                string line = string.Empty;
                line = string.Join(",", propNames);
                sb.AppendLine(line);
                sb.AppendLine("");
            }
            if (!string.IsNullOrEmpty(sb.ToString()) && path != "")
            {
                File.WriteAllText(path, sb.ToString());
            }
            return path;
        }


        private static List<PropertyInfo> GetSelectedProperties(PropertyInfo[] props, string include, string exclude)
        {
            List<PropertyInfo> propList = new List<PropertyInfo>();
            if (include != "") //Do include first
            {
                var includeProps = include.ToLower().Split(',').ToList();
                foreach (var item in props)
                {
                    var propName = includeProps.Where(a => a == item.Name.ToLower()).FirstOrDefault();
                    if (!string.IsNullOrEmpty(propName))
                        propList.Add(item);
                }
            }
            else if (exclude != "") //Then do exclude
            {
                var excludeProps = exclude.ToLower().Split(',');
                foreach (var item in props)
                {
                    var propName = excludeProps.Where(a => a == item.Name.ToLower()).FirstOrDefault();
                    if (string.IsNullOrEmpty(propName))
                        propList.Add(item);
                }
            }
            else //Default
            {
                propList.AddRange(props.ToList());
            }
            return propList;
        }

        private static string GetSimpleTypeName<T>(IList<T> list)
        {
            string typeName = list.GetType().ToString();
            int pos = typeName.IndexOf("[") + 1;
            typeName = typeName.Substring(pos, typeName.LastIndexOf("]") - pos);
            typeName = typeName.Substring(typeName.LastIndexOf(".") + 1);
            return typeName;
        }
        #endregion
    }

Step 4- Add new folder in directory tempfiles

Step 5- Add new method in Service Method
    public Stream GetCSVFile()
    {
        List<UserData> FeedData = GetDataList(); //Write your logic to get custom Data

        if (WebOperationContext.Current == null) throw new Exception("WebOperationContext not set");
        string FilePath = "";
        FilePath = HttpContext.Current.Server.MapPath("~") + "tempfiles";
        if (!Directory.Exists(FilePath))
        {
            Directory.CreateDirectory(FilePath);
        }
        FilePath += "\\UserData_" + DateTime.Now.ToString("ddMMyyyyhhmmss") + ".csv";
        FeedData.Offers.ToCSV<Offer>(path: FilePath);
        var fileName = "UserData_" + DateTime.Now.ToString("ddMMyyyy") + ".csv";
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
        WebOperationContext.Current.OutgoingResponse.Headers.Add("content-disposition", "inline; filename=" + fileName);
        return File.OpenRead(FilePath);
    }

Step 6- Add following code in IService class
 [WebGet]  
 Stream GetCSVFile(string apiKey);
That's it your WCF service is ready to download file. Call your WCF service & CSV file will download.

0 comments :

Post a Comment

  • Popular Posts
  • Comments