ASP.NET MVC 和 WCF
Posted
技术标签:
【中文标题】ASP.NET MVC 和 WCF【英文标题】:ASP.NET MVC and WCF 【发布时间】:2010-09-18 01:01:14 【问题描述】:我目前正在努力进入 MVC,但在我的“在某个时候学习”列表中,我也有 WCF。
我只是想知道 WCF 是否应该/可以在 MVC 应用程序中使用?背景是我想要一个桌面应用程序(.NET 3.5,WPF)与我的 MVC 网站交互,我想知道在两者之间传输数据的最佳方式是什么。我应该只使用特殊视图/让控制器返回 JSON 或 XML(使用 ContentResult)吗?
也许更重要的是,反过来,我可以调用特殊控制器吗?不确定授权在这种情况下如何工作。我可以使用 Windows 身份验证,或者(如果站点正在运行表单身份验证)让用户将他/她的凭据存储在应用程序中,但我基本上会在我的应用程序中创建一个 HTTP 客户端。因此,虽然 MVC => Application 看起来真的很简单,但 Application => MVC 似乎有点棘手并且可能用于 WCF?
我并不是想在这方面暴力破解 WCF,但我只是想知道在 MVC 应用程序中是否确实存在 WCF 的良好用例。
【问题讨论】:
【参考方案1】:WCF 服务在这种情况下可能有意义,但不要创建与您的 UI 一致的服务,而是创建与业务流程一致的服务。 IE。您将不会有一个返回每个页面的视图数据的服务,您将有一个公开逻辑操作的服务。然后,您的站点可以调用 windows 客户端调用的相同服务,但您不必将 windows 客户端的设计与网站的设计结合起来。
而不是这个:
Windows 客户端 -> 服务 -> 网站
应该是:
Windows 客户端 -> 服务
网站 -> 服务
【讨论】:
我花了一些时间才真正理解这一点,但这是有道理的。 WCF作为多个客户端的服务宿主,mvc作为将服务调用翻译成s ui的网站。【参考方案2】:您可以使用 ADO.NET 数据服务与 JSON(用于 javascript 客户端)或 XML(用于桌面应用程序)共享您的数据。
ASP.NET MVC 然后可以通过在模型中使用两个中的任何一个来利用这一点。您可能知道,ADO.NET 数据服务基于 WCF,因此您走在了正确的轨道上。
【讨论】:
【参考方案3】:我使用 asp.net mvc 作为我的 html 网站(默认视图引擎)和我的服务端点。我的 WPF 和 Silverlight 客户端通过将“content-type=text/xml”注入到 WebClient 请求的标头中来使用服务端点(请参阅 ScottGu 的 post 关于在 SL 中使用服务,它启发了这种方法)。我在网上的某个地方找到了一些覆盖 OnActionExecuted 事件的代码,如下所示:
public class JsonOrXml : ActionFilterAttribute
private static UTF8Encoding UTF8 = new UTF8Encoding(false);
public override void OnActionExecuted(ActionExecutedContext filterContext)
// setup the request, view and data
HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
ViewResult view = (ViewResult)(filterContext.Result);
var data = view.ViewData.Model;
String contentType = request.ContentType ?? string.Empty;
// JSON
if (contentType.Contains("application/json") || (string)view.ViewData["FORMAT"] == "json")
filterContext.Result = new JsonResult
Data = data
;
// POX
else if (contentType.Contains("text/xml") || (string)view.ViewData["FORMAT"] == "xml")
// MemoryStream to encapsulate as UTF-8 (default UTF-16)
// http://***.com/questions/427725/
//
// MemoryStream also used for atomicity but not here
// http://***.com/questions/486843/
//using (MemoryStream stream = new MemoryStream(500))
//
// using (var xmlWriter =
// XmlTextWriter.Create(stream,
// new XmlWriterSettings()
//
// OmitXmlDeclaration = false,
// Encoding = UTF8,
// Indent = true
// ))
//
// new XmlSerializer(data.GetType()).Serialize(xmlWriter, data);
//
// filterContext.Result = new ContentResult
//
// ContentType = "text/xml",
// Content = UTF8.GetString(stream.ToArray()),
// ContentEncoding = UTF8
// ;
//
XmlDeclaration xmlDecl = new XmlDocument().CreateXmlDeclaration("1.0", "UTF-8", "yes");
filterContext.Result = new ContentResult
ContentType = "text/xml",
Content = xmlDecl.OuterXml + data.ToString(),
ContentEncoding = UTF8
;
所以,注释掉的部分是我找到的代码 - 请参阅 *** 链接了解我从哪里得到它:)
我在所有业务对象上覆盖了 ToString() 方法,以返回表示业务对象希望如何将自身表示为 xml 的字符串。 WCF 通过属性实现了这一点,但我想要一个不依赖反射的更清洁的解决方案,而且我不想同时拥有一个网站项目和一个 WCF 项目——两个项目的问题是很难同时保留它们在功能方面同步 - 我会收到诸如“为什么该服务不允许我像网站那样过滤我的结果?”之类的请求?
我对其他人对此方法的反馈非常感兴趣 :)
这是一个业务对象的示例:
public class ContentFile : Entity
public ContentBook BelongsToBook get; set;
public string FileName get; set;
public XElement FileXml get; set;
public Binary FileData get; set;
public List<ContentFile> Versions get; set;
public List<ContentNode> ContentNodes get; set;
public override string ToString()
return this.ToString(SaveOptions.DisableFormatting);
public string ToString(SaveOptions options)
XElement xml = XElement.Parse("<contentFile id=\"" + Id.ToString() + "" + "\" />");
xml.Add(new XElement("fileName", FileName));
xml.Add(new XElement("fileStructure", FileXml));
xml.Add(base.ToString(options));
return xml.ToString(options);
【讨论】:
【参考方案4】:您可以为您的 MVC 应用程序使用 OData 来处理 Xml/Json 类型的内容。我知道其他人建议你自己动手——这就是我目前正在做的事情……通过使用我自己的自定义 ActionFilter 或自定义 ViewResult。
示例 OData 代码:Scott Hanselman's OData + *** blog post。
【讨论】:
以上是关于ASP.NET MVC 和 WCF的主要内容,如果未能解决你的问题,请参考以下文章