我有一个 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 来尝试实现这一目标,但并没有走得太远,并且可以就实现这一目标的最佳方式提出一些意见。