创建公共JSON源

时间:2013-01-31 11:09:36

标签: json web-services

我想在我的ASP.net(4)Forms网站上添加一个公共(可外部调用的)JSON数据源。为此,我创建了以下Web服务:

[WebService(Namespace = "http://localtest.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class BlogWebService : System.Web.Service.WebService
{
   [WebMethod]
   [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
   public List<Blog> GetLatestBlogs(int noBlogs)
   {
      return GetLatestBlogs(noBlogs)
         .Select(b => b.ToWebServiceModel())
         .ToList();
   }
}

我已通过打开

在本地服务器上对此进行了测试
http://localhost:55671/WebServices/BlogWebService.asmx?op=GetLatestBlogs

并且它可以正常工作。

当我尝试远程访问此服务并获得内部服务器错误时。例如,我使用LinqPad运行以下代码(基于http://geekswithblogs.net/JuanDoNeblo/archive/2007/10/24/json_in_aspnetajax_part2.aspx中的一些脚本):

void Main()
{
   GetLatestBlogs().Dump();
}

private readonly static string BlogServiceUrl =
   "http://localhost:55671/BlogWebService.asmx/GetLatestBlogs?noBlogs={0}";

public static string GetLatestBlogs(int noBlogs = 5)
{
   string formattedUri = String.Format(CultureInfo.InvariantCulture,
      BlogServiceUrl, noBlogs);

   HttpWebRequest webRequest = GetWebRequest(formattedUri);
   HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
   string jsonResponse = string.Empty;
   using (StreamReader sr = new StreamReader(response.GetResponseStream()))
   {
      jsonResponse = sr.ReadToEnd();
   }
   return jsonResponse;
}

private static HttpWebRequest GetWebRequest(string formattedUri)
{
   Uri serviceUri = new Uri(formattedUri, UriKind.Absolute);
   return (HttpWebRequest)System.Net.WebRequest.Create(serviceUri);
}

我有很多问题/怀疑:

  1. 如何格式化对Web服务的调用?我不确定在LinqPad测试代码中构建我的BlogServiceUrl是否正确。
  2. 我的BlogWebService类和GetBlogs()方法是否已正确定义和归属?
  3. 我是否需要在网站配置中添加任何内容才能使其正常工作?
  4. 非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

我无法找到使HttpHandler(.ashx)机制适用于远程JavaScript调用的方法 - 我总是在远程jQuery调用中收到'无效引用者'错误。我不是说这是不可能的,但我找不到任何关于如何做的文件 - 不管怎么说都没有。

最后,我将代码转换为由this Ben Dewey文章引导的WCF服务 - 这非常有用 - 确保您仔细应用类和方法属性 - 我没有并花了一个小时左右的时间试图找出问题所在!

以下是代码:

<强> IBlogService.cs

[ServiceContract]
public interface IBlogService
{
   [OperationContract]
   List<WebServiceModels.Blog> GetLatestBlogs(int noItems);
}

<强> BlogService.svc

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class BlogService 
   : Ninject.Web.WebServiceBase, IBlogService
{

   private readonly IScoRepository ScoDb;       // Data repository


   public BlogService(IScoRepository scoDb)
   {
      this.ScoDb = scoDb;
   }


   [WebGet(ResponseFormat = WebMessageFormat.Json)]
   public List<WebServiceModels.Blog> GetLatestBlogs(int noItems)
   {
      return ScoDb
         .GetLatestBlogs(noItems)
         .Select(b => b.ToWebServiceModel(hostAddress))
         .ToList();
   }
}

<强>的Web.config

<system.serviceModel>
   <serviceHostingEnvironment multipleSiteBindingsEnabled="true"  aspNetCompatibilityEnabled="true" />
   <behaviors>
      <endpointBehaviors>
         <behavior name="webHttpBehavior">
            <webHttp />
         </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
         <behavior name="">
            <serviceMetadata httpGetEnabled="true" />
            <serviceDebug includeExceptionDetailInFaults="false" />
         </behavior>
      </serviceBehaviors>
   </behaviors>
   <bindings>
      <webHttpBinding>
         <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
   </bindings>
   <services>
      <service name="WebServices.JSON.BlogService">
         <endpoint name="WebServices.JSON.IBlogService" address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="WebServices.JSON.IBlogService" behaviorConfiguration="webHttpBehavior" />
      </service>
   </services>
</system.serviceModel>

测试JavaScript

$.ajax({
   type: "GET",
   url: "http://localhost:55671/WebServices/JSON/BlogService.svc/GetLatestBlogs",
   data: {
      noItems: 3
   },
   dataType: "jsonp",
   cache: false,
   success: function(result) {
      alert(result[0].Title + " (" + result.length + " Blogs returned)");
   },
   error: function(jqXHR, textStatus, errorThrown) {
     alert(errorThrown);
   }
});

如您所见,我还使用了Ninject DI。这是有问题的,直到我遇到Ninject.Extension.Wcf模块,这使生活变得非常容易。虽然有几个gotchyas。

  • 我找不到太多文档

  • 将'factory'属性添加到WCF页面:

    厂= “Ninject.Extensions.Wcf.NinjectWebServiceHostFactory”

    • 调整Web.config以引用服务接口,否则不会发生绑定魔法。

我希望它有所帮助。