T4MVC AsyncController

I recently installed T4MVC using Nuget. I used to have an old version that worked fine, but I had a new requirement that required an asynchronous controller. After creating the asynchronous controller, my project will not compile due to the fact that it will be associated with t4. So I updated using Nuget.

Now the problem is that my controller worked fine until I updated t4mvc. After updating the compilation of the code, but when I call the asynchronous action, it returns after a long time and returns a huge amount of invalid data. Also, critically, if I set breakpoints in my controller, it no longer beats them ?! If I return my DocumentController.generated.cs file to the latest working version, everything will be fine.

Below is my old DocumentController.generated.cs, which works, and a new one, which does not.

Can someone help me figure out what's going on here? I began to rely on T4MVC because it is so good, however I really can not avoid these asynchronous actions.

OLD

// <auto-generated /> // This file was generated by a T4 template. // Don't change it directly as your change would get overwritten. Instead, make changes // to the .tt file (ie the T4 template) and save it to regenerate this file. // Make sure the compiler doesn't complain about missing Xml comments #pragma warning disable 1591 #region T4MVC using System; using System.Diagnostics; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Web; using System.Web.Hosting; using System.Web.Mvc; using System.Web.Mvc.Ajax; using System.Web.Mvc.Html; using System.Web.Routing; using T4MVC; namespace WebUI.Client.Controllers { public partial class DocumentController { [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public DocumentController() { } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] protected DocumentController(Dummy d) { } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] protected RedirectToRouteResult RedirectToAction(ActionResult result) { var callInfo = result.GetT4MVCResult(); return RedirectToRoute(callInfo.RouteValueDictionary); } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public DocumentController Actions { get { return MVC.Document; } } [GeneratedCode("T4MVC", "2.0")] public readonly string Area = ""; [GeneratedCode("T4MVC", "2.0")] public readonly string Name = "Document"; static readonly ActionNamesClass s_actions = new ActionNamesClass(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public ActionNamesClass ActionNames { get { return s_actions; } } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class ActionNamesClass { public readonly string Index = "Index"; } static readonly ViewNames s_views = new ViewNames(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public ViewNames Views { get { return s_views; } } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class ViewNames { public readonly string Index = "~/Views/Document/Index.aspx"; } } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class T4MVC_DocumentController: WebUI.Client.Controllers.DocumentController { public T4MVC_DocumentController() : base(Dummy.Instance) { } public override System.Web.Mvc.ActionResult Index() { var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.Index); return callInfo; } } } #endregion T4MVC #pragma warning restore 1591 

NEW

 // <auto-generated /> // This file was generated by a T4 template. // Don't change it directly as your change would get overwritten. Instead, make changes // to the .tt file (ie the T4 template) and save it to regenerate this file. // Make sure the compiler doesn't complain about missing Xml comments #pragma warning disable 1591 #region T4MVC using System; using System.Diagnostics; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Web; using System.Web.Hosting; using System.Web.Mvc; using System.Web.Mvc.Ajax; using System.Web.Mvc.Html; using System.Web.Routing; using T4MVC; namespace WebUI.Client.Controllers { public partial class DocumentController { [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public DocumentController() { } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] protected DocumentController(Dummy d) { } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] protected RedirectToRouteResult RedirectToAction(ActionResult result) { var callInfo = result.GetT4MVCResult(); return RedirectToRoute(callInfo.RouteValueDictionary); } [NonAction] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public System.Web.Mvc.JsonResult GetDocumentListCompleted() { return new T4MVC_JsonResult(Area, Name, ActionNames.GetDocumentListCompleted); } [NonAction] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public System.Web.Mvc.ActionResult GetDocumentThumbnailCompleted() { return new T4MVC_ActionResult(Area, Name, ActionNames.GetDocumentThumbnailCompleted); } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public DocumentController Actions { get { return MVC.Document; } } [GeneratedCode("T4MVC", "2.0")] public readonly string Area = ""; [GeneratedCode("T4MVC", "2.0")] public readonly string Name = "Document"; static readonly ActionNamesClass s_actions = new ActionNamesClass(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public ActionNamesClass ActionNames { get { return s_actions; } } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class ActionNamesClass { public readonly string Index = "Index"; public readonly string GetDocumentListCompleted = "GetDocumentListCompleted"; public readonly string GetDocumentThumbnailCompleted = "GetDocumentThumbnailCompleted"; } static readonly ViewNames s_views = new ViewNames(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public ViewNames Views { get { return s_views; } } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class ViewNames { public readonly string Index = "~/Views/Document/Index.aspx"; } } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public class T4MVC_DocumentController: WebUI.Client.Controllers.DocumentController { public T4MVC_DocumentController() : base(Dummy.Instance) { } public override System.Web.Mvc.ActionResult Index() { var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.Index); return callInfo; } public override System.Web.Mvc.JsonResult GetDocumentListCompleted(Web.Gateway.DocumentMetaDataCollection clientDocuments) { var callInfo = new T4MVC_JsonResult(Area, Name, ActionNames.GetDocumentListCompleted); callInfo.RouteValueDictionary.Add("clientDocuments", clientDocuments); return callInfo; } public override System.Web.Mvc.ActionResult GetDocumentThumbnailCompleted(System.IO.Stream document, string type) { var callInfo = new T4MVC_ActionResult(Area, Name, ActionNames.GetDocumentThumbnailCompleted); callInfo.RouteValueDictionary.Add("document", document); callInfo.RouteValueDictionary.Add("type", type); return callInfo; } } } #endregion T4MVC #pragma warning restore 1591 

