Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

How to refresh CSRF token on login when using cookie authentication without identity in ASP .NET Core Web API

I have an ASP .NET Core 3.1 backend, with angular 9 frontend (based on dotnet angular template, just with updated angular to v9). I use cookie authentication (I know JWT is more suited for SPAs, take this as an experiment) and I also added support for CSRF protection on server side:

services.AddAntiforgery(options =>
{
   options.HeaderName = "X-XSRF-TOKEN"; // angular csrf header name
});

I have server side setup to automatically check CSRF using

options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute())

so GET requests are not checked against CSRF, but POST are.

At the very beginning, the angular app makes a GET request to api/init to get some initial data before bootstrapping. On server-side this action initializes CSRF as follows:

// init action body
var tokens = _antiForgery.GetAndStoreTokens(HttpContext);
Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions
{
   HttpOnly = false
});
// return some inital data DTO

This works as expected - the GET response contains 2 CSRF cookies - first being ASP .NET core default CSRF cookie .AspNetCore.Antiforgery... and second being XSRF-TOKEN that angular will read and put into X-XSRF-TOKEN header for subsequent requests.

If afterwards I do login (POST request containing credentials to api/auth/login) from the angular app, everything works - request is POSTed including X-XSRF-TOKEN header and CSRF validation passes, so if credentials are correct the user is logged in.

Now here is where the problems begin. The ASP .NET server app uses cookie authentication without identity as described here https://learn.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1. In login action also CSRF token needs to be regenerated as with authentication the CSRF token starts including authenticated user identity. Therefore my login action looks like this:

public async Task<IActionResult> Login(CredentialsDto credentials)
{
   // fake user credentials check
   if (credentials.Login != "admin" || credentials.Password != "admin")
   {
      return Unauthorized();
   }

   var claimsIdentity = new ClaimsIdentity(new[]
   {
     new Claim(ClaimTypes.Name, "theAdmin"),
   }, CookieAuthenticationDefaults.AuthenticationScheme);

   var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
   await HttpContext.SignInAsync(claimsPrincipal); 

   // refresh antiforgery token on login (same code as in init action before)
   var tokens = _antiForgery.GetAndStoreTokens(HttpContext);
   Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions 
   {
       HttpOnly = false
   });

   return new JsonResult(new UserDto { Id = 1, Login = "theAdmin" });
}

This however does not work. The response contains the XSRF-TOKEN cookie, but subsequent POST request (in my case its logout = POST to api/auth/logout) fails with 400, despite angular correctly putting this cookie value into X-XSRF-TOKEN header. I believe the reason is that the dafault .AspNetCore.Antiforgery... cookie is not being set in the response for some reason, therefore retains the original value even after login and thus CSRF check fails as the values don't match,

How does one properly refresh the CSRF token is such scenario?

How can handle this conflict with fluent API in ASP.NET Core in my tables?

This is my diagram:

enter image description here

And this is my method to add food and its category. Food is added to the database correctly, but it does not add to foodcategorySelected table

public async Task AddFoodCategoryToFoodList(int foodId, List<int> foodCategoryId)
{
    if (!foodCategoryId.Any()) 
         return;

    foreach (var foodCat in foodCategoryId)
    {
        FoodSelectedCategory foodSelectedCategory = new FoodSelectedCategory()
                             {
                                 FoodId = foodId,
                                 FoodCategoryId = foodCat,
                                 RegisterDate = DateTime.Now,
                             };
        await _foodRepository.AddFoodCategoryToFood(foodSelectedCategory);
        await _foodRepository.SaveChanges();
    }
}

Before that I have a method to get information with food and selected category.

Food is added to the database and when goes to this method, however it takes all Ids (food and food categories) but can not add and have this error:

My main method:

