Restful WebApi V2 Put Issue - asp.net-web-api2

I cannot understand why my WebApi returns a success (200) when I Post, but doesn't return anything when I Put. Both successfully update the database.
I have attached my code for both methods.
Thanks
Paul
// PUT: api/items/5
[Route("api/items/{id:int}")]
[ResponseType(typeof(void))]
public async Task<IHttpActionResult> PutItem([FromBody] Item[] item, string updateitems)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
foreach (Item i in item)
{
if (updateitems.IndexOf(i.ItemId.ToString()) > 0)
{
db.Entry(i).State = EntityState.Modified;
}
}
await db.SaveChangesAsync();
var iStatus = StatusCode(HttpStatusCode.OK);
return iStatus;
}
// POST: api/items
[Route("api/items")]
[ResponseType(typeof(Item))]
public async Task<IHttpActionResult> PostItem([FromBody] Item[] item)
{
int itemCount = 0;
string edititems = "";
IHttpActionResult iStatus;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
foreach (Item i in item)
{
if (!ItemExists(i.SurveyId, i.LineId))
{
db.Items.Add(i);
}
else
{
var id = FindItemId(i.SurveyId, i.LineId);
edititems = edititems + ',' + id.ToString();
i.ItemId = id;
}
itemCount ++;
}
await db.SaveChangesAsync();
if (edititems.Length > 0)
{
IHttpActionResult result = PutItem(item, edititems).Result;
}
iStatus = StatusCode(HttpStatusCode.OK);
return iStatus;
}

your code looks fine, the only difference that I see is in the ResponseType attribute of the Put, you have: [ResponseType(typeof(void))]
Change to: [ResponseType(typeof(item))]

Related

Azure Redis Cache - add_ServerMaintenanceEvent from StackExchange.Redis ConnectionMultiplexer pool does not have an implementation

I was creating a library in .net core 6 for using with other projects.I am trying to add cache pooling using StackExchange.Redis.MultiplexerPool in that library.
public class Library1 : ILibrary1
{
public Library1(IConfiguration configuration, string azureOptionsKey)
{
configuration.Bind(azureOptionsKey, azureOptions);
//redis client
_redisClient = new LibraryRedisCacheService();
}
}
below is my CacheService
public class LibraryRedisCacheService
{
private readonly IConnectionMultiplexerPool _connectionMultiplexerPool;
private readonly int[] _connectionsErrorCount;
public LibraryRedisCacheService()
{
var configureOptions = ConfigurationOptions.Parse("Cache connection string");
configureOptions.AllowAdmin = true;
configureOptions.AsyncTimeout = 10000;
_connectionMultiplexerPool = ConnectionMultiplexerPoolFactory.Create(
poolSize: 10,
configurationOptions: configureOptions,
connectionSelectionStrategy: ConnectionSelectionStrategy.RoundRobin);
_connectionsErrorCount = new int[_connectionMultiplexerPool.PoolSize];
}
public async Task<TResult> QueryRedisAsync<TResult>(Func<IDatabase, Task<TResult>> op)
{
var connection = await _connectionMultiplexerPool.GetAsync();
try
{
return await op(connection.Connection.GetDatabase());
}
catch (RedisConnectionException)
{
_connectionsErrorCount[connection.ConnectionIndex]++;
if (_connectionsErrorCount[connection.ConnectionIndex] < 3)
{
throw;
}
await connection.ReconnectAsync();
return await op(connection.Connection.GetDatabase());
}
}
public async Task SetCacheAsync<T>(string key, T value, TimeSpan? expiry = null, int retryCount = 0)
{
try
{
await QueryRedisAsync(async db => await db.StringSetAsync(key, JsonConvert.SerializeObject(value), expiry ?? TimeSpan.FromHours(12)));
}
catch (Exception)
{
if (retryCount < 3)
{
await Task.Delay(3000);
await SetCacheAsync(key, value, expiry, retryCount + 1);
}
}
}
public async Task<T?> GetCacheAsync<T>(string key, int retryCount = 0)
{
try
{
var value = await QueryRedisAsync(async db => await db.StringGetAsync(key));
return !value.HasValue ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
catch (Exception)
{
if (retryCount < 3)
{
await Task.Delay(3000);
await GetCacheAsync<T>(key, retryCount + 1);
}
}
return default;
}
public async Task<TResult> RetryCachConnectAsync<TResult>(Func<IConnectionMultiplexer, TResult> op)
{
var connection = await _connectionMultiplexerPool.GetAsync();
try
{
return op(connection.Connection);
}
catch (RedisConnectionException)
{
_connectionsErrorCount[connection.ConnectionIndex]++;
if (_connectionsErrorCount[connection.ConnectionIndex] < 3)
{
throw;
}
await connection.ReconnectAsync();
return op(connection.Connection);
}
}
}
}
and in my project startup i am adding this library like this
services.AddSingleton<ILibrary1, Library1>(
_ => new Library1(Configuration, "KeyvaultReference"));
after that i am getting run time exception in my application like below
Unable to load one or more of the requested types.
Method 'add_ServerMaintenanceEvent' in type 'StackExchange.Redis.MultiplexerPool.Multiplexers.InternalDisposableConnectionMultiplexer' from assembly 'StackExchange.Redis.MultiplexerPool, Version=1.0.2.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
How to add this method implementation, Or I am doing something wrong in the library implementation

