There are three modes for working with MVC in Sitefinity. The difference is that Sitefinity’s MVC support allows multiple controllers on a Sitefinity page versus classic MVC using only one controller. This may cause problems when a controller performs a postback and navigates to an action.
Example
- FirstController has actions Index and IndexPostBack
- SecondController has actions Load and LoadPostBack
Both controllers are placed on a Sitefinity hybrid page, allowing for MVC widgets and WebForms widgets. FirstController performs a postback, which changes the URL to http://site.com/page/IndexPostBack.
SecondController is not rendered on this URL because the action Load is not available for the route http://site.com/page/IndexPostBack.
Solution
To overcome this, I provide a sample of two MVC widgets performing postbacks asynchronously. Refer to the attached sample for the code.
There are two controllers: the first for creating News and the second for creating Events (CreateNewsController and EventsController).
Upon postback, the controllers create Sitefinity Event/News items.
[HttpPost] public ActionResult Create(CreateNewsModel model) { if(ModelState.IsValid) { var manager = NewsManager.GetManager(); var newsItem = manager.CreateNewsItem(); newsItem.Title = model.Title; newsItem.Content = model.Content; newsItem.Author = model.Author; manager.SaveChanges(); Dictionary<string, string> contextBag = new Dictionary<string, string>(); WorkflowManager.MessageWorkflow(newsItem.Id, typeof(NewsItem), manager.Provider.Name, "Publish", true, contextBag); return Content(MvcHelper.RenderPartialViewToString(this, "_NewsCreated", null)); } return Content(MvcHelper.RenderPartialViewToString(this, "Default", model)); }Under normal conditions, the postback redirects to a new route, and in this case, it goes to http://site.com/page/Create. This hides all other widgets since they are unavailable for this route.
The control handles this redirect to another route by performing an async postback. When creating a news/event item, the result of the postback loads two partial views (_NewsCreated.cshtml and _EventCreated.cshtml) through the MvcHelper class.
public class MvcHelper { public static string RenderPartialViewToString(Controller controller, string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = controller.ControllerContext.RouteData.GetRequiredString("action"); controller.ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } } The async postback is performed client-side by the script NewsScript/EventScript.js.
//check if Create ActionResult is called $(document).ready( function () { $("#createNews").click( function(){ var model = NewsObject.collectModel(); NewsObject.sendData(model, "/" + CURRENTPAGE + "/Create", "myNewsForm"); } ); }); //perform async POST sendData: function(newsData, destination, resultHolderId) { $.ajax({ type: 'POST', url: destination, contentType: 'application/json; charset=utf-8', data: JSON.stringify(newsData), success: function (result, args) { $("#"+resultHolderId).html(result) }, error: this._syncFailureDelegate }); } }
Stanislav Velikov
Stanislav Velikov is a Tech Support Engineer at Telerik. He joined the Sitefinity Support team in April 2011.