public async Task<CreateFoodResult> CreateFoodByAdmin(CreateFoodViewModel createFoodViewModel) { Food food = new Food()
{
     FoodTitle = createFoodViewModel.FoodTitle.SanitizeText(),
     IsActive = createFoodViewModel.IsActive,
     RegisterDate = DateTime.Now,
     FoodDescription = createFoodViewModel.FoodDescription.SanitizeText(),
     IsDelete = true,
     CreatedUser = createFoodViewModel.CreatedUser,
};

if (createFoodViewModel.FoodAvatar != null)
{
     string imageName = NameGenerator.GenerateUniqCode() +
                        Path.GetExtension(createFoodViewModel.FoodAvatar.FileName);
     createFoodViewModel.FoodAvatar.AddImageToServer(imageName, FilePath.FilePath.FoodAvatarServer, 100,
         100, FilePath.FilePath.FoodAvatarThumbServer);
     food.ImageFood = imageName;
}

await _foodRepository.CreateFoodByAdmin(food);
await _foodRepository.SaveChanges();

if (createFoodViewModel.SelectedFoodCategory != null)
{
     await AddFoodCategoryToFoodList(food.FoodId, createFoodViewModel.SelectedFoodCategory);
     await _foodRepository.SaveChanges();
}

return CreateFoodResult.Success;

I get this error:

SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_FoodSelectedCategories_FoodCategories_FoodCategoryId". The conflict occurred in database "EvSef_db", table "dbo.FoodCategories", column 'FoodCategoryId'.

these are my models: Food: enter image description here

FoodCategory:

enter image description here

FoodCategorySelected

enter image description here

How can handle this conflict with fluent API in ASP.NET Core in my tables?

call instance method that has dependency injections without calling DI Constructor

I have an ASP.NET Core Web API that I made using the repository pattern. When a request comes to my controller, I call one of my services dependency methods, then in that service that was just called, I call another service, which is just my repository layer.

This class in the repository layer MyRepo.cs relies on a DBClient.cs class I created.

Appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Database": {
    "ConnectionString": connection string"
  }
}

Program.cs:

// APPSETTINGS CONFIG
builder.services.Configure<DatabaseConfig>(
    config.GetSection(DatabaseConfig.ConfigSectionName)); //Appsetting `Database` property


builder.services.AddScoped<IMyService, MyService>();
builder.services.AddScoped<IMyRepo, MyRepo>();

MyService.cs:

public class MyService: IMyService
{
    private IMyRepo _myRepo;

    public SurveyFormDataServices(IMyRepo myRepo) 
    {
        _myRepo= myRepo;
    }

    public IEnumerable<MyTypes> GetTypes()
    {
        var types= _myRepo.GetTypes();
        ...
    }
}

MyRepo.cs:

public class MyRepo: IMyRepo
{
    private SqlConnection sqlConnection;

    public IEnumerable<MyType> GetTypes()
    {
        using (sqlConnection = DBContext.GetConnection())
        {   
            // ...
        }
    }
}

DBClient.cs:

public sealed class DBClient
{
     private readonly DatabaseConfig _options;
     private static string connectionString = string.Empty;

     public DBClient(IOptions<DatabaseConfig> options)
     {
         _options = options.Value;
         connectionString = _options.ConnectionString;
     }

     public static SqlConnection GetConnection()
     {
         SqlConnection connection = new SqlConnection(connectionString);
         connection.Open();
         return connection;
     }
}

As you can see in my DBClient.cs class, the constructor has a parameter IOptions from the injected AppSettings. I did the options pattern by also binding it to a class that represent the settings.

What my issue is, in the MyRepo.cs, if I do this:

using (sqlConnection = DBClient.GetConnection())

The connectionString property in my DBClient.cs file will be empty, since I am guessing I did not instantiate with new DBClient(IOptions). I want to avoid this and even if I do it like this, I get an error because I don't know how to pass in IOptions, and I rather not.

How can I call or use the DBClient.GetConnection() function and ensure GetConnection() will have the connectionString value from the appsettings.json?

Table header shifting the right after clicking button

