1

我有一个 web api,它根据(目前)一些简单的搜索条件向我返回一个用户列表。

 public class UserListAPIController : APIController
{

    public List<UserManagerSearchResult> Get(int siteGroupId)
    {
        return userService.UserManagerSearch(LoggedInUserToken.DefaultSiteID, siteGroupId);
    }
}

这是使用 ajax getJson 请求从客户端 knockoutjs 视图模型调用的,该请求具有基于选择的各种过滤条件动态生成的 url。

  self.LoadUsers = function () {

    var SiteGroupID = self.selectedSiteGroup();
    $.getJSON("/API/UserListAPI/?siteGroupId=" + SiteGroupID
        , function (allData) {
        var mappedUsers = $.map(allData, function (item) {
           //mapping code
            return dbu;

        });
        self.Users(mappedUsers);
    });
};

然后使用敲除模板绑定在网格中很好地显示结果。

我还需要实现“下载到 csv”功能,该功能将返回与为 ui 搜索列表选择的完全相同的结果。

所以我的想法是实现一个自定义的 mediatypeformatter,它允许我执行相同的 web api,但返回一个 csv 响应而不是 json 响应。

我已经在 fiddler 中实现并测试了它,并且按预期工作。所以当我将类型设置为“text/csv”并调用 web api 时,我得到了 csv 结果。

public class UserManagerSearchResultCSVFormatter : BufferedMediaTypeFormatter 
{

    public UserManagerSearchResultCSVFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
    }

    public override bool CanReadType(Type type)
    {
        return false; 
    }

    public override bool CanWriteType(Type type)
    {
        if (type == typeof(UserManagerSearchResult))
        {
            return true;
        }
        else
        {
            Type enumerableType = typeof(List<UserManagerSearchResult>);
            return enumerableType.IsAssignableFrom(type);
        }


    }

    public override void WriteToStream(Type type, object value, Stream writeStream,
                                       System.Net.Http.HttpContent content)
    {
        using (var writer = new StreamWriter(writeStream))
        {
            var results = value as List<UserManagerSearchResult>;
            if (results != null)
            {
                foreach (var result in results)
                {
                    WriteItem(result, writer);
                }
            }
            else
            {
                var result = value as UserManagerSearchResult;
                if (result == null)
                {
                    throw new InvalidOperationException("Cannot serialize type");
                }
                WriteItem(result, writer);
            }
        }
        writeStream.Close();
    }


    // Helper methods for serializing Products to CSV format. 
    private void WriteItem(UserManagerSearchResult result, StreamWriter writer)
    {
        writer.WriteLine("{0},{1},{2}", Escape(result.UserId),
            Escape(result.UserName), Escape(result.Year));
    }

    static char[] _specialChars = new char[] { ',', '\n', '\r', '"' };

    private string Escape(object o)
    {
        if (o == null)
        {
            return "";
        }
        string field = o.ToString();
        if (field.IndexOfAny(_specialChars) != -1)
        {
            return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
        }
        else return field;
    }

}

这就是所有的背景。

我遇到了几个我不知道如何最好地实施的问题。

首先,为了使其工作,我需要能够执行以下操作: 1. 动态构建 url(如上面的 ajax getjson 示例所示) 2. 将请求类型设置为 'text/csv' 3. initite使用请求类型调用 url 并强制下载文件。

这几乎是我被困为实现这一点的最佳方式。我一直在寻找一些 jquery ajax 来尝试实现这一目标,但并没有走得太远,并且可以就实现这一目标的最佳方式提出一些意见。

4

0 回答 0