When I sign in with SignInAsync in ASP.NET Core Identity, RedirectToLocal is not authenticated

When I sign in with SignInAsync in ASP.NET Core Identity, RedirectToLocal is not authenticated.
If I log in without returning Url or go to allow anonymous action, it works fine, but when I redirect authenticate action return to the login page like the user never signs in. Still, I go to allow anonymous action and see the user sign in everything is okay.
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> LoginWithSms(string userId, string code, string returnUrl)
{
if (userId == null)
{
throw new ArgumentNullException(nameof(userId));
}
if (code == null)
{
throw new ArgumentNullException(nameof(code));
}
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
throw new ApplicationException(string.Format(ErrorConstant.UnableToLoadUser, userId));
}
var result = await _userManager.ConfirmEmailAsync(user, code);
if (!result.Succeeded)
{
return View("AccountError", this.GetErrorVm(AccountConstant.Persian.ConfirmSms, ErrorConstant.Persian.CodeWrong));
}
if (!user.PhoneNumberConfirmed)
{
user.PhoneNumberConfirmed = true;
_context.Users.Update(user);
_context.SaveChanges();
}
await _signInManager.SignInAsync(user, true);
await _setUserActivityLog.SetLogAsync(user.Id, AccountConstant.Persian.LoginToProfile);
return RedirectToLocal(string.IsNullOrEmpty(returnUrl) ? AccountConstant.Routes.ReturnUrlManageIndex : returnUrl);
}
redirect action:
[HttpGet]
[ActionDetail(menuCode: MenuConstant.ManageService.Code, name: "پاسخ دادن به تیکت")]
public async Task<IActionResult> TicketAnswer(long id)
{
var baseTicket = await _context.Tickets.Include(t => t.TicketType).Include(t => t.TicketRecords)
.ThenInclude(tr => tr.Person)
.SingleOrDefaultAsync(t => t.Id == id);
if (baseTicket == null)
{
return NotFound();
}
var vm = new ManageVm<TicketAnwserVm>
{
Entity = new TicketAnwserVm
{
QuickResponses = _context.QuickResponses.OrderBy(qr => qr.Title).Select(qr => new QuickResponseVm
{
Id = qr.Id,
Title = qr.Title
}),
Ticket = new TicketDisplayVm(baseTicket.StartDate)
{
Id = baseTicket.Id,
PersonId = baseTicket.PersonId,
State = baseTicket.State,
Subject = baseTicket.Subject,
TicketTypeName = baseTicket.TicketType.Name,
TicketRecords = baseTicket.TicketRecords.Join(_context.Users, tr => tr.PersonId,
u => u.PersonId,
(tr, u) => new TicketRecordVm(tr.Date)
{
Id = tr.Id,
PersonName = tr.Person.Name,
UserId = u.Id,
Content = tr.Content,
IsOwner = tr.IsOwner,
TicketId = tr.TicketId,
Status = tr.IsOwner ? TicketStatus.Out : TicketStatus.In
})
}
}
};
return View(vm);
}

