ASP.NET MVC 和 WCF
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/217111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET MVC and WCF
提问by Michael Stum
I'm working my way into MVC at the moment, but on my "To learn at some point" list, I also have WCF.
我目前正在努力进入 MVC,但在我的“在某个时候学习”列表中,我也有 WCF。
I just wonder if WCF is something that should/could be used in an MVC Application or not? The Background is that I want a Desktop Application (.NET 3.5, WPF) interact with my MVC Web Site, and I wonder what the best way to transfer data between the two is. Should I just use special Views/have the controllers return JSON or XML (using the ContentResult)?
我只是想知道 WCF 是否应该/可以在 MVC 应用程序中使用?背景是我想要一个桌面应用程序(.NET 3.5,WPF)与我的 MVC 网站交互,我想知道在两者之间传输数据的最佳方式是什么。我应该只使用特殊的视图/让控制器返回 JSON 或 XML(使用 ContentResult)吗?
And maybe even more important, for the other way round, could I just call special controllers? Not sure how Authorization would work in such a context. I can either use Windows Authentication or (if the Site is running forms authentication) have the user store his/her credentials in the application, but I would then essentially create a HTTP Client in my Application. So while MVC => Application seems really easy, Application => MVC does seem to be somewhat tricky and a possible use for WCF?
也许更重要的是,反过来说,我可以调用特殊控制器吗?不确定授权在这种情况下如何工作。我可以使用 Windows 身份验证或(如果站点正在运行表单身份验证)让用户将他/她的凭据存储在应用程序中,但我基本上会在我的应用程序中创建一个 HTTP 客户端。因此,虽然 MVC => Application 看起来很简单,但 Application => MVC 似乎有点棘手并且可能用于 WCF?
I'm not trying to brute-force WCF in this, but I just wonder if there is indeed a good use case for WCF in an MVC application.
我不是想在这方面强行使用 WCF,但我只是想知道在 MVC 应用程序中 WCF 是否确实有很好的用例。
回答by jezell
WCF services might make sense in this situation, but don't create services that align with your UI, create services that align with the business processes. ie. you won't have a service that returns the view data for each page, you will have a service that exposes logical operations. Then, your site can call the same services that the windows client calls, but you don't have to couple the design of the windows client to the design of the web site.
WCF 服务在这种情况下可能有意义,但不要创建与您的 UI 一致的服务,而是创建与业务流程一致的服务。IE。您将没有返回每个页面的视图数据的服务,您将拥有一个公开逻辑操作的服务。然后,您的站点可以调用 Windows 客户端调用的相同服务,但您不必将 Windows 客户端的设计与网站的设计结合起来。
Instead of this:
取而代之的是:
Windows Client -> Services -> Web Site
Windows 客户端 -> 服务 -> 网站
It should be:
它应该是:
Windows Client -> Services
Windows 客户端 -> 服务
Web Site -> Services
网站 -> 服务
回答by jaircazarin-old-account
You could use ADO.NET Data Services to share your data with either JSON (for JavaScript clients) or XML (for desktop applications).
您可以使用 ADO.NET 数据服务与 JSON(对于 JavaScript 客户端)或 XML(对于桌面应用程序)共享数据。
ASP.NET MVC can then take advantage of this by using either of two in the model. As you probably know, ADO.NET Data Services is based on WCF so you were on the right track.
然后 ASP.NET MVC 可以通过在模型中使用两个中的任何一个来利用这一点。您可能知道,ADO.NET 数据服务基于 WCF,因此您走在正确的轨道上。
回答by user139669
I use asp.net mvc as both my html website (default view engine) and my service endpoint. The service endpoint is used by my WPF and Silverlight clients by injecting "content-type=text/xml" into the header of a WebClient request (see ScottGu's poston consuming a service in SL which inspired this approach). I found somewhere on the net, some code that overrides the OnActionExecuted event like this:
我使用 asp.net mvc 作为我的 html 网站(默认视图引擎)和我的服务端点。我的 WPF 和 Silverlight 客户端通过将“content-type=text/xml”注入到 WebClient 请求的标头中来使用服务端点(请参阅 ScottGu关于在 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://stackoverflow.com/questions/427725/
//
// MemoryStream also used for atomicity but not here
// http://stackoverflow.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
};
}
}
}
So, the commented out piece is the code that I found - see the stackoverflow links for where I got it :)
所以,注释掉的部分是我找到的代码 - 请参阅我在哪里得到它的计算器链接:)
I overrode the ToString() method on all of my business objects to return string representing how the business object would like to represent itself as xml. WCF accomplishes this via attributes, but I wanted a cleaner solution that didn't rely on reflection AND I didn't want to have both a website project and a WCF project - the problem with two projects is that it was hard to keep them both in sync with respect to functionality - I would get requests like "why doesn't the service allow me to filter my results like the website does?"
我覆盖了所有业务对象上的 ToString() 方法以返回表示业务对象希望如何将自身表示为 xml 的字符串。WCF 通过属性实现这一点,但我想要一个不依赖反射的更简洁的解决方案,而且我不想同时拥有一个网站项目和一个 WCF 项目——两个项目的问题是很难同时保留它们在功能方面同步 - 我会收到诸如“为什么该服务不允许我像网站那样过滤我的结果?”之类的请求。
I'm very interested in other's feedback on this approach :)
我对其他人对这种方法的反馈很感兴趣:)
Here's an example of a business object:
下面是一个业务对象的例子:
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);
}
}
回答by Pure.Krome
You could use ODatafor your MVC application to handle Xml/Json type stuff. I know other people have suggested roll your own - and this is what I'm currently doing .. via the use of my own custom ActionFilter or custom ViewResult.
您可以为 MVC 应用程序使用OData来处理 Xml/Json 类型的东西。我知道其他人建议你自己动手 - 这就是我目前正在做的事情……通过使用我自己的自定义 ActionFilter 或自定义 ViewResult。
Sample OData code: Scott Hanselman's OData + StackOverflow blog post.
示例 OData 代码:Scott Hanselman 的 OData + StackOverflow 博客文章。

