返回NULL时,WCF JSONP返回空白/空文档

时间:2011-11-02 00:12:25

标签: .net wcf null jsonp

我正在使用Microsoft提供的JSONP示例。 http://msdn.microsoft.com/en-us/library/cc716898(v=vs.90).aspx

JSONPEncoderFactory JSONPBindingExtension JSONPBindingElement JSONPBehavior

除非返回null,否则一切正常。 而不是我想要的,这是:callback(null); 它返回一个空白文档,导致大多数JSONP框架出错,如

jQuery.ajax({jsonp:"callback"}); 

我在自定义类中的每个方法调用和完成所有工作的方法调用中设置了断点:

public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)

我最接近找到解决方案仅仅是猜测。我想也许WebServiceHost类可能有一个我可以覆盖的方法来构建我期望的功能,但到目前为止,我已经空手而归。

我还想提一下,由于以下问题,我没有使用WebScriptServiceHostFactory类:

Endpoints using 'UriTemplate' cannot be used with 'System.ServiceModel.Description.WebScriptEnablingBehavior'.

如果我使用这个工厂,返回null会导致我正在寻找的功能。但是,我不能使用TemplateUri,我正在使用它们进行HMAC加密。由于我无法在JSONP请求中使用标头格式为

/Service/Action/publicKey-signature?params

我尝试通过JSONP类型请求找到HMAC标准但找不到任何内容。这是我能想到的最干净的。 Params用作签名。

更新

尝试以下解决方案时我遗漏的内容是你必须确保在web.config上构建一个具有crossDomainScriptAccessEnabled =“true”的webHttpBinding。此外,您必须确保使用该行为。也不要使用WebScriptServiceHostFactory。 您可以使用WebServiceHostFactory,但是您必须在web.config中使用它(或者通过绑定为单个服务执行此操作):

<system.serviceModel>
    <standardEndpoints>
        <webHttpEndpoint>
            <standardEndpoint crossDomainScriptAccessEnabled="true" />
        </webHttpEndpoint>
    </standardEndpoints>
</system.serviceModel>

1 个答案:

答案 0 :(得分:1)

4.0框架具有本机JSONP支持,并且它支持URI模板,如下面的示例所示。您需要在WebHttpBinding类上启用支持(如果您愿意,还需要在配置中启用)。

public class StackOverflow_7974435
{
    [ServiceContract]
    public class Service
    {
        [WebGet(UriTemplate = "/Sum?x={x}&y={y}")]
        public int Add(int x, int y)
        {
            return x + y;
        }
        [WebGet(UriTemplate = "/Data?isNull={isNull}")]
        public string GetData(bool isNull)
        {
            return isNull ? null : "Hello world";
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        WebHttpBinding binding = new WebHttpBinding { CrossDomainScriptAccessEnabled = true };
        WebHttpBehavior behavior = new WebHttpBehavior { DefaultOutgoingResponseFormat = WebMessageFormat.Json };
        host.AddServiceEndpoint(typeof(Service), binding, "").Behaviors.Add(behavior);
        host.Open();
        Console.WriteLine("Host opened");

        WebClient c = new WebClient();
        Console.WriteLine("Not a JSONP call");
        Console.WriteLine(c.DownloadString(baseAddress + "/Sum?x=6&y=8"));

        Console.WriteLine("A JSONP call");
        Console.WriteLine(c.DownloadString(baseAddress + "/Sum?x=6&y=8&callback=MyFunction"));

        Console.WriteLine("A JSONP call returning string");
        Console.WriteLine(c.DownloadString(baseAddress + "/Data?isNull=false&callback=MyFunction"));

        Console.WriteLine("A JSONP call returning null");
        Console.WriteLine(c.DownloadString(baseAddress + "/Data?isNull=true&callback=MyFunction"));

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

更新:还添加了另一个返回null的操作,以及对它的调用。在第一次调用(返回字符串)时,服务返回MyFunction("Hello world");,而在第二种情况下,它正确返回MyFunction(null);。正如我在评论中提到的,如果您不使用ASP.NET AJAX框架,请不要使用WebScriptEnablingBehavior,因为它不适用于其他框架。