error CS0103: The name 'ModelHelper' does not exist in the current context

I am trying to implement Object detection on HoloLens2 using Microsoft Custom Vision.
I have been following the tutorial (https://learn.microsoft.com/en-us/archive/blogs/appconsult/23535)
but faced with this error..
error CS0103: The name 'ModelHelper' does not exist in the current context
the codes are as below.
what is this ModelHelper for?
and is there anything that i have to add to use it?
using System;
using System.Linq;
using System.Threading.Tasks;
#if UNITY_WSA && !UNITY_EDITOR
using Windows.Media.Capture;
using Windows.Media.Capture.Frames;
using Windows.Media.MediaProperties;
public class ScanEngine
{
public TimeSpan PredictionFrequency = TimeSpan.FromMilliseconds(400);
private MediaCapture CameraCapture;
private MediaFrameReader CameraFrameReader;
private Int64 FramesCaptured;
IUnityScanScene UnityApp;
public ScanEngine()
{
}
public async Task Inititalize(IUnityScanScene unityApp)
{
UnityApp = unityApp;
await InitializeCameraCapture();
await InitializeCameraFrameReader();
}
private async Task InitializeCameraCapture()
{
CameraCapture = new MediaCapture();
MediaCaptureInitializationSettings settings = new
MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Video;
await CameraCapture.InitializeAsync(settings);
}
private async Task InitializeCameraFrameReader()
{
var frameSourceGroups = await MediaFrameSourceGroup.FindAllAsync();
MediaFrameSourceGroup selectedGroup = null;
MediaFrameSourceInfo colorSourceInfo = null;
foreach (var sourceGroup in frameSourceGroups)
{
foreach (var sourceInfo in sourceGroup.SourceInfos)
{
if (sourceInfo.MediaStreamType == MediaStreamType.VideoPreview
&& sourceInfo.SourceKind == MediaFrameSourceKind.Color)
{
colorSourceInfo = sourceInfo;
break;
}
}
if (colorSourceInfo != null)
{
selectedGroup = sourceGroup;
break;
}
}
var colorFrameSource = CameraCapture.FrameSources[colorSourceInfo.Id];
var preferredFormat = colorFrameSource.SupportedFormats.Where(format =>
{
return format.Subtype == MediaEncodingSubtypes.Argb32;
}).FirstOrDefault();
CameraFrameReader = await CameraCapture.CreateFrameReaderAsync(colorFrameSource);
await CameraFrameReader.StartAsync();
}
public void StartPullCameraFrames()
{
Task.Run(async () =>
{
for (; ; ) // Forever = While the app runs
{
FramesCaptured++;
await Task.Delay(PredictionFrequency);
using (var frameReference = CameraFrameReader.TryAcquireLatestFrame())
using (var videoFrame = frameReference?.VideoMediaFrame?.GetVideoFrame())
{
if (videoFrame == null)
{
continue; //ignoring frame
}
if (videoFrame.Direct3DSurface == null)
{
videoFrame.Dispose();
continue; //ignoring frame
}
try
{
await
ModelHelper.EvaluateVideoFrameAsync(videoFrame).ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
finally
{
}
}
}
});
}
}
#endif

Getting the result of Iactionresult in .net Core using nswagger studio

I have this api as you can see :
[HttpGet("CreateToken")]
public IActionResult CreateToken()
{
string tokenString = string.Empty;
tokenString = BuildJWTToken();
return Ok(new { Token = tokenString });
}
I use nswagger studio to generate my api code as you can see in my MVC core
public System.Threading.Tasks.Task CreateTokenAsync()
{
return CreateTokenAsync(System.Threading.CancellationToken.None);
}
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>Success</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public async System.Threading.Tasks.Task CreateTokenAsync(System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Default1/CreateToken");
var client_ = new System.Net.Http.HttpClient();
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
request_.Method = new System.Net.Http.HttpMethod("GET");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = ((int)response_.StatusCode).ToString();
if (status_ == "200")
{
return;
}
else
if (status_ != "200" && status_ != "204")
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + (int)response_.StatusCode + ").", (int)response_.StatusCode, responseData_, headers_, null);
}
}
finally
{
if (response_ != null)
response_.Dispose();
}
}
}
finally
{
if (client_ != null)
client_.Dispose();
}
}
This code is generated by NswaggerStudio .
So when I want to call my createtoken API as you can see i couldn't get the token in the result:
public async Task<IActionResult> Index()
{
var q = myapi.CreateTokenAsync();
ViewBag.data = q;
return View(q);
}
And the view
<div class="text-center">
<h1 class="display-4">#ViewBag.data</h1>
<p>Learn about building Web apps with ASP.NET Core.</p>
</div>
And here you can see the result
Unfortunately, you cannot return result in this way.
To return any model your returning type in method should look like something like this
[HttpGet("CreateToken")]
public IActionResult<TokenModel> CreateToken()
{
string tokenString = string.Empty;
tokenString = BuildJWTToken();
return Ok(new { Token = tokenString });
}
Check this for more information
There is an alternative solution to this with ProducesResponseType (part of Microsoft.AspNetCore.Mvc).
Setting the typeof to the correct value you wish to return, will let swagger generate the json correctly. Which in turn allows nswag studio to generate
[HttpGet("CreateToken")]
[ProducesResponseType(typeof(Token), StatusCodes.Status200OK)]
public IActionResult CreateToken()
{
string tokenString = string.Empty;
tokenString = BuildJWTToken();
return Ok(new { Token = tokenString });
}

