Me gusta permitir que la aplicación de llamadas decida. He peiced juntos un MultiViewController (gran parte del código que encontré en línea, intentaré actualizar con el crédito cuando lo encuentre) que, en función de la extensión de la acción, devolverá el formato apropiado.por ejemplo:
myapp.com/api/Users/1 - defaults to html based on route
myapp.com/api/Users.html/1 - html
myapp.com/api/Users.json/1 - json
myapp.com/api/Users.xml/1 - xml
myapp.com/api/Users.partial/1 - returns a partial view of action name (see code)
myapp.com/api/Users.clean/1 - partial html without styling, etc...
Mis controladores heredan de MultiViewController y en lugar de "vista de retorno (Modelo);" Simplemente llamo "return FormatView (Model); o FormatView (" ViewName ", Model);". El segundo si necesito aplicar una vista específica al resultado, no la vista implícita.
El MultiViewController tiene este aspecto. Prestar especial atención a FormatView, générale devuelve un resultado de la acción:
public abstract class MultiViewController : Controller
{
private const string FORMAT_KEY = "format";
public enum FileFormat {Html, Json, Xml, Partial, Clean}
protected MultiViewController()
{
RequestedFormat = FileFormat.Html;
}
protected FileFormat RequestedFormat { get; private set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var routeValues = filterContext.RouteData.Values;
if (routeValues.ContainsKey(FORMAT_KEY))
{
var requestedFormat = routeValues[FORMAT_KEY].ToString();
if (isValidFormat(requestedFormat))
{
RequestedFormat = (FileFormat)Enum.Parse(typeof(FileFormat), requestedFormat, true);
}
}
}
private bool isValidFormat(string requestedFormat)
{
return Enum.GetNames(typeof (FileFormat)).Any(format => format.ToLower() == requestedFormat.ToLower());
}
protected ActionResult FormatView(string viewName, object viewModel)
{
switch (RequestedFormat)
{
case FileFormat.Html:
if (viewName != string.Empty)
{
return View(viewName,viewModel);
}
return View(viewModel);
case FileFormat.Json:
return Json(viewModel);
case FileFormat.Xml:
return new XmlResult(viewModel);
case FileFormat.Partial:
//return View(this.ControllerContext.RouteData.Values["action"] + "Partial");
return PartialView(this.ControllerContext.RouteData.Values["action"] + "Partial");
case FileFormat.Clean:
if (viewName != string.Empty)
{
return View(viewName, "~/Views/Shared/Clean.master", viewModel);
}
var v = View(viewModel);
v.MasterName = "~/Views/Shared/Clean.Master";
return v;
default:
throw new FormatException(string.Concat("Cannot server the content in the request format: ", RequestedFormat));
}
}
protected ActionResult FormatView(object viewModel)
{
return FormatView("", viewModel);
}
}
Clean.master es simplemente una página maestra que no contiene ningún tipo de HTML adicional - que toma la vista (para que pueda consolidar las clases parciales) y lo renderiza con html limpio que se puede colocar directamente.
Si quiero json - el controlador construye mi modelo de vista y luego devuelve ese modelo de vista como json, en lugar de enviar a la vista predeterminada - lo mismo con .xml.
Las vistas parciales son un poco interesantes ya que, por convención, todas mis vistas principales se dividen en parciales, por lo que ese parcial en particular se puede solicitar por sí mismo; esto es útil para imitar la funcionalidad de un panel de actualización usando jquery sin toda la basura asociada con el panel de actualización.
Sobre la discusión en los comentarios a las respuestas: - En total, hay muchas maneras disponibles para usted. Usa lo que quieras MVC rocas !!!! – IsmailS