I have a table that works beautifullly but for some reason when I click on my testing button the table headers shift to the right. I tried using `style="position:fixed" and I tried taking out the thead in my table neither one worked. I can't find any other resources with my exact problem. Any help is appreciated.

LangInfo view:

@model OfficerLangVM

<body>
<div class="full-width">
    <h4>Language Information</h4>
    <table style="background-color:lightgray; width:75%" class="table table-boardered table-striped" cellpadding="5">
        <thead>
            <tr>
                <th>Language</th>
                <th>Fluency</th>
                <th>Read</th>
                <th>Write</th>
                <th>Speak</th>
                <th>Understand</th>
                <th>Date Modified</th>
                <th><!--Edit--></th>
                <th><!--Delete--></th>
            </tr>
        </thead>
        <tbody>
            <input type="hidden" asp-for="OfficerKey" />
            <input type="hidden" asp-for="AgGuid" />
            <input type="hidden" asp-for="LanguageKey"/>
            @{
                if (Model.Languages != null)
                {
                    int rownum = 0;
                    foreach (Language lang in Model.Languages)
                    {
                            <tr id="@rownum">
                                <td>@lang.LanguageName</td>
                                <td>@lang.Fluency</td>
                                @if (lang.CanRead == true)
                                {
                                    <td><input type="checkbox" checked="checked" /></td>
                                }
                                else
                                {
                                    <td><input type="checkbox" /></td>
                                }
                                @if (lang.CanWrite == true)
                                {
                                    <td><input type="checkbox" checked="checked" /></td>
                                }
                                else
                                {
                                    <td><input type="checkbox" /></td>
                                }
                                @if (lang.CanSpeak == true)
                                {
                                    <td><input type="checkbox" checked="checked" /></td>
                                }
                                else
                                {
                                    <td><input type="checkbox" /></td>
                                }
                                @if (lang.CanUnderstand == true)
                                {
                                    <td><input type="checkbox" checked="checked" /></td>
                                }
                                else
                                {
                                    <td><input type="checkbox" /></td>
                                }
                                    <td>@lang.DateUpdated</td>
                                    <td>
                                        <!--Testing to keep user on same view page, doesn't pull an info-->
                                        <input type="button" value="testing" onclick="show(@lang.LanguageKey); hide(@rownum)"/> 
                                    </td>
                                    <td>
                                        <!--This works just takes user to new view page-->
                                        <a asp-action="LanguageUpdate" asp-route-id="@lang.LanguageKey">Edit</a>
                                    </td>
                                    <td>
                                        <a asp-action="DeleteLang" asp-route-id="@lang.LanguageKey">Delete</a>
                                    </td>
                            </tr>
                            <tr style="display:none" id="@lang.LanguageKey">
                                @await Html.PartialAsync("LanguageUpdate", lang)
                            </tr>
                        rownum++;
                    }
                }
        }
        </tbody>
    </table>
</div>

<script type="text/javascript">
    function show(key) {
        document.getElementById(key).style.display = "block";
    }

    function hide(rownum) {
        document.getElementById(rownum).style.display = "none";
    }
</script>

<style>

    .body-container {
        /*remove the container default padding attribute*/
        /*padding-left: 0px !important;
                padding-right: 0px !important;*/
        /*increase width as per your need*/
        max-width: 100%;
    }
</style>

LanguageUpdate view that is called from testing button:

@model Language

<form asp-action="UpdateLang" method="post">
<input type="hidden" asp-for="OfficerKey" />
<input type="hidden" asp-for="AgGuid" />
<input type="hidden" asp-for="LanguageKey" />
@{
    if (Model != null)
    {
        <td>
            <select asp-for="LanguageName">
                <option Value=""> 1) Select a Language . . .</option>
                <option value="American Sign English (ASE)">American Sign English (ASE)</option>
                <option value="American Sign Language (ASL)">American Sign Language (ASL)</option>
                <option value="Arabic: Algerian">Arabic: Algerian</option>
                <option value="Arabic: Egyptian">Arabic: Egyptian</option>
                <option value="Awadhi">Awadhi</option>
                <option value="Azerbaijani">Azerbaijani</option>
                <option value="Bengali">Bengali</option>
                <option value="Bhojpuri">Bhojpuri</option>
                <option value="Chinese: Cantonese">Chinese: Cantonese</option>
                <option value="Chinese: Fukein">Chinese: Fukein</option>
                <option value="Chinese: Jinyu">Chinese: Jinyu</option>
                <option value="Chinese: Mandarin">Chinese: Mandarin</option>
                <option value="Chinese: Min Nan">Chinese: Min Nan</option>
                <option value="Chinese: Wu">Chinese: Wu</option>
                <option value="Creole">Creole</option>
                <option value="Creole-Jamaican">Creole-Jamaican</option>
                <option value="Czech">Czech</option>
                <option value="Dutch">Dutch</option>
                <option value="Esperanza">Esperanza</option>
                <option value="Estonian">Estonian</option>
                <option value="Farsi">Farsi</option>
                <option value="French">French</option>
                <option value="Gaelic">Gaelic</option>
                <option value="German">German</option>
                <option value="Greek">Greek</option>
                <option value="Hausa">Hausa</option>
                <option value="Hebrew">Hebrew</option>
                <option value="Hindi">Hindi</option>
                <option value="Hmong">Hmong</option>
                <option value="Hungarian">Hungarian</option>
                <option value="Icelandic">Icelandic</option>
                <option value="Italian">Italian</option>
                <option value="Japanese">Japanese</option>
                <option value="Kannada">Kannada</option>
                <option value="Korean">Korean</option>
                <option value="Lao">Lao</option>
                <option value="Latin">Latin</option>
                <option value="Maithili">Maithili</option>
                <option value="Marathi">Marathi</option>
                <option value="Malayalam">Malayalam</option>
                <option value="Native American: Blackfoot">Native American: Blackfoot</option>
                <option value="Native American: Cheyenne">Native American: Cheyenne</option>
                <option value="Native American: Chippewa">Native American: Chippewa</option>
                <option value="Native American: Cree">Native American: Cree</option>
                <option value="Native American: Dakota">Native American: Dakota</option>
                <option value="Native American: Lakota">Native American: Lakota</option>
                <option value="Native American: Lenape">Native American: Lenape</option>
                <option value="Native American: Navajo">Native American: Navajo</option>
                <option value="Native American: Ojibwi">Native American: Ojibwii</option>
                <option value="Native American: Oneida">Native American: Oneida</option>
                <option value="Native American: Onodaga">Native American: Onodaga</option>
                <option value="Native American: Paivte">Native American: Paivte</option>
                <option value="Native American: Shoshoni">Native American: Shoshoni</option>
                <option value="Native American: Sioux">Native American: Sioux</option>
                <option value="Niger-Congo: Akan">Niger-Congo: Akan</option>
                <option value="Niger-Congo: Twi">Niger-Congo: Twi</option>
                <option value="Norwegian">Norwegian</option>
                <option value="Oriya">Oriya</option>
                <option value="Panjabi">Panjabi</option>
                <option value="Patois">Patois</option>
                <option value="Polish">Polish</option>
                <option value="Portuguese">Portuguese</option>
                <option value="Romanian">Romanian</option>
                <option value="Russian">Russian</option>
                <option value="Serbian">Serbian</option>
                <option value="Serbo-croatian">Serbo-croatian</option>
                <option value="Sign Language">Sign Language</option>
                <option value="Sindhi">Sindhi</option>
                <option value="Slovaic(Slovak)">Slovaic(Slovak</option>
                <option value="Spanish">Spanish</option>
                <option value="Sunda">Sunda</option>
                <option value="Swedish">Swedish</option>
                <option value="Tagalog">Tagalog</option>
                <option value="Tamil">Tamil</option>
                <option value="Telugu">Telugu</option>
                <option value="Thai">Thai</option>
                <option value="Turkish">Turkish</option>
                <option value="Ukrainian">Ukrainian</option>
                <option value="Urdu">Urdu</option>
                <option value="Vietnamese">Vietnamese</option>
            </select>
        </td>
        <td>
            <select asp-for="Fluency">
                <option value="1) Limited Proficiency">1. Limited Proficiency</option>
                <option value="2) Novice">2. Novice</option>
                <option value="3) Intermediate">3. Intermediate</option>
                <option value="4) Advanced">4. Advanced</option>
                <option value="5) Native Speaker">5. Native Speaker</option>
            </select>
        </td>
        @if (Model.CanRead == true)
        {
            <td>
                @Html.CheckBoxFor((modelItem => Model.CanRead))
            </td>
        }
        else
        {
            <td>
                @Html.CheckBoxFor((modelItem => Model.CanRead))
            </td>
       }
       @if (Model.CanWrite == true)
       {
            <td>
                @Html.CheckBoxFor((modelItem => Model.CanWrite))
            </td>
       }
       else
       {
           <td>
               @Html.CheckBoxFor((modelItem => Model.CanWrite))
           </td>
       }
       @if (Model.CanSpeak == true)
       {
            <td>
                @Html.CheckBoxFor((modelItem => Model.CanSpeak))
            </td>
       }
       else
       {
            <td>@Html.CheckBoxFor((modelItem => Model.CanSpeak))</td>
       }
       @if (Model.CanUnderstand == true)
       {
            <td>
                @Html.CheckBoxFor((modelItem => Model.CanUnderstand))
            </td>
       }
       else
       {
            <td>@Html.CheckBoxFor((modelItem => Model.CanUnderstand))</td>
       }
       <td>@Model.DateUpdated</td>
       <td>
            <input type="submit" value="Update" class="btn btn-primary" style="background-color:lightgray; color:black" />
       </td>
       <td>
            <input type="submit" value="Delete" class="btn btn-primary" style="background-color:lightgray; color:black" asp-action="DeleteLang" asp-route-id="@Model.LanguageKey" />
       </td>
       <td>
            <input type="submit" class="btn btn-primary" asp-action="Editing" asp-route-id="@Model.OfficerKey" value="Cancel" style="background-color:lightgray; color:black" />
       </td>
    }
}    

Controller:

public IActionResult LanguageUpdate (int id)
{
  Language lang = getLanguage(id);

  return View(lang);
}

[HttpPost]
public IActionResult UpdateLang(Language UpdateLang)
{
  MailkitErrors errors = new(ServiceProvider!, Configuration!);

  UserEmail = HttpContext.Session.GetString("UserEmail")!;

  string ConnectionString = connectionStrings.Get("ForeignLanguageConnectString");

  var objLangUpdateConnect = new SqlConnection(ConnectionString);
  var objLangUdDataSet = new DataSet();
  string strLangUpdate = "UpdateLanguage";
  try
  {
    var objCommandlang = new SqlCommand(strLangUpdate, objLangUpdateConnect);
    objCommandlang.CommandType = CommandType.StoredProcedure;

    //Add parameters for input
    objCommandlang.Parameters.AddWithValue("@RowCount", 1);
    objCommandlang.Parameters.AddWithValue("@OfficerKey", UpdateLang.OfficerKey);
    objCommandlang.Parameters.AddWithValue("@LanguageKey", UpdateLang.LanguageKey);
    objCommandlang.Parameters.AddWithValue("@LanguageName", UpdateLang.LanguageName);
    objCommandlang.Parameters.AddWithValue("@Fluency", UpdateLang.Fluency);
    objCommandlang.Parameters.AddWithValue("@CanRead", UpdateLang.CanRead);
    objCommandlang.Parameters.AddWithValue("@CanWrite", UpdateLang.CanWrite);
    objCommandlang.Parameters.AddWithValue("@CanSpeak", UpdateLang.CanSpeak);
    objCommandlang.Parameters.AddWithValue("@CanUnderstand", UpdateLang.CanUnderstand);
    objCommandlang.Parameters.Add("@UserUpdated", SqlDbType.VarChar, 150).Value = "";

    var ObjDataAdapterLang = new SqlDataAdapter(objCommandlang);
    ObjDataAdapterLang.Fill(objLangUdDataSet, "Language"); //FLIPV2 dbo.Language Table
}
catch (Exception)
{
    ViewBag.ErrorMessage = "There has been an error. MAGLOCLEN HelpDesk has been notified.";
    errors.ErrorEmails(UserEmail, "Error occured while updating language for selected officer:\n");
}

UpdateLang.Officer = getOfficer(UpdateLang.OfficerKey);
UpdateLang.syncOfficer();
return RedirectToAction("Editing", new { id = UpdateLang.OfficerKey });

}

Extra logs from API

Does anyone know how to filter (remove) unnecessary logs from API function calls? They pollute logs) .NET Core. I was trying to confige logging via appsettings.json, but it didn't work. I need to avoid them at all, or better to reduce logs in the Trace/Info/ modes. Im using NLog in Program\StartUp, Microsoft Extension Logging in other..

Trace: sample trace logs

UPDATE

appsettings.json:

  "Logging": {
    "LogLevel": { 
      "Default": "Error",
      "Microsoft": "Error",
      "Microsoft.Hosting.Lifetime": "Error",
      "Microsoft.AspNetCore": "Error" //<----i hoped it will help
    },
    "EventLog": {
      "LogLevel": {
        "Default": "None",
        "Microsoft": "None",
        "Microsoft.Hosting.Lifetime": "None"
      }
    }
  },

nlog.config:

  <rules>
    <logger name="*" minLevel="Info" writeTo="file, kafka, console" />
    <logger name="Microsoft.AspNetCore*" minLevel="None" final="true" />
  </rules>
</nlog>

Program:

public static void Main(string[] args)
{
    var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ProjectConstants.FOLDER_CONFIGS);
    var logger = NLogBuilder.ConfigureNLog(Path.Combine(path, "nlog.config")).GetCurrentClassLogger();
    logger.Info("init main");
    var builder = new ConfigurationBuilder()
        .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
        .AddJsonFile(Path.Combine(path, "appsettings.json"), true);
    Configuration = builder.Build();
    CreateHostBuilder(args).Build().Run();
}
    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
          .ConfigureWebHostDefaults(webBuilder =>
          {
              webBuilder.UseKestrel()
                  .UseConfiguration(Configuration)
                  .UseStaticWebAssets()
                  .UseStartup<Startup>()
                  /*
                  .ConfigureLogging(logging =>
                  {
                      logging.ClearProviders();
                      logging.SetMinimumLevel(LogLevel.Trace);
                  })
                  */
                  .UseNLog();
          }).UseWindowsService().UseSystemd();
}

logs for API creates automatically.

enter image description here

<logger name="Microsoft.AspNetCore" minLevel="None"* - does not effecr on anything(.

'UserControl' is a namespace but is used like a type

this is the code for my CardDay.xaml where i designed the card view for my weather app using WPF framework in which i'm very new and learning

<UserControl x:Class="WeatherApp.UserControl.CardDay"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Name="cardDay">
    <Border CornerRadius="10" Width="85" Padding="10" Margin="0 0 10 0" BorderThickness="1">
        <Border.Style>
            <Style TargetType="Border">
                <Setter Property="Background" Value="White"/>
                <Setter Property="BorderBrush" Value="#e9e9e9e9"/>

                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" Value="#03a9f4"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <StackPanel>
            <TextBlock Text="{Binding Path=Day, ElementName=cardDay}" TextAlignment="Center" FontSize="14" FontWeight="SemiBold"/>
            <Image Source="{Binding Path=Source, ElementName=cardDay}" Width="30" Margin="0 10 0 10"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <TextBlock Text="{Binding Path=MaxNum, ElementName=cardDay}" TextAlignment="Center" FontWeight="SemiBold" Margin="0 0 8 0"/>
                <TextBlock Text="{Binding Path=MinNum, ElementName=cardDay}" TextAlignment="Center" FontWeight="SemiBold" Background="#7a7a7a"/>
            </StackPanel>
        </StackPanel>
    </Border>
</UserControl>

and here is the code for CardDay.xaml.cs which i guess work as backend code for my weather app. really don't know much about C# and i'm learning and this is my first time using this language for a project.


using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WeatherApp.UserControl
{

    public partial class CardDay : UserControl
    {
        public CardDay()
        {
            InitializeComponent();
        }


        public string Day
        {
            get { return (string)GetValue(DayProperty); }
            set { SetValue(DayProperty, value); }
        }
        public static readonly DependencyProperty DayProperty = DependencyProperty.Register("Day", typeof(string), typeof(CardDay));



        public string MaxNum
        {
            get { return (string)GetValue(MaxNumProperty); }
            set { SetValue(MaxNumProperty, value); }
        }
        public static readonly DependencyProperty MaxNumProperty = DependencyProperty.Register("MaxNum", typeof(string), typeof(CardDay));


        public string MinNum
        {
            get { return (string)GetValue(MinNumProperty); }
            set { SetValue(MinNumProperty, value); }
        }
        public static readonly DependencyProperty MinNumProperty = DependencyProperty.Register("MinNum", typeof(string), typeof(CardDay));


        public ImageSource Source
        {
            get { return (ImageSource)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }
        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ImageSource), typeof(CardDay));
    }
}

where you'll be able to see the UserControl is red underlined and not working in any other way.

public partial class CardDay : UserControl
{
    public CardDay()
    {
        InitializeComponent();
    }

CardDay: UserControl is showing used as a type how can i solve it ?? really new at this thing

Tried to use the potential fixes but it didn't work.

Retrieving a List from TempData[] causes it to be null

I am trying to pass a List<int> from 2 methods in ASP.NET Core, using TempData[]. In the Category method, when retrieving the information productID is null, while TempData["Products"] is not null and contains the 2 numbers i added earlier - 1,2.

public IActionResult Homepage()
{
    List<int> productIDs = new List<int> { 1, 2};
    TempData["Products"] = productIDs;
    return View();
}

public IActionResult Category(string categoryName)
{
    List<int> productIDs = TempData["Products"] as List<int>;
    return View();
}

SqlException: The INSERT statement conflicted with the FOREIGN KEY

I created my database in SQL Server with the code first method in ASP.NET Core. My intention is to build a simple news site. I have two tables in one of which I create news groups and it is successful in the other. I have to select that news group from my tables and add descriptions, photos, etc.

When I click on record, I get this error:

SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Pages_PageGroups_PageGroupGroupID". The conflict occurred in database "dbNews", table "dbo.PageGroups", column "GroupID".

I suppose it is for the subject of dependency injection, but I did not try it.

using System.ComponentModel.DataAnnotations;

namespace toplern18.Models
{
    public class Page
    {
        [Key]
        public int PagrID { get; set; }

        [Display(Name = "عنوان گروه")]
        [Required(ErrorMessage = "لطفا{0} را وارد نمایید")]
        public int GroupID { get; set; }

        [Display(Name = "عنوان")]
        [Required(ErrorMessage = "لطفا{0} را وارد نمایید")]
        [MaxLength(250)]
        public string Title { get; set; }

        [Display(Name = "توضیح مختصر")]
        [Required(ErrorMessage = "لطفا{0} را وارد نمایید")]
        [MaxLength(350)]
        [DataType(DataType.MultilineText)]
        public string ShortDescription { get; set; }

        [Display(Name = "متن")]
        [Required(ErrorMessage = "لطفا{0} را وارد نمایید")]
        [MaxLength(400)]
        [DataType(DataType.MultilineText)]
        public string text { get; set; }

        [Display(Name = "بازدید")]
        public int visit { get; set; }

        [Display(Name = "تصویر")]
        public string ImageName { get; set; }

        [Display(Name = "اسلاید")]
        public bool ShowDlider { get; set; }

        [Display(Name = "تاریخ ایجاد")]
        public DateTime CreateDate { get; set; }

        //الان این اون یکه است
        public virtual PageGroup PageGroup { get; set; }

        public virtual List<PageComment> PageComment { get; set; }

        public Page()
        {
        }
    }
}

-------------

using System.ComponentModel.DataAnnotations;

namespace toplern18.Models
{
    public class PageGroup
    {
        [Key]
        public int GroupID { get; set; }

        [Display(Name = "عنوان گروه")]
        [Required(ErrorMessage = "لطفا{0} را وارد نمایید")]
        [MaxLength(150)]
        public string GroupTitle { get; set; }


        //رابطش با پیج یک به چند است  الان لیست اون چنده است
         public virtual List<Page> Page { get; set; } //برقراری رابطه

        public PageGroup()
        {
            //سازنده خالی
        }
    }
}

Read Asp.Net Core Response body in ActionFilterAttribute

I'm using ASP.NET Core as a REST API Service. I need access to request and response in ActionFilter. Actually, I found the request in OnActionExcecuted but I can't read the response result.

I'm trying to return value as follow:

[HttpGet]
[ProducesResponseType(typeof(ResponseType), (int)HttpStatusCode.OK)]
[Route("[action]")]
public async Task<IActionResult> Get(CancellationToken cancellationToken)
{
    var model = await _responseServices.Get(cancellationToken);
    return Ok(model);
}

And in ActionFilter OnExcecuted method as follow:

_request = context.HttpContext.Request.ReadAsString().Result;
_response = context.HttpContext.Response.ReadAsString().Result; //?

I'm trying to get the response in ReadAsString as an Extension method as follow:

public static async Task<string> ReadAsString(this HttpResponse response)
{
     var initialBody = response.Body;
     var buffer = new byte[Convert.ToInt32(response.ContentLength)];
     await response.Body.ReadAsync(buffer, 0, buffer.Length);
     var body = Encoding.UTF8.GetString(buffer);
     response.Body = initialBody;
     return body;
 }

But, there is no result!

How I can get the response in OnActionExcecuted?

How to get current model in action filter

I have a generic action filter, and I want to get current model in the OnActionExecuting method. My current implementation is like below:

public class CommandFilter<T> : IActionFilter where T : class, new()
{
    public void OnActionExecuting(ActionExecutingContext actionContext)
    {
        var model= (T)actionContext.ActionArguments["model"];
    }
}

It works well if my all model names are same. But i want to use differnet model names.

How to solve this problem?

public class HomeController : Controller
{
    [ServiceFilter(typeof(CommandActionFilter<CreateInput>))]
    public IActionResult Create([FromBody]CreateInput model)
    {
        return new OkResult();
    }
}

ASP.NET Core 8 MVC web app : scaffolding not working as expected

I'm migrating a project from ASP.NET Core 3.1 to ASP.NET Core 8.0. I created a new project (targeting .NET 8) and copied the folders, classes, model, controller and view files into the new project folder.

When compiling the new project, I get errors on all views. An example of one of the errors is:

The type or namespace name 'Models' does not exist in the namespace 'Samadhi.Pages.Samadhi' (are you missing an assembly reference?).

D:\PROJECTS_VS\MyWebsite_2024\Samadhi\Microsoft.CodeAnalysis.Razor.Compiler.SourceGenerators\Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator\Views_Rbk_VideoFiles_cshtml.g.cs

I tried basic things like Clean, Build, Rebuilds, etc. but that did nothing.

https://www.reddit.com/r/dotnet/comments/14zd7zp/brand_new_default_aspnet_core_mvc_8_project/

I tried the steps shown in the link above - a post that sounded like a similar issue - however, this had no effect.

The steps in the above post were:

  1. Install the Nuget Package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
  2. In Program.cs append builder.Services.AddControllersWithViews() with .AddRazorRuntimeCompilation()

Can anyone shed some light on what is causing this problem?

Project file

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="Samadhi\" />
    <Folder Include="Views\Shared\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="DeviceDetector.NET" Version="6.3.3" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
    <PackageReference Include="QRCoder" Version="1.4.3" />
    <PackageReference Include="Stripe.net" Version="43.22.0" />
  </ItemGroup>

</Project>

Project explorer

enter image description here

Error list

enter image description here

React Preamble error when trying to serve files through Vite dev server to ASP.NET Project

I'm trying to set up an ASP.NET MVC application with a ClientApp that uses React with Vite as the bundler. This is meant to be an MPA instead of a SPA, so there will be a separate .tsx file for each page of my application (i.e. home.tsx, about.tsx, etc.)

During development, the ClientApp files should be served by the Vite development server to my ASP.NET app for HMR, while in production the app will use the bundled files within wwwroot/dist.

I've attempted to set up my Program.cs to communicate with the Vite development server using the Vite.AspNetCore package.

Program.cs:

using Vite.AspNetCore.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddViteServices(options =>
{
    options.PackageDirectory = "ClientApp"; // Set the root path to the ClientApp folder
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}
else
{
    app.UseViteDevelopmentServer();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

In order to read from the Vite development server, I've added the following block to my _Layout.cshtml file that will be shared by all my views:

<environment include="Development">
    <script type="module" src="https://localhost:5173/@@vite/client"></script>
    <link rel="stylesheet" href="https://localhost:5173/src/theme/site.css" />
    @if (ViewData["ViteScript"] != null)
    {
        <script defer type="module" src="@($"https://localhost:5173/src/pages/{ViewData["ViteScript"]}/index.tsx")"></script>
    }
</environment>

In other words, I'm trying to read the site.css file from ClientApp/src/theme/site.css, and the index.tsx file that's associated with the particular page I'm on, like ClientApp/src/pages/home/index.tsx. The name of the page (like "home") is stored in the ViewData["ViteScript"] at the top of the Razer view.

So I run my Vite development server on port 5173 and then I run my ASP.NET app, but I'm met with the generic message:

"Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong."

For reference, here is my vite.config.ts file:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import mkcert from "vite-plugin-mkcert";
import appsettings from "../appsettings.json";
import appsettingsDev from "../appsettings.Development.json";

const cssPattern = /\.css$/;
const imagePattern = /\.(png|jpe?g|gif|svg|webp|avif)$/;

export default defineConfig({
  plugins: [react(), mkcert()],
  build: {
    manifest: appsettings.Vite.Manifest,
    outDir: "../wwwroot/dist",
    emptyOutDir: true,
    rollupOptions: {
      input: {
        home: "./src/pages/home/index.tsx",
        site: "./src/site.ts",
        styles: "./src/theme/site.css",
      },
      output: {
        entryFileNames: "js/[name].js",
        chunkFileNames: "js/[name]-chunk.js",
        assetFileNames: (info) => {
          if (info.name) {
            if (cssPattern.test(info.name)) {
              return "css/[name][extname]";
            }
            if (imagePattern.test(info.name)) {
              return "images/[name][extname]";
            }

            return "assets/[name][extname]";
          } else {
            return "[name][extname]";
          }
        },
      },
    },
  },
  server: {
    port: appsettingsDev.Vite.Server.Port,
    strictPort: true,
    hmr: {
      host: "localhost",
      clientPort: appsettingsDev.Vite.Server.Port,
    },
  },
});

When I check the Sources tab of the Chrome Developer Tools, I see the ASP.NET app running on localhost:44380 and the Vite dev server running on localhost:5173 (and its files like ExampleComponent.tsx and pages/home/index.tsx.

Sources tab

Here's a screenshot of my ClientApp within the Solution Explorer:

ClientApp folder

If anyone has experienced a similar issue when trying to integrate the Vite development server into an MPA, I'd appreciate your help.

Thanks!

Nuget Package works in console app but not in Web API app

I downloaded a package from Nuget Package. It's not a commonly used package, however the package works in a Console app, but does not work in a Web API app.

The console app and Web API are both running on .NET 5.0.

Can such situations occur? What could be the reason for this? I searched online but couldn't find a reason.

Note: the method in the package works fine in the console app, but when it runs in the Web API, there's no exception or anything; the method works fine and returns a status code of 200, it just returns the output as exactly what I input.

I did some research in the source code of the package I downloaded because it's a bit outdated. The package uses the BinaryFormatter class, and according to my research, this package is no longer supported by Microsoft.

However, I don't think this constitutes a problem because the package works fine in the console app.

How to fix obsolete ILoggerFactory methods?

I upgraded my project to .NET Core 2.2.x and got an obsolete warning regarding the following code - both lines:

public void Configure(IApplicationBuilder app, 
                      IHostingEnvironment env, 
                      ILoggerFactory loggerFactory) 
  {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));

The suggestion to fix is The recommended alternative is AddConsole(this ILoggingBuilder builder). I thought that is what I am using.

What am I missing here?

No service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Areas.Identity.Data.ApplicationUser]' has been registered

Error:

No service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Areas.Identity.Data.ApplicationUser]' has been registered.

I am a student and trying to understand why I am getting this error. I have looked everywhere and cannot find a solution. I am using .Net 8. Thank you.

Program.cs

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

ApplicationUser.cs

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
}

_LoginPartial.cshtml

@using Microsoft.AspNetCore.Identity
@using readiit.Areas.Identity.Data
@using readiit.Models

@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager
❌
❌