return result from async operation in mvvm

I have a viewModel named CarsList with main property
public ObservableCollection<Car> Cars
{
get
{
if (_cars.Count == 0)
{
IsBusy = true;
_ws.GetCarsCompleted += new EventHandler<GetCarsCompletedEventArgs>(GetCarsCompleted);
_ws.GetCarsAsync(_app.HandlerId);
}
return _cars;
}
set
{
if (_cars != value)
{
if (_cars != null)
{
Unsubscribe(_cars);
}
_cars = value;
if (_cars != null)
{
Subscribe(_cars);
}
RaisePropertyChanged("Cars");
}
}
}
private void GetCarsCompleted(object sender, GetCarsCompletedEventArgs e)
{
//_cars = e.Result;
IsBusy = false;
}
When view gets _cars and the list is empty I must wait to get collection of cars from wcf service, and there is a problem because it is async operation.
Or maybe if list is empty I should return null, and fire async operation, and in asynccompleted set _cars to result from the wcf service?
I can only guess that you are trying to set up a view binding and property change notification. If I am right I would change you code as follows:
public void GetCars(Int32 handlerId)
{
_ws.GetCarsCompleted += new EventHandler<GetCarsCompletedEventArgs>GetCarsCompleted);
IsBusy = true;
_ws.GetCarsAsync(handlerId);
}
public ObservableCollection<Car> Cars
{
get
{
return _cars;
}
set
{
if (_cars != value)
{
_cars = value;
RaisePropertyChanged("Cars");
}
}
private void GetCarsCompleted(object sender, GetCarsCompletedEventArgs e)
{
_ws.GetCarsCompleted -= new EventHandler<GetCarsCompletedEventArgs>GetCarsCompleted);
IsBusy = false;
if (e.Error != null)
{
//Error handler
}
else
{
Cars = e.Result;
}
}
And then the view binding (in the case of a DataGrid) would look something like this..
<DataGrid IsReadOnly="True"
ItemsSource="{Binding Cars}"
.........
........./>