As requested here are stubs of my DocumentController class;

 namespace WebUI.Client.Controllers { [Activated] [ConcurrentSessionDisabled] public partial class DocumentController : AsyncController { public readonly HashSet<string> ImageTypes = new HashSet<string>(new[] { "jpeg", "jpg", "png", "tif", "tiff", "bmp" }); public readonly HashSet<string> IgnoredImageTypes = new HashSet<string>(new[] { "tif", "tiff" }); public virtual ActionResult Index() { return RedirectToAction("List"); } public virtual ActionResult List() { return View(); } public virtual ActionResult Thumbnails(int id) { ViewData["documentId"] = id; return View(); } public void GetDocumentListAsync() { AsyncManager.Timeout = 30000; AsyncManager.OutstandingOperations.Increment(); Task.Factory.StartNew((state) => { Tuple<int, int> clientDetails = (Tuple<int, int>)state; DocumentMetaDataCollection clientDocuments = DocumentHelper.GetClientDocuments(clientDetails.Item1, clientDetails.Item2); AsyncManager.Parameters["clientDocuments"] = clientDocuments; AsyncManager.OutstandingOperations.Decrement(); }, new Tuple<int, int>(Profile.User().ClientId, Profile.User().CrmAccountId)); } public virtual JsonResult GetDocumentListCompleted(DocumentMetaDataCollection clientDocuments) { return Json(from document in clientDocuments.Documents select new { Id = document.Id, Values = document.Values, }, JsonRequestBehavior.AllowGet); } public void GetDocumentFilenamesAsync(int id) { AsyncManager.Timeout = 5000; AsyncManager.OutstandingOperations.Increment(); Task.Factory.StartNew((state) => { int documentId = (int)state; List<string> urls = DocumentHelper.GetUrlsForDocument(documentId); AsyncManager.Parameters["documentId"] = documentId; AsyncManager.Parameters["urls"] = urls; AsyncManager.OutstandingOperations.Decrement(); }, id); } public JsonResult GetDocumentFilenamesCompleted(int documentId, List<string> urls) { IDictionary<int, string> filenameToUrl = new Dictionary<int, string>(); Regex illegalCharacters = new Regex("[^A-Za-z0-9_[-]:]"); int idCounter = 0; foreach(string url in urls) { filenameToUrl.Add(++idCounter, url); } session_HoldDocumentUrls(documentId, filenameToUrl); return Json(from file in filenameToUrl select new { Name = filenameFrom(file.Value), Id = file.Key }); } private string filenameFrom(string url) { return url.Substring(url.LastIndexOf('/') + 1, url.Length - (url.LastIndexOf('/') + 1)); } public void GetThumbnailAsync(int documentId, int imageId) { AsyncManager.Timeout = 5000; AsyncManager.OutstandingOperations.Increment(); string url = session_GetDocumentUrls(documentId).First(f => f.Key == imageId).Value; Task.Factory.StartNew((state) => { string fileUrl = (string)state; thumbnailLoader(fileUrl); }, url); } private void thumbnailLoader(string fileUrl) { Stream document = DocumentHelper.GetDocument(fileUrl); string type = fileUrl.Substring(fileUrl.LastIndexOf('.') + 1, fileUrl.Length - (fileUrl.LastIndexOf('.') + 1)).ToLower(); if (ImageTypes.Contains(type)) { document = ImageHelper.ResizeImage(document, 210); type = "png"; } AsyncManager.Parameters["document"] = document; AsyncManager.Parameters["type"] = type; AsyncManager.OutstandingOperations.Decrement(); } public virtual ActionResult GetThumbnailCompleted(Stream document, string type) { switch (type) { case "png": return new FileStreamResult(document, "image/png"); case "pdf": return File(Links.Content.Images.pdf_256_png, "image/png"); default: return File(Links.Content.Images.document_256_png, "image/png"); } } public void FileAsync(int documentId, int imageId) { if (session_GetDocumentUrls(documentId) == null) { return; } string url = session_GetDocumentUrls(documentId).First(f => f.Key == imageId).Value; AsyncManager.Timeout = 5000; AsyncManager.OutstandingOperations.Increment(); Task.Factory.StartNew((state) => { string fileUrl = (string)state; Stream document = DocumentHelper.GetDocument(fileUrl); string type = fileUrl.Substring(fileUrl.LastIndexOf('.') + 1, fileUrl.Length - (fileUrl.LastIndexOf('.') + 1)).ToLower(); if (ImageTypes.Contains(type) && !IgnoredImageTypes.Contains(type)) { document = ImageHelper.ConvertToPng(document); type = "png"; } AsyncManager.Parameters["document"] = document; AsyncManager.Parameters["type"] = type; AsyncManager.OutstandingOperations.Decrement(); }, url); } public virtual ActionResult FileCompleted(Stream document, string type) { if (document == null || type == null) { return RedirectToAction("List"); } return new FileStreamResult(document, MimeHelper.Lookup("." + type)); } } 

}

