5

我想EscapingFormatProvider在返回它们之前创建一个自动 HTML 转义格式化字符串,除非格式参数以 ! 开头:

string.Format(new EscapingFormatProvider(), "<div>{0}</div>", "<script src='foo'></script>");
// => <div>&lt;script src='foo'&gt;&lt;/script&gt;</div>

string.Format(new EscapingFormatProvider(), "<div>{0:!}</div>", "<script src='foo'></script>");
// => <div><script src='foo'></script></div>

我希望它传递格式参数,而不是 ! 如果有,则使用默认格式化程序。唯一的麻烦是,我不知道如何使用默认格式化程序。我发现的所有示例都没有解决委托给默认格式化程序的问题。

编辑:这就是我想出的:

private class EscapingFormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType) { return this; }

    private string DefaultFormat(string format, object arg)
    {
        return string.Format("{0:" + format + "}", arg);
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        return (format.First() == '!')
            ? HttpUtility.HtmlEncode(DefaultFormat(format.Substring(1), arg))
            : DefaultFormat(format, arg);
    }
}

这有点间接,但我认为它有效。

4

2 回答 2

3

正确的解决方案是重新实现默认格式化程序所做的事情,如下所示:

var formattable = arg as IFormattable;
return formattable == null
    ? arg.ToString()
    : formattable.ToString(format, formatProvider);

ICustomFormatter最重要的是,您的格式提供者应该只在请求的类型时才返回自己。

因此,在您的情况下,您的格式提供程序应如下所示:

class EscapingFormatProvider : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;
        return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        var escape = false;
        if (format.StartsWith("!"))
        {
            escape = true;
            format = format.Substring(1);
        }
        var formattable = arg as IFormattable;
        var formatted = formattable == null
            ? arg.ToString()
            : formattable.ToString(format, formatProvider);
        return escape ? HttpUtility.HtmlEncode(formatted) : formatted;
    }
}
于 2015-12-16T18:35:57.960 回答
1

如果我对您的理解正确,那么使用默认格式提供程序所需要做的就是调用不采用 IFormatProvider 的 string.Format 的重载!或者您是指“默认格式化程序”的其他意思,还是您担心本地化?

于 2012-07-11T17:36:24.087 回答