我有2个布局页面,一个是主布局。这具有基本布局,无论用户是否登录,我的所有页面都将使用该布局。另一个是我所谓的授权布局,它是登录到应用程序的用户的布局视图。授权布局视图在主布局的主体内呈现,并且要求用户登录的所有页面都在授权布局的主体内呈现。
现在我的问题是我如何在子页面布局中使用主布局中的渲染部分,例如主页(对于登录用户),我现在无法正确,因为主布局不是直接主在子视图中,它是授权布局的主控,它是子视图的布局。
这就是.NET CORE中的所有内容
答案 0 :(得分:0)
我认为你不能在布局中进行布局渲染。但另一种可能适合您的方法如下:
创建两个布局,一个用于非授权访问者,另一个用于授权访问者。对于两个相同布局的所有方面,创建视图组件。然后在两个布局上使用这些视图组件。这样所有常见的html和逻辑只在一个地方。
然后,您可以根据访问者是否经过身份验证,选择适用于视图的布局。
我的网站工作采用了非常类似的方法。
答案 1 :(得分:0)
你是否正在寻找这些方面的东西:
#include <tuple>
#include <utility>
#include <type_traits>
#include <cassert>
#include <iostream>
// CODE TO BE TESTED:
class Object
{
public:
Object( double value ) : value( value ) {}
inline const double& getValue() const { return value; }
private:
double value;
};
static const double minA = 0;
static const double maxA = 100;
static const int minB = 10;
static const int maxB = 20;
static const Object minC = Object( 23.0 );
static const Object maxC = Object( 29.0 );
bool func1( double a )
{
std::cout << "Calling func1(" << a << ")" << std::endl;
if ( a < minA )
return false;
else if ( a > maxA )
return false;
// do something
return true;
}
bool func2( int b, const Object& c )
{
std::cout << "Calling func2(" << b << "," << c.getValue() << ")" << std::endl;
if ( b < minB )
return false;
else if ( b > maxB )
return false;
else if ( c.getValue() < minC.getValue() )
return false;
else if ( c.getValue() > maxC.getValue() )
return false;
// do something
return true;
}
// TESTING CODE:
// integer_sequence implementation
template <class T, T... Vs>
struct integer_sequence { };
template <class T, class, class, class = integer_sequence<T>, class = integer_sequence<T, 0>, class = void>
struct make_integer_sequence_impl;
template <class T, T ICV1, T... Res, T... Pow>
struct make_integer_sequence_impl<T, std::integral_constant<T, ICV1>, std::integral_constant<T, 0>, integer_sequence<T, Res...>, integer_sequence<T, Pow...>, typename std::enable_if<(ICV1 > 0)>::type>: make_integer_sequence_impl<T, std::integral_constant<T, ICV1/2>, std::integral_constant<T, ICV1%2>, integer_sequence<T, Res...>, integer_sequence<T, Pow..., (Pow + sizeof...(Pow))...>> { };
template <class T, T ICV1, T... Res, T... Pow>
struct make_integer_sequence_impl<T, std::integral_constant<T, ICV1>, std::integral_constant<T, 1>, integer_sequence<T, Res...>, integer_sequence<T, Pow...>, void>: make_integer_sequence_impl<T, std::integral_constant<T, ICV1/2>, std::integral_constant<T, ICV1%2>, integer_sequence<T, Pow..., (Res + sizeof...(Pow))...>, integer_sequence<T, Pow..., (Pow + sizeof...(Pow))...>> { };
template <class T, class Res, class Pow>
struct make_integer_sequence_impl<T, std::integral_constant<T, 0>, std::integral_constant<T, 0>, Res, Pow, void> {
using type = Res;
};
template <class T, T V>
using make_integer_sequence = typename make_integer_sequence_impl<T, std::integral_constant<T, V/2>, std::integral_constant<T, V%2>>::type;
template <size_t V>
using make_index_sequence = make_integer_sequence<size_t, V>;
template <size_t... V>
using index_sequence = integer_sequence<size_t, V...>;
// end of integer_sequence implementation
// helper functions to generate valid/invalid inputs:
// TODO: possibly return values randomly offseted?
double getValidValue( const std::pair<double,double>& minmax ) { return minmax.first + (minmax.second-minmax.first)/2; }
int getValidValue( const std::pair<int,int>& minmax ) { return minmax.first + (minmax.second-minmax.first)/2; }
Object getValidValue( const std::pair<Object,Object>& minmax ) { return Object( minmax.first.getValue() + (minmax.second.getValue()-minmax.first.getValue())/2); }
double getInvalidLowerValue( const std::pair<double,double>& minmax ) { return minmax.first - 1; }
int getInvalidLowerValue( const std::pair<int,int>& minmax ) { return minmax.first - 1; }
Object getInvalidLowerValue( const std::pair<Object,Object>& minmax ) { return Object( minmax.first.getValue() - 1); }
double getInvalidUpperValue( const std::pair<double,double>& minmax ) { return minmax.second + 1; }
int getInvalidUpperValue( const std::pair<int,int>& minmax ) { return minmax.second + 1; }
Object getInvalidUpperValue( const std::pair<Object,Object>& minmax ) { return Object( minmax.second.getValue() + 1); }
// end of helper functions to generate valid/invalid inputs:
template <std::size_t N, std::size_t, class = make_index_sequence<N>>
struct TestFuncImplInnerLoop;
template <std::size_t N, std::size_t J, std::size_t... Is>
struct TestFuncImplInnerLoop<N, J, index_sequence<Is...>> {
template <class Func, class Tup>
int operator()(Func func, const std::string& funcName, Tup &tup) {
std::cout << "Calling " << funcName << " with argument #" << J+1 << " lower than lower bound:" << std::endl;
assert(!(*func)((J == Is)?getInvalidLowerValue(std::get<Is>(tup)):getValidValue(std::get<Is>(tup))...));
std::cout << "Calling " << funcName << " with argument #" << J+1 << " greater than upper bound:" << std::endl;
assert(!(*func)((J == Is)?getInvalidUpperValue(std::get<Is>(tup)):getValidValue(std::get<Is>(tup))...));
return 0;
}
};
template <std::size_t N, class = make_index_sequence<N>>
struct TestFuncImpl;
template <std::size_t N, std::size_t... Is>
struct TestFuncImpl<N, index_sequence<Is...>> {
template<class Func, class Tup>
void operator()(Func func, const std::string& funcName, Tup &tup) {
std::cout << "Calling " << funcName << " with valid arguments:" << std::endl;
assert((*func)(getValidValue(std::get<Is>(tup))...));
int falseAsserts[sizeof...(Is)] = { TestFuncImplInnerLoop<N, Is>{}(func, funcName, tup)... };
(void)falseAsserts;
}
};
template <class... Args>
void testFunc(bool (*func)(Args...), const std::string& funcName, std::pair<Args, Args>&&... args) {
auto argsTup = std::make_tuple(args...);
std::cout << std::endl << "Testing " << funcName << ":" << std::endl;
TestFuncImpl<sizeof...(Args)>{}(func, funcName, argsTup);
}
// wrapper needed because testFunc can't call function taking const ref as arguments, they need to pass parameters by copy
bool func2Wrapper( int b, Object c )
{
return func2( b, c );
}
int main() {
testFunc( &func1, "func1", std::make_pair( minA, maxA ) );
testFunc( &func2Wrapper, "func2", std::make_pair( minB, maxB ), std::make_pair( minC, maxC ) );
}
...