UPDATE 7/4/11

Hi David, I apologize for returning to you for so long, I studied some other works.

I managed to track down the problem and hopefully you can shed some light on it and possibly create a fix.

If you look at the second dump of the code above, this is the problem with this problem. The problem is what you created;

 [NonAction] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public System.Web.Mvc.JsonResult GetDocumentListCompleted() { return new T4MVC_JsonResult(Area, Name, ActionNames.GetDocumentListCompleted); } 

I did not think that MVC throws an error, but it was:

2011-04-07 15: 59: 38,921 [41] FATAL MvcApplication [(null)] - an uncaught System.Reflection.AmbiguousMatchException exception occurred: a search for the GetDocumentListCompleted method on the "DocumentController" controller failed because of the ambiguity between the following methods: System. Web.Mvc.JsonResult GetDocumentListCompleted (Web.Gateway.DocumentMetaDataCollection) by type WebUI.Client.Controllers.DocumentController System.Web.Mvc.JsonResult GetDocumentListCompleted () for type WebUI.Client.Controllers.DocuWntrol.Controllers.DocumentController. AsyncActionMethodSelector.GetMethodByName (String methodName)

So, as I understand it, the MVC system has an ambiguous match with my code and the code you created.

If I comment on your code above, everything will work fine again.

Do you now understand the nature or problem? Could it be fixed?

Greetings

Ryan.

+4
source share
1 answer

Update (4/12/2011): ok, I just published a new build of T4MVC (2.6.51), which ignored methods to complete asynchronous testing. This should solve the problem for you!


T4MVC does not support asynchronous operation. That is, you can certainly have asynchronous actions in your controllers, but you cannot reference them using T4MVC

See a previous question on this topic: AsyncController in MVC2 and T4MVC: can they work together?

+3
source

Source: https://habr.com/ru/post/1345078/


All Articles