0

I defined a simple view where I request the user to choose a file to upload. This file is stored in a model (model of the view) and is then treated in the POST method. Once the file has been uploaded, I save the new model (result of the file) it into the TempData in order to pass it to the next view to be displayed and later validate the content by the user.

Everything works fine until the redirecttoaction which is not doing anything and I don't know what I'm doing wrong here

Here is an example of what I do:

[HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Index(ImportIndexViewModel model)
        {
            if (!ModelState.IsValid)
                return View(model);

            if (model.File == null)
            {
                ModelState.AddModelError("File", "File is null");
                return View(model);
            }

            var extension = Path.GetExtension(model.FileName);

            if (extension != ".xlsx")
            {
                ModelState.AddModelError("File extension", "File type is not authorized. Please use the correct template file");
                return View(model);
            }

            var uploads = Path.Combine(_webHostEnvironment.WebRootPath, "uploads");

            if (model.File.Length <= 0)
            {
                ModelState.AddModelError("File size", "File length is <= 0");
                return View(model);
            }

            var resultModel = InterclubsApiClient.GetInterclubsReaderModel(model.File, uploads).GetAwaiter().GetResult();
            TempData.Put<InterclubsReaderModel>("InterclubsReaderModel", resultModel);
            return RedirectToAction(nameof(ImportController.Upload), typeof(ImportController).GetControllerName());
        }

        [HttpGet]
        public IActionResult Upload()
        {
            var model = TempData.Get<InterclubsReaderModel>("InterclubsReaderModel");
            if (model == null)
                return BadRequest(ErrorHelper.GetModelStateDictionary("InterclubsReaderModel", "Model is null when retrieved from TempData"));

            return View(model);
        }

Upload is working because I can find the file in the uploads folder. The model is also correct because I can find values into it but why the redirect isn't working ?

Instead, the page stays there and I can't do anything on it. If I use Chrome, it says that the website isn't reachable (like missing the link to IIS).

Thanks for your help.

EDIT: In answer to the question: are you sure this is the correct method name given by nameof(...) Here it is: Proof

SECOND EDIT: Do you guys think something is wrong here ?

public class Startup
    {
        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Environment { get; }

        #region Constructor

        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            Environment = env;
        }

        #endregion

        #region Configure services

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddAuthentication("InterclubsCookieAuth")
                .AddCookie("InterclubsCookieAuth", config =>
                {
                    config.Cookie.Name = "Interclubs.Cookie";
                    config.LoginPath = "/Connect/Login";
                    config.LogoutPath = "/Connect/Logout";
                    config.ExpireTimeSpan = TimeSpan.FromHours(15);
                });

            services.AddAuthorization(config =>
            {
                var defaultAuthBuilder = new AuthorizationPolicyBuilder("InterclubsCookieAuth");
                var defaultAuthPolicy = defaultAuthBuilder
                    .RequireAuthenticatedUser()
                    .Build();

                config.DefaultPolicy = defaultAuthPolicy;
            });

            services.AddHttpContextAccessor();

            services.AddMemoryCache();
            services.AddSession();
            services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false;
            });

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            // Enables .Net Core to refresh updated views in browser while debugging
            var builder = services.AddControllersWithViews();
            builder.AddRazorRuntimeCompilation(options =>
            {
                var libraryPath = Path.GetFullPath(Path.Combine(Environment.ContentRootPath));
                options.FileProviders.Add(new PhysicalFileProvider(libraryPath));
            });
        }

        #endregion

        #region Configuration

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler($"/{typeof(HomeController).GetControllerName()}/{nameof(HomeController.Error)}");
                app.UseHsts(options => options.MaxAge(days: 365).IncludeSubdomains());
            }

            app.UseXContentTypeOptions();
            app.UseXfo(options => options.SameOrigin());
            app.UseXXssProtection(options => options.EnabledWithBlockMode());
            app.UseReferrerPolicy(options => options.NoReferrer());
            app.UseHttpsRedirection();

            var contentTypeProvider = new FileExtensionContentTypeProvider();

            if (!contentTypeProvider.Mappings.ContainsKey(".svg"))
            {
                contentTypeProvider.Mappings.Add(".svg", "image/svg+xml");
            }
            if (!contentTypeProvider.Mappings.ContainsKey(".woff"))
            {
                contentTypeProvider.Mappings.Add(".woff", "application/font-woff");
            }
            if (!contentTypeProvider.Mappings.ContainsKey(".woff2"))
            {
                contentTypeProvider.Mappings.Add(".woff2", "application/font-woff2");
            }

            var staticFilesOptions = new StaticFileOptions
            {
                ContentTypeProvider = contentTypeProvider
            };

            app.UseStaticFiles(staticFilesOptions);
            app.UseSession();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: $"{{controller={typeof(ConnectController).GetControllerName()}}}/{{action={nameof(ConnectController.Login)}}}");
            });
        }

        #endregion
    }
Eagle
  • 421
  • 1
  • 3
  • 9
  • Did you try using `Put` instead `Post` – Eldar Dec 28 '19 at 20:35
  • Is there a reason you're using `return RedirectToAction(nameof(ImportController.Upload), typeof(ImportController).GetControllerName());` when `return RedirectToAction("upload");` yields the same result and is much simpler? – Tieson T. Dec 28 '19 at 20:35
  • I'm using these nameof and GetControllerName methods to ensure if I change a name somewhere I will see everywhere where it is used. I also use this trick into cshtml and in Url links too. I'm used to use it since years and of course this is better when renaming or searching if it is used somewhere instead of string values ;) – Eagle Dec 28 '19 at 21:12
  • PUT gives the same result unfortunately – Eagle Dec 28 '19 at 21:14
  • Are you sure nameof is giving the correct value? Did you verify? – Rajesh G Dec 29 '19 at 03:00
  • I edited my original post to give you the proof it is working correctly. As I've said, I recommend using this way of working to ensure less hardcoded references. – Eagle Dec 29 '19 at 08:35
  • Check this [post](https://stackoverflow.com/questions/41492634/passing-tempdata-with-redirecttoaction/41500275) – Thangadurai Dec 30 '19 at 03:33
  • My TempData is working correctly, but there must be probably an option configure in the startup which changes the fact RedirectToAction is not working anymore. – Eagle Dec 30 '19 at 16:04

1 Answers1

0

I solved it: it comes from the TempData. In .NetCore 3.0 which I'm using, the TempData needs to use Cookies or Session. I enabled the Session and then the redirect was working again without changing anything to my code ! Hope this will help others.

Eagle
  • 421
  • 1
  • 3
  • 9