0

我想向我的 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 回答 1

0

我无法找到让 HttpHandler (.ashx) 机制适用于远程 JavaScript 调用的方法 - 我总是在远程 jQuery 调用中收到“无效的引用者”错误。我并不是说这是不可能的,但我找不到任何关于如何做到这一点的文档 - 无论如何都没有用。

最后,我在Ben Dewey的这篇文章的指导下将代码转换为 WCF 服务- 这非常有帮助 - 确保您仔细应用类和方法属性 - 我没有,并且花了大约一个快乐的时间试图弄清楚出了什么问题!

这是代码:

博客服务.cs

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

博客服务.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();
   }
}

网页配置

<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虽然。

  • 我找不到太多文档

  • 将“工厂”属性添加到 WCF 页面:

    Factory="Ninject.Extensions.Wcf.NinjectWebServiceHostFactory"

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

我希望它有所帮助。

于 2013-02-05T11:30:24.777 回答