Where is my null entry for parameter error coming from? - asp.net-mvc-4

The parameters dictionary contains a null entry for parameter
'restaurantId' of non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult Index(Int32)' in
'OdeToFood.Controllers.ResturantReviewsController'. An optional
parameter must be a reference type, a nullable type, or be declared as
an optional parameter.
The error only occurs when I click the back to list button
I am getting the same error as the patron posting here. I have tried out all of the suggestions on that post but I am able to add some additional points of reference not listed on that question. I noticed that when I hover on the 'back to list' link the url on the bottom of the screen does not contain the restaurantId which got me questioning as to why/how it works on the Pluralsight tutorial anyway.
I have even gone so far as replacing all of my files with those from the provided exercise files and I get the same error.
Here is the code that I believe is causing the error:
[HttpPost]
public ActionResult Edit(RestaurantReview review)
{
if (ModelState.IsValid)
{
_db.Entry(review).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index", new { id = review.RestaurantId });
}
return View(review);
}

For the code that you posted (it helps but not much, should have posted the view's code and the create/edit/reviews actions code) my assumption is below:
What is happening is that you have an action that expected to receive an restaurantId (of type int, that means, not nullable) but it is not receiving any value for restaurantId, causing that exception. Probably, for what you say and looking at the code, it is the Reviews action that expects a restaurantId that it is not being provided. If the Reviews action has an restaurantId as parameter you should create the "Back Link" with that id.
Hope I´ve helped.
Regards,

Related

Parse-server result.attributes vs get()

Been using Parse Server for about a month in our project, and it's been a fantastic addition to our tech stack. However, there is one thing that has slowed down our team a bit ; when using Parse.Query, we can only access the fields of the returned Object by using get('fieldName'), which seems to be very redundant and prone to errors (using strings to get the fields). In Firebase, there is a method to get all the data : .data(). I haven't seen this feature in Parse.
We found out about a property when getting the query result called attributes. It seems to be an object that we can destructure and directly get all the fields of the Parse Object. For example :
const query = Parse.Query('Movie');
const result = await query.first();
const { title, price } = result.attributes
There is only a slight reference to it in the docs : https://parseplatform.org/Parse-SDK-JS/api/master/Parse.Object.html under Members, only with the description Prototype getters/setters.
If this property makes it much more easier/convenient than the get() method, is there any reason it is not include in the get started guide of Parse-SDK-JS? Or am I missing something?
Thanks
As you can see in this line, the get method just access the attributes property and returns the value for the specified key, so you should be fine with const { title, price } = result.attributes.

How to bind optional querystring string parameter on POST

I have the following controller in ASP.NET WebApi 2:
[RoutePrefix("Validations")]
public partial class ValidationsController
{
[HttpPost, Route("Bsb")]
public IHttpActionResult ValidateBsb(string value)
{
var validator = new BankStateBranchValidator(DbContext.BankStateBranches);
var data = new ValidationsResult
{
IsValid = validator.IsValid(value ?? string.Empty)
};
data.Error = data.IsValid
? null
: "The BSB you have entered does not appear to be valid. Please check the value and try again.";
return Ok(data);
}
}
For historical reasons, the value parameter needs to be in the querystring, rather than the form body, which should be empty. So the expected API call would be POST /Validate/Bsb?value=012345.
That all works fine, and I get the expected result; however, sometimes we are getting clients calling the API with POST /Validate/Bsb or POST /Validate/Bsb?value=, and that is resulting in a 400 Bad Request response from WebAPI itself, because, as far as I can tell, the model binder is failing to bind the missing value to the parameter. If I put a breakpoint inside the method, it never gets hit.
So, given that I can't change the API contract, how can I handle this scenario? I've tried adding a [ValueProvider(typeof(RouteDataValueProviderFactory))] attribute to the parameter, and my test case for the missing value works, but then the valid value test cases break since the value isn't in the route but in the querystring.
Update
Based on Craig H's suggestion, I've added a default value to the value parameter. So the various scenarios are:
POST /Validate/Bsb?value=012345 - pass (valid value)
POST /Validate/Bsb?value=000000 - pass (invalid value)
POST /Validate/Bsb?value= - fail (empty value)
POST /Validate/Bsb - pass (missing value)
You should be able to make the parameter optional by specifying a default value in the method signature.
e.g.
[HttpPost, Route("Bsb")]
public IHttpActionResult ValidateBsb(string value = null)
Your question says that a query with ?value= was throwing a bad request.
When I tried this locally my breakpoint was hit and value was null.
If I omitted the QS parameter completely, then I received a method not allowed response.
This page makes mention of optional route parameters with attribute routing, although you are not specifying the parameter like that here.
I cannot find the document which describes the other options with regards to routing and optional parameters. I have seen one which indicates the differences between defining it as optional in the route definition, and optional in the method signature. If I find it, I will update this answer!

Edit Custom Attribute after Log In

I can only Edit a custom field when I before edit it by hand with the user administrator.
What's wrong with my code and what I should do to solve this??
Exactly, I'm trying to assign a value to a User custom attribute when It logs in the portal. And I'm not able to get ExpandoColumn in the conditions specified.
The problem is that ExpandoValue is null.
public class LoginAction extends Action {
public void run(HttpServletRequest req, HttpServletResponse res) {
User currentUser;
try {
currentUser = PortalUtil.getUser(req);
long userId = PrincipalThreadLocal.getUserId();
long companyId = currentUser.getCompanyId();
long groupId = GroupLocalServiceUtil.getGroup(companyId, "Guest").getGroupId();
/* Get de CustomField Segmentation */
ExpandoTable expandoTable = ExpandoTableLocalServiceUtil.getDefaultTable(companyId, User.class.getName());
ExpandoColumn expandoColumn = ExpandoColumnLocalServiceUtil.getColumn(companyId, User.class.getName(), expandoTable.getName(), "Segmentation");
if (expandoColumn != null) {
ExpandoValue expandoValue = ExpandoValueLocalServiceUtil.getValue(expandoTable.getTableId(), expandoColumn.getColumnId(), userId);
if (expandoValue != null) {
expandoValue.setData(finalsegment);
ExpandoValueLocalServiceUtil.updateExpandoValue(expandoValue);
}
}
}
Summary: My problem is that
ExpandoValue expandoValue = ExpandoValueLocalServiceUtil.getValue(expandoTable.getTableId(), expandoColumn.getColumnId(), classPK);
is Null when I access the Value of Custom Attribute. If I edit by hand this customattribute and then execute the same Code it works!!! I don't know why and I dont know how to solve this.
Edit (after your update to the question)
Take a look at the ExpandoValueLocalService javadoc: You'll find that there's a createExpandoValue method. Now guess the relationship between the scenario "You have not manually set the value at all, and you're getting back null as ExpandoValue" vs. "You have set it once and get back a value that you can update...
Another option would also be to just specify a default value for your expando value - this way you'll definitely have a value in there and you can unconditionally update it (at least until it's deliberately deleted - for robustness you should still cater for this possibility)
Original answer:
Where else but in the if condition do you go? Have you tried an else condition or do you get any exception before? E.g. you might need to create the 'default' table before you can just get it.
See this code for an example on how to access Expando Tables/Columns.
I didn't run your code, but of course exceptions might occur earlier as well. Or you might have made a mistake in configuring your LoginAction, so that it doesn't run at all.
By default, regular User role has no permissions to access Expando values.
Anyway, it is better to modify expando values with
User user = UserLocalService.getUserById(userId);
user.getExpandoBridge().setAttribute("attributeName", "attributeValue");
If you want to modify value with any permissions, use
user.getExpandoBridge().setAttribute("attributeName", "attributeValue", false);
Here I found the answer of the question..
You can manage the solution with the code proposed.
http://www.liferay.com/es/community/forums/-/message_boards/message/26154530

The "X" property on "Y" could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'

When I run my application and I click a specific button I get the error:
"The "X" property on "Y" could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'."
Cool so I go to my Entity project, go to Y table, find X column, right-click and go to X's properties and find that Nullable is set to False.
I verify in SQL that in Y table, X is set to allow nulls, and it is.
I then go back to my Entity project, set Nullable to True, save and build and I receive:
Error 3031: Problem in mapping fragments starting at line 4049:Non-nullable column "X" in table "Y" is mapped to a nullable entity property.
I've heard that deleting the table from the .edmx file and then re-adding it is a possibility but have never done that and don't understand the implications enough to feel comfortable in doing that.
I've heard that it could be in the view, could be in the stored procedure...
Also have heard that this is a bug.
Has anyone come across this and found an "across the board" fix or somewhat of a road map of sorts on where to look for this error?
Thanks!
"The "X" property on "Y" could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'."
In your EDMX, if you go under your Y table and click on X column, right-click, click on Properties, scroll down to Nullable and change from False to True.
If you get a "mapping fragment" error, you'll have to delete the table from the EDMX and re-add it, because in the Model Browser it stores the table properties and the only way to refresh that (that I know of) is to delete the table from the Model Browser under <database>.Store then retrieving it using Update Model from Database.. command.
I just replace data type int to int32?
public Int32 Field{ get; set; }
to
public Int32? Field{ get; set; }
and the problem is solved
My problem was that my Model database was out of sync with the actual (dev) database. So the EDMX thought it was smallint but the actual column was int. I updated the model database to int and the EDMX to Int32 and now it works.
For future readers.
I got this error when I had a multiple result stored procedure.
As seen here:
http://msdn.microsoft.com/en-us/data/jj691402.aspx
If you try to access an item in the first-result, after doing a .NextResult, you may get this error.
From the article:
var reader = cmd.ExecuteReader();
// Read Blogs from the first result set
var blogs = ((IObjectContextAdapter)db)
.ObjectContext
.Translate<Blog>(reader, "Blogs", MergeOption.AppendOnly);
foreach (var item in blogs)
{
Console.WriteLine(item.Name);
}
// Move to second result set and read Posts
reader.NextResult();
var posts = ((IObjectContextAdapter)db)
.ObjectContext
.Translate<Post>(reader, "Posts", MergeOption.AppendOnly);
foreach (var item in posts)
{
Console.WriteLine(item.Title);
}
Now, if before the line
foreach (var item in posts)
you put in this code
Blog foundBlog = blogs.FirstOrDefault();
I think you can simulate the error.
Rule of Thumb:
You still gotta treat this thing like a DataReader (fire-hose).
For my needs, I had to convert to a List<>.
So I changed this:
foreach (var item in blogs)
{
Console.WriteLine(item.Name);
}
to this:
List<Blog> blogsList = blogs.ToList();
foreach (var item in blogsList )
{
Console.WriteLine(item.Name);
}
And I was able to navigate the objects without getting the error.
Here is another way I encountered it.
private void DoSomething(ObjectResult<Blog> blogs, ObjectResult<Post> posts)
{
}
And then after this code (in the original sample)
foreach (var item in posts)
{
Console.WriteLine(item.Title);
}
put in this code:
DoSomething(blogs,posts);
If I called that routine and started accessing items/properties in the blogs and posts, I would encounter the issue. I understand why, I should have caught it the first time.
I verified that the entity was pointing at the correct database.
I then deleted the table from the .edmx file and added it again.
Problem solved.
Check your model & database both should be defined accordingly....
public Int32? X { get; set; } ----> Nullable
Accordingly in DB 'X' should be Nullable = True
or
public Int32 X { get; set; } ----> not Nullable
Accordingly in DB 'X' should be Nullable = false
In my case in created view in DB column that I select that contains null value I change that value by this select statement:
Before my change
select
..., GroupUuId , ..
after my change
select
..., ISNULL(GroupUuId, 0), ...
Sorry for my bad English
This may happen when the database table allows NULL and there are records that have a null value and you try to read this record with EF and the mapping class does not allow a null value.
The solution is either change the database table so that it does not allow null or change your class to allow null.
For me the following Steps corrected the Error:
Remove the 'X'-Property from the 'Y'-Table
Save EDMX
build Database from Model
compile
Add the 'X'-Property to 'Y'-Table again (with non-nullable and int16)
Save EDMX
build Database from Model
compile
to fix the error
Error 3031: Problem in mapping fragments starting at line 4049:Non-nullable column "X" in table "Y" is mapped to a nullable entity property.
open your EDMX file with and xml editor and lookup you table in
edmx:StorageModels
find the propertie which gives the error and set or add
Nullable="false" >> to Nullable="true"
save the edmx, open it in visual studio and build it. problem solved
Got same error but different context, tried to join tables using linq where for one of the tables in database, a non-null column had a null value inserted, updated the value to default and the issue is fixed.

RhinoMocks expecting call with the exact value

Sometimes Rhino.Mocks is driving me mad, 'cause there's not enough documentation on topics that, I suppose, are relatively easy.
What I want to do is to expect call to AddContact("test", contact). So for the second parameter I must use parameter constraint Property.AllPropertiesMatch(contact). But what should I use for the first one?
_contactManagerMock
.Expect(m => m.AddContact(null, null))
.Constraints(??????????, Property.AllPropertiesMatch(contact));
What goes instead of "??????????"
I was looking for this as well, here is a more detailed answer.
This is an example of how to use the AllPropertyMatch in Rhino.Mocks. I tested this in Rhino.Mocks 3.6.
//arrange
var contactManagerMock = MockRepository.GenerateMock<IManager>();
contactManagerMock.Expect(m => m.AddContact(
Arg.Is("test"),
Arg<Contact>.Matches(Property.AllPropertiesMatch(contact))))
//Act
//Perform action here that should result in the above expected call
//Assert
contactManagerMock.VerifyAllExpectations();
This says to expect the AddContact method to be called. The first parameter should be a string with the value 'test' the second should be an object of type Contact that has all the same properties as the instance of contact.
Calling VerifyAllExpectations performs the assertion.
More info on the Rhino